Skip to content

feat: add PASSKEY branch to auth credential create#363

Draft
DhruvPareek wants to merge 1 commit into04-21-feat_add_oauth_branch_to_additional-credential_challenge_flowfrom
04-21-feat_add_passkey_branch_to_auth_credential_create
Draft

feat: add PASSKEY branch to auth credential create#363
DhruvPareek wants to merge 1 commit into04-21-feat_add_oauth_branch_to_additional-credential_challenge_flowfrom
04-21-feat_add_passkey_branch_to_auth_credential_create

Conversation

@DhruvPareek
Copy link
Copy Markdown
Contributor

Adds the PASSKEY branch to AuthCredentialCreateRequestOneOf, letting platforms register a WebAuthn passkey as an authentication credential on an Embedded Wallet internal account.

Request shape

  • POST /auth/credentials body: { type: "PASSKEY", accountId, nickname, challenge, attestation } → 201 AuthMethod.

Schemas added

  • PasskeyAttestation{ credentialId, clientDataJson, attestationObject, transports }, all base64url-encoded fields plus a W3C-enum-validated transports array (values: usb | nfc | ble | internal | hybrid | smart-card).
  • PasskeyCredentialCreateRequestFields{ type: "PASSKEY", nickname, challenge, attestation } (variant single-value enum on type).
  • PasskeyCredentialCreateRequestallOf(AuthCredentialCreateRequest, PasskeyCredentialCreateRequestFields); wire body is { type, accountId, nickname, challenge, attestation } (accountId inherited from base).

Wire-up

  • AuthCredentialCreateRequestOneOf.yaml discriminator map extended with PASSKEY → PasskeyCredentialCreateRequest.
  • PASSKEY request example added to POST /auth/credentials.
  • Endpoint description updated to document the PASSKEY path: the platform backend issues the WebAuthn challenge (not Grid), the client completes navigator.credentials.create(), and the resulting attestation is submitted here. Activation still happens via /verify.
  • .stainless/stainless.yml registers the three new schemas under auth.credentials.

Design notes

  • transports values at the Grid API surface are the raw W3C AuthenticatorTransport strings as returned by AuthenticatorAttestationResponse.getTransports(). Clients pass them through verbatim; provider-specific translation is handled server-side. This keeps the API surface decoupled from the downstream passkey provider.
  • nickname is user-chosen at registration (unlike EMAIL_OTP where it's derived from the email address) and appears on AuthMethod responses for credential listings.
  • Multiple passkey credentials per internal account are allowed (no PASSKEY_CREDENTIAL_ALREADY_EXISTS); follows the OAUTH precedent.

Notes

  • This PR only wires the create flow; POST /auth/credentials/{id}/verify gets its own PASSKEY branch in the next PR in the stack.
  • Bundled openapi.yaml and mintlify/openapi.yaml regenerated via make build.

Adds the PASSKEY branch to `AuthCredentialCreateRequestOneOf`, letting platforms register a WebAuthn passkey as an authentication credential on an Embedded Wallet internal account.

**Request shape**
- `POST /auth/credentials` body: `{ type: "PASSKEY", accountId, nickname, challenge, attestation }` → 201 `AuthMethod`.

**Schemas added**
- `PasskeyAttestation` — `{ credentialId, clientDataJson, attestationObject, transports }`, all base64url-encoded fields plus a W3C-enum-validated `transports` array (values: `usb | nfc | ble | internal | hybrid | smart-card`).
- `PasskeyCredentialCreateRequestFields` — `{ type: "PASSKEY", nickname, challenge, attestation }` (variant single-value enum on `type`).
- `PasskeyCredentialCreateRequest` — `allOf(AuthCredentialCreateRequest, PasskeyCredentialCreateRequestFields)`; wire body is `{ type, accountId, nickname, challenge, attestation }` (accountId inherited from base).

**Wire-up**
- `AuthCredentialCreateRequestOneOf.yaml` discriminator map extended with `PASSKEY → PasskeyCredentialCreateRequest`.
- PASSKEY request example added to `POST /auth/credentials`.
- Endpoint description updated to document the PASSKEY path: the platform backend issues the WebAuthn challenge (not Grid), the client completes `navigator.credentials.create()`, and the resulting `attestation` is submitted here. Activation still happens via `/verify`.
- `.stainless/stainless.yml` registers the three new schemas under `auth.credentials`.

**Design notes**
- `transports` values at the Grid API surface are the raw W3C `AuthenticatorTransport` strings as returned by `AuthenticatorAttestationResponse.getTransports()`. Clients pass them through verbatim; provider-specific translation is handled server-side. This keeps the API surface decoupled from the downstream passkey provider.
- `nickname` is user-chosen at registration (unlike EMAIL_OTP where it's derived from the email address) and appears on `AuthMethod` responses for credential listings.
- Multiple passkey credentials per internal account are allowed (no `PASSKEY_CREDENTIAL_ALREADY_EXISTS`); follows the OAUTH precedent.

**Notes**
- This PR only wires the create flow; `POST /auth/credentials/{id}/verify` gets its own PASSKEY branch in the next PR in the stack.
- Bundled `openapi.yaml` and `mintlify/openapi.yaml` regenerated via `make build`.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment Apr 22, 2026 4:43am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

✱ Stainless preview builds

This PR will update the grid SDKs with the following commit messages.

kotlin

feat(api): add passkey credential support to credentials

openapi

feat(api): add passkey credential support to auth

python

feat(api): add passkey support to auth.credentials.create method

typescript

feat(api): add passkey credential type with attestation to auth credentials create

Edit this comment to update them. They will appear in their respective SDK's changelogs.

grid-openapi studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅

grid-typescript studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/grid-typescript/42d20a115a778bccc26c81f7df1a40b47e3708b4/dist.tar.gz
grid-python studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅

pip install https://pkg.stainless.com/s/grid-python/6736186a720825f417f7978b728dede6cf1ea7a2/grid-0.0.1-py3-none-any.whl
grid-kotlin studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-04-22 04:48:40 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant