Skip to content

docs: move passkey clientPublicKey from /verify to /challenge#408

Merged
pengying merged 1 commit intomainfrom
04-27-docs_move_passkey_clientpublickey_from__verify_to__challenge
Apr 28, 2026
Merged

docs: move passkey clientPublicKey from /verify to /challenge#408
pengying merged 1 commit intomainfrom
04-27-docs_move_passkey_clientpublickey_from__verify_to__challenge

Conversation

@pengying
Copy link
Copy Markdown
Contributor

Reflects the API change in #407 — for PASSKEY credentials,
clientPublicKey now goes on POST /auth/credentials/{id}/challenge
instead of /verify. Grid bakes the public key into the Turnkey
session-creation payload that the returned challenge is computed
from, so the resulting session signing key is sealed to the device
that requested the challenge.

Knock-on flow change: registration response is now a plain AuthMethod
(no inline PasskeyAuthChallenge). Both first-time activation and
reauthentication for PASSKEY follow the same three-step shape:
register → /challenge (with clientPublicKey) → /verify (with
Request-Id, no clientPublicKey).

EMAIL_OTP and OAUTH are unchanged — clientPublicKey stays on /verify
for those types; /challenge takes an empty body.

Updates:

  • snippets/global-accounts/authentication.mdx — overview, passkey
    registration sequence diagram + TS/Kotlin/Swift code samples,
    parameter map split into challenge + assertion tables, passkey
    reauth diagram, additional-credential activation prose
  • snippets/global-accounts/overview.mdx — Quickstart Step 7 now
    generates the keypair before calling /challenge with
    clientPublicKey, and the /verify body drops it
  • snippets/global-accounts/client-keys.mdx — clarifies which call
    carries clientPublicKey for each credential type
  • snippets/sandbox-global-account-magic.mdx — passkey example now
    shows the /challenge + /verify pair; verify body drops
    clientPublicKey

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Reflects the API change in #407 — for PASSKEY credentials,
clientPublicKey now goes on POST /auth/credentials/{id}/challenge
instead of /verify. Grid bakes the public key into the Turnkey
session-creation payload that the returned challenge is computed
from, so the resulting session signing key is sealed to the device
that requested the challenge.

Knock-on flow change: registration response is now a plain AuthMethod
(no inline PasskeyAuthChallenge). Both first-time activation and
reauthentication for PASSKEY follow the same three-step shape:
register → /challenge (with clientPublicKey) → /verify (with
Request-Id, no clientPublicKey).

EMAIL_OTP and OAUTH are unchanged — clientPublicKey stays on /verify
for those types; /challenge takes an empty body.

Updates:
- snippets/global-accounts/authentication.mdx — overview, passkey
  registration sequence diagram + TS/Kotlin/Swift code samples,
  parameter map split into challenge + assertion tables, passkey
  reauth diagram, additional-credential activation prose
- snippets/global-accounts/overview.mdx — Quickstart Step 7 now
  generates the keypair before calling /challenge with
  clientPublicKey, and the /verify body drops it
- snippets/global-accounts/client-keys.mdx — clarifies which call
  carries clientPublicKey for each credential type
- snippets/sandbox-global-account-magic.mdx — passkey example now
  shows the /challenge + /verify pair; verify body drops
  clientPublicKey

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented Apr 28, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Grid 🟢 Ready View Preview Apr 28, 2026, 5:02 AM

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 28, 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 28, 2026 5:01am

Request Review

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 28, 2026

Greptile Summary

This PR updates four documentation snippets to reflect the API change introduced in #407: for PASSKEY credentials, clientPublicKey now travels on POST /auth/credentials/{id}/challenge instead of /verify. All code samples (TypeScript, Kotlin, Swift), sequence diagrams (registration and reauthentication), parameter tables, and sandbox magic-value instructions are updated consistently with the new three-step flow (register → /challenge with clientPublicKey → /verify with assertion + Request-Id). EMAIL_OTP and OAUTH flows are unchanged.

Confidence Score: 4/5

Safe to merge — one minor wording inaccuracy in the sandbox docs, all core content is consistent and correct.

All four files are internally consistent and correctly reflect the API change. The single finding is a P2 wording issue in sandbox-global-account-magic.mdx where 'reauthentication' is used to describe a flow that applies equally to first-time activation.

mintlify/snippets/sandbox-global-account-magic.mdx — the new prose scopes the /challenge → /verify two-step to 'reauthentication' only, which is inaccurate.

Important Files Changed

Filename Overview
mintlify/snippets/global-accounts/authentication.mdx Accurately moves clientPublicKey from /verify to /challenge for PASSKEY across the overview prose, both sequence diagrams (registration + reauth), all three SDK code samples (TS/Kotlin/Swift), and the parameter tables.
mintlify/snippets/global-accounts/client-keys.mdx Single-paragraph update correctly maps clientPublicKey placement per credential type (PASSKEY → /challenge, EMAIL_OTP/OAUTH → /verify, export → /export).
mintlify/snippets/global-accounts/overview.mdx Quickstart Step 7 correctly reordered: keypair generation and /challenge (with clientPublicKey) now happen before the WebAuthn assertion, and /verify body drops clientPublicKey.
mintlify/snippets/sandbox-global-account-magic.mdx Adds /challenge → /verify example pair for sandbox passkey, but the new prose scopes the two-step flow only to 'reauthentication' when first-time activation follows the same pattern.

