Skip to content

Add passkey credentialId to auth credential list#448

Merged
DhruvPareek merged 2 commits into
mainfrom
auth-passkey-list-credential-id-openapi
May 11, 2026
Merged

Add passkey credentialId to auth credential list#448
DhruvPareek merged 2 commits into
mainfrom
auth-passkey-list-credential-id-openapi

Conversation

@DhruvPareek
Copy link
Copy Markdown
Contributor

@DhruvPareek DhruvPareek commented May 7, 2026

Summary:

  • Add a passkey-specific auth method response schema with WebAuthn credentialId.
  • Switch GET /auth/credentials list items to a discriminated union so credentialId is required only for PASSKEY rows.
  • Update the list response example to show EMAIL_OTP, OAUTH, and PASSKEY credentials.

Screenshot 2026-05-07 at 4.37.20 PM.png

https://docs.google.com/document/d/18f3pLcXbLein9McsXxiPzVJMmXhBFGWQ-6Gys5WILLk/edit?tab=t.zg1lhkeq1hek

Test:

  • npm run lint:openapi

@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 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 May 11, 2026 8:53pm

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

✱ Stainless preview builds

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

kotlin

feat(api): add PasskeyAuthMethod variant with credentialId to auth credentials response

openapi

feat(api): add credentialId field to passkey auth credentials

python

feat(api): add passkey auth method to auth credential list response

typescript

feat(api): add credentialId field to passkey response in auth.credentials.list

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