Sequence Diagram

sequenceDiagram
    participant C as Client
    participant IB as Integrator Backend
    participant G as Grid
    participant A as Authenticator

    note over C,A: Registration
    C->>A: navigator.credentials.create({ challenge })
    A-->>C: attestation
    C->>IB: POST /my-backend/passkey/register (attestation)
    IB->>G: POST /auth/credentials { type: PASSKEY, … }
    G-->>IB: 201 AuthMethod { id, type, accountId, … }
    IB-->>C: { credentialId }

    note over C,A: First Auth / Reauthentication (same shape)
    C->>C: generateClientKeyPair()
    C->>IB: POST /my-backend/passkey/challenge (credentialId, clientPublicKey)
    IB->>G: POST /auth/credentials/{id}/challenge { clientPublicKey }
    G-->>IB: 200 PasskeyAuthChallenge { challenge, requestId, expiresAt }
    IB-->>C: { challenge, requestId }
    C->>A: navigator.credentials.get({ challenge })
    A-->>C: assertion
    C->>IB: POST /my-backend/passkey/verify (assertion, requestId)
    IB->>G: POST /auth/credentials/{id}/verify Request-Id: requestId { type: PASSKEY, assertion }
    G-->>IB: 200 AuthSession { encryptedSessionSigningKey, expiresAt }
    IB-->>C: { encryptedSessionSigningKey, expiresAt }
    C->>C: decrypt with private key → session signing key
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: mintlify/snippets/sandbox-global-account-magic.mdx
Line: 27

Comment:
**"Reauthentication" scope is too narrow**

The new paragraph says "Passkey reauthentication is a two-step `/challenge``/verify` flow," but per the PR description and the updated `authentication.mdx`, both first-time activation *and* reauthentication now follow this same shape. A developer testing first-time passkey setup in sandbox might read this and not realise they need to call `/challenge` (with `clientPublicKey`) before the magic `/verify` call.

```suggestion
Passkey authentication (both first-time activation and reauthentication) is a two-step `/challenge` → `/verify` flow. The `clientPublicKey` is sent on `/challenge` (so Grid can seal the session signing key to your device) — the magic value bypasses the credential check, not the HPKE plumbing, so the public key is still required.
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "docs: move passkey clientPublicKey from ..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor Author

pengying commented Apr 28, 2026

Merge activity

  • Apr 28, 5:16 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 28, 5:16 AM UTC: @pengying merged this pull request with Graphite.


Pass `sandbox-valid-passkey-signature` as `assertion.signature` on `POST /auth/credentials/{id}/verify` when the credential type is `PASSKEY`. The sandbox accepts the rest of the assertion as-is and skips the WebAuthn signature check.

Passkey reauthentication is a two-step `/challenge` → `/verify` flow. The `clientPublicKey` is sent on `/challenge` (so Grid can seal the session signing key to your device) — the magic value bypasses the credential check, not the HPKE plumbing, so the public key is still required.
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.

P2 "Reauthentication" scope is too narrow

The new paragraph says "Passkey reauthentication is a two-step /challenge/verify flow," but per the PR description and the updated authentication.mdx, both first-time activation and reauthentication now follow this same shape. A developer testing first-time passkey setup in sandbox might read this and not realise they need to call /challenge (with clientPublicKey) before the magic /verify call.

Suggested change
Passkey reauthentication is a two-step `/challenge``/verify` flow. The `clientPublicKey` is sent on `/challenge` (so Grid can seal the session signing key to your device) — the magic value bypasses the credential check, not the HPKE plumbing, so the public key is still required.
Passkey authentication (both first-time activation and reauthentication) is a two-step `/challenge``/verify` flow. The `clientPublicKey` is sent on `/challenge` (so Grid can seal the session signing key to your device) — the magic value bypasses the credential check, not the HPKE plumbing, so the public key is still required.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/snippets/sandbox-global-account-magic.mdx
Line: 27

Comment:
**"Reauthentication" scope is too narrow**

The new paragraph says "Passkey reauthentication is a two-step `/challenge``/verify` flow," but per the PR description and the updated `authentication.mdx`, both first-time activation *and* reauthentication now follow this same shape. A developer testing first-time passkey setup in sandbox might read this and not realise they need to call `/challenge` (with `clientPublicKey`) before the magic `/verify` call.

```suggestion
Passkey authentication (both first-time activation and reauthentication) is a two-step `/challenge` → `/verify` flow. The `clientPublicKey` is sent on `/challenge` (so Grid can seal the session signing key to your device) — the magic value bypasses the credential check, not the HPKE plumbing, so the public key is still required.
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

@pengying pengying merged commit 990eee4 into main Apr 28, 2026
9 checks passed
@pengying pengying deleted the 04-27-docs_move_passkey_clientpublickey_from__verify_to__challenge branch April 28, 2026 05:16
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