grid-python studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/daef6e8831fcb703b3fed9d5bf35347034e95b0d/grid-0.0.1-py3-none-any.whl
New diagnostics (6 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/ObjectHasNoProperties: Type information is missing for schema
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
grid-kotlin studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

New diagnostics (16 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/ObjectHasNoProperties: Type information is missing for schema
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.
⚠️ grid-typescript studio · code · diff

Your SDK build had a failure in the build CI job, which is a regression from the base state.
generate ✅build ❗ (prev: build ✅) → lint ❗test ❗ (prev: test ✅)

New diagnostics (6 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/ObjectHasNoProperties: Type information is missing for schema
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
grid-openapi studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅

New diagnostics (8 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/ObjectHasNoProperties: Type information is missing for schema
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/RequiredPropertyNotDefined: This schema marks `type` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.

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-05-07 23:48:01 UTC

@DhruvPareek DhruvPareek marked this pull request as ready for review May 7, 2026 23:12
@DhruvPareek DhruvPareek requested a review from pengying May 7, 2026 23:12
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 7, 2026

Greptile Summary

This PR extends the GET /auth/credentials list response to expose the WebAuthn credentialId for passkey credentials, enabling clients to target a specific registered passkey in navigator.credentials.get(). It introduces PasskeyAuthMethod (a new schema extending AuthMethod with required credentialId) and AuthCredentialListItem (a discriminated oneOf routing EMAIL_OTP/OAUTH to the existing AuthMethodResponse and PASSKEY to the new schema).

  • New schemas: PasskeyAuthMethod.yaml adds credentialId as a required field on top of AuthMethod; AuthCredentialListItem.yaml wires the three credential types through a discriminator keyed on type.
  • Discriminator correctness: AuthMethodResponse's unevaluatedProperties: false prevents a PASSKEY object (with the extra credentialId field) from inadvertently matching the EMAIL_OTP/OAUTH branch, and PasskeyAuthMethod's required: credentialId prevents EMAIL_OTP/OAUTH objects from matching the PASSKEY branch — so the oneOf is unambiguous.
  • Scope: credentialId is intentionally scoped to the list endpoint only; the POST /auth/credentials create response continues to use AuthMethodResponse without credentialId, consistent with the PR description.

Confidence Score: 5/5

Safe to merge — the changes are additive and well-scoped to the GET /auth/credentials list response without touching any other endpoint schemas.

The discriminated union is correctly constructed: unevaluatedProperties: false on AuthMethodResponse prevents PASSKEY objects from matching that branch, and the required credentialId on PasskeyAuthMethod prevents EMAIL_OTP/OAUTH objects from matching the PASSKEY branch. The bundled files are in sync with the source. No existing endpoint contracts are broken.

No files require special attention.

Important Files Changed

Filename Overview
openapi/components/schemas/auth/AuthCredentialListItem.yaml New discriminated union routing EMAIL_OTP/OAUTH to AuthMethodResponse and PASSKEY to PasskeyAuthMethod; discriminator mapping is complete and correct
openapi/components/schemas/auth/PasskeyAuthMethod.yaml New schema extending AuthMethod with required credentialId; correctly uses allOf and restricts type to PASSKEY for discriminator routing
openapi/components/schemas/auth/AuthCredentialListResponse.yaml Single-line change swapping the list item ref from AuthMethod to AuthCredentialListItem, correctly delegating to the new discriminated union
openapi/paths/auth/auth_credentials.yaml GET /auth/credentials example updated to show all three credential types (EMAIL_OTP, OAUTH, PASSKEY) with credentialId present only on the PASSKEY entry
openapi.yaml Bundled file regenerated consistently with source changes; AuthMethodResponse relocated earlier, PasskeyAuthMethod and AuthCredentialListItem added in correct position
mintlify/openapi.yaml Mintlify bundled file mirrors openapi.yaml changes; doc-site schema and example are updated in sync

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as Grid API

    Client->>API: POST /auth/credentials (type: PASSKEY, attestation)
    API-->>Client: 201 AuthMethodResponse (id, type, nickname — no credentialId)

    Client->>API: "GET /auth/credentials?accountId=..."
    API-->>Client: 200 AuthCredentialListResponse
    note over Client,API: data[] = AuthCredentialListItem (oneOf)
    note over Client,API: EMAIL_OTP/OAUTH → AuthMethodResponse
    note over Client,API: PASSKEY → PasskeyAuthMethod (+ credentialId)

    Client->>Client: "navigator.credentials.get({allowCredentials: [{id: credentialId}]})"
Loading

Reviews (2): Last reviewed commit: "Add passkey credentialId to auth credent..." | Re-trigger Greptile

@DhruvPareek DhruvPareek changed the base branch from main to graphite-base/448 May 7, 2026 23:19
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from 9190274 to 04167e9 Compare May 7, 2026 23:19
@DhruvPareek DhruvPareek changed the base branch from graphite-base/448 to auth-v2-session-request-id-contract May 7, 2026 23:19
@DhruvPareek DhruvPareek marked this pull request as draft May 7, 2026 23:20
@DhruvPareek DhruvPareek force-pushed the auth-v2-session-request-id-contract branch from 014a693 to a60c666 Compare May 7, 2026 23:26
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from 04167e9 to 01c31c0 Compare May 7, 2026 23:26
@DhruvPareek DhruvPareek marked this pull request as ready for review May 7, 2026 23:29
@DhruvPareek DhruvPareek force-pushed the auth-v2-session-request-id-contract branch from a60c666 to f25ca4f Compare May 7, 2026 23:44
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from 01c31c0 to 7833483 Compare May 7, 2026 23:44
@DhruvPareek DhruvPareek force-pushed the auth-v2-session-request-id-contract branch 2 times, most recently from 651a738 to 74ce1d0 Compare May 8, 2026 20:52
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from 7833483 to b45b4dd Compare May 8, 2026 20:52
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 8, 2026

✱ Stainless preview builds for grid

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

kotlin

feat(api): add PasskeyAuthMethod variant with credentialId to auth credentials response

openapi

feat(api): add credentialId field to passkey auth credentials

python

feat(api): add passkey auth method to auth credential list response

typescript

feat(api): add credentialId field to passkey response in auth.credentials.list
⚠️ grid-python studio · code

Your SDK build had at least one warning diagnostic.
generate ✅build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/5ed6e73d92562d838d61ad83d5fd3a097f36a7e5/grid-0.0.1-py3-none-any.whl
⚠️ grid-kotlin studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ✅build ✅lint ✅test ❗

⚠️ grid-openapi studio · code

Your SDK build had at least one warning diagnostic.
generate ✅

⚠️ grid-typescript studio · code

Your SDK build had a failure in the build CI job, which is a regression from the base state.
generate ✅build ❗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-05-11 21:26:29 UTC

@DhruvPareek DhruvPareek changed the base branch from auth-v2-session-request-id-contract to graphite-base/448 May 8, 2026 20:56
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from b45b4dd to f4a5bb1 Compare May 8, 2026 23:05
@DhruvPareek DhruvPareek force-pushed the graphite-base/448 branch from 74ce1d0 to db1473a Compare May 8, 2026 23:05
@graphite-app graphite-app Bot changed the base branch from graphite-base/448 to main May 8, 2026 23:06
@DhruvPareek DhruvPareek force-pushed the auth-passkey-list-credential-id-openapi branch from f4a5bb1 to 853808d Compare May 8, 2026 23:06
credentials include the WebAuthn `credentialId` needed to target a specific
registered passkey; other credential types use the base `AuthMethod` shape.
oneOf:
- $ref: ./AuthMethodResponse.yaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this use authmethodresponse instead of authmethod? I don't quite understand what

unevaluatedProperties: false 

does

Comment thread openapi/components/schemas/auth/PasskeyAuthMethod.yaml Outdated
Comment thread openapi/components/schemas/auth/AuthCredentialListItem.yaml Outdated
Copy link
Copy Markdown
Contributor

@pengying pengying left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some questions

Copy link
Copy Markdown
Contributor Author

okay the sdk was messed up

Copy link
Copy Markdown
Contributor Author

The issue with AuthMethodResponse | PasskeyAuthMethod was that PASSKEY could match both sides.

Copy link
Copy Markdown
Contributor Author

So I split the list response into one schema per discriminator value (EMAIL_OTP, OAUTH, PASSKEY)

Copy link
Copy Markdown
Contributor Author

I also pulled the shared fields into AuthMethodBase so we still reuse the common auth-method shape

Copy link
Copy Markdown
Contributor Author

We couldn't just reuse AuthMethod for the list response because AuthMethod.type can be (EMAIL_OTP | OAUTH | PASSKEY), so if we reuse it inside the list union, the generated SDK can’t reliably know that type === "PASSKEY" means credentialId exists

@DhruvPareek DhruvPareek requested a review from pengying May 11, 2026 20:41
Copy link
Copy Markdown
Contributor Author

Wait actually stainless still doesn't like this way of doing it

format: date-time
description: Last update timestamp.
example: '2026-04-08T15:35:00Z'
title: Auth Method
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there anything that still references authMethod?

Copy link
Copy Markdown
Contributor Author

Okay just going to make credentialId an optional field here

@DhruvPareek DhruvPareek merged commit f6fed80 into main May 11, 2026
7 of 8 checks passed
@DhruvPareek DhruvPareek deleted the auth-passkey-list-credential-id-openapi branch May 11, 2026 21:20
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.

2 participants