Skip to content

[grid] fix passkey reauth challenge docs#561

Merged
DhruvPareek merged 1 commit into
mainfrom
dp/fix-passkey-challenge-docs
Jun 9, 2026
Merged

[grid] fix passkey reauth challenge docs#561
DhruvPareek merged 1 commit into
mainfrom
dp/fix-passkey-challenge-docs

Conversation

@DhruvPareek

Copy link
Copy Markdown
Contributor

Updates the Global Accounts docs source to match the backend passkey reauthentication behavior: /auth/credentials/{id}/challenge returns a lowercase hex SHA-256 digest, so clients should UTF-8 encode the challenge string for navigator.credentials.get() instead of base64url-decoding it. Also updates the Mintlify passkey walkthrough snippet.

@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jun 9, 2026 7:07pm

Request Review

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for grid

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

cli

chore(internal): regenerate SDK with no functional changes

csharp

docs(api): clarify passkey challenge field format in auth credentials

go

docs(api): clarify challenge encoding in passkey authentication

kotlin

docs(api): clarify passkey challenge encoding in auth credentials

openapi

docs(api): clarify challenge field format in PasskeyAuthChallenge

php

docs(api): clarify challenge field format in passkey authentication

python

docs(api): clarify passkey challenge format in auth credentials

ruby

docs(api): clarify challenge encoding in passkey auth

typescript

docs(api): clarify passkey challenge encoding in auth credentials
grid-openapi studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅

grid-ruby studio · code

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

⚠️ grid-go studio · code

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

go get github.com/stainless-sdks/grid-go@369a8b10973e3183a2e4e911cd07919dd5efbf1e
grid-kotlin studio · code

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

grid-typescript studio · code

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

npm install https://pkg.stainless.com/s/grid-typescript/fdecfc0e410ec1316281c3092413bd8ea08b83b7/dist.tar.gz
⚠️ grid-python studio · code

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

pip install https://pkg.stainless.com/s/grid-python/6456fdae4bb4c25e07767f8b7a8784e6089e97dd/grid-0.0.1-py3-none-any.whl
⚠️ grid-csharp 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 ❗

grid-php studio · code

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

⚠️ grid-cli 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 ❗


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-06-09 19:31:28 UTC

@mintlify

mintlify Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

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

Project Status Preview Updated (UTC)
Grid 🟢 Ready View Preview Jun 9, 2026, 6:56 PM

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR corrects the passkey reauthentication challenge documentation across OpenAPI specs and the Mintlify walkthrough: the challenge returned by /auth/credentials/{id}/challenge is a lowercase hex-encoded SHA-256 digest, not a base64url string, so clients must UTF-8-encode it rather than base64url-decode it before passing it to navigator.credentials.get().

  • OpenAPI specs (openapi.yaml, mintlify/openapi.yaml, and their source files) — PasskeyAuthChallenge.challenge description and example value updated to reflect the hex SHA-256 format; endpoint description now explicitly shows new TextEncoder().encode(challenge).
  • JS snippet (authentication.mdx) — base64urlToBytes(gridChallenge) replaced with new TextEncoder().encode(gridChallenge) and a clarifying comment added.
  • iOS/Android snippets — not updated: the Swift call still passes the raw string to createCredentialAssertionRequest(challenge:) and the Kotlin helper receives the raw string with no encoding guidance, leaving both mobile paths broken under the new format.

Confidence Score: 4/5

Safe to merge for JS clients; iOS and Android developers following the walkthrough will produce wrong WebAuthn bytes until the Swift and Kotlin snippets are fixed.

The OpenAPI spec changes and the JS snippet update are correct and complete. However, the Swift snippet still passes the raw hex string directly to createCredentialAssertionRequest(challenge:), and the Kotlin snippet passes the raw string to buildWebAuthnGetOptionsJson with no encoding guidance — both will produce incorrect WebAuthn assertions under the new hex challenge format.

mintlify/snippets/global-accounts/authentication.mdx — the iOS (Swift) and Android (Kotlin) code examples need the same UTF-8 encoding fix applied to the JS snippet.

Important Files Changed

Filename Overview
openapi/components/schemas/auth/PasskeyAuthChallenge.yaml Corrects the challenge field description from base64url to lowercase hex SHA-256; updates the example value to a valid 64-char hex digest.
openapi/paths/auth/auth_credentials_{id}_challenge.yaml Updates endpoint description to clarify UTF-8 encoding requirement for the challenge and base64url-decoding for credentialId; updates the example challenge value.
openapi.yaml Mirrors the source YAML changes: challenge description updated to hex SHA-256, example updated, PasskeyAuthChallenge component description corrected.
mintlify/openapi.yaml Identical changes to openapi.yaml; challenge description and example value updated for the Mintlify-hosted spec.
mintlify/snippets/global-accounts/authentication.mdx JS snippet and prose updated correctly, but the Kotlin and Swift code examples still pass the raw challenge string without UTF-8 encoding, which will produce wrong WebAuthn bytes on Android and iOS.

Comments Outside Diff (2)

  1. mintlify/snippets/global-accounts/authentication.mdx, line 305-308 (link)

    P1 iOS challenge encoding not updated

    ASAuthorizationPlatformPublicKeyCredentialProvider.createCredentialAssertionRequest(challenge:) takes a Data parameter. With the challenge now a lowercase hex string, passing challengeResp.challenge directly will either fail to compile (type mismatch) or — if the backend model decodes it as Data via base64 — produce the wrong bytes, silently breaking iOS passkey auth. The fix is challengeResp.challenge.data(using: .utf8)! as the argument, mirroring the JS new TextEncoder().encode(gridChallenge) pattern added in this PR.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: mintlify/snippets/global-accounts/authentication.mdx
    Line: 305-308
    
    Comment:
    **iOS challenge encoding not updated**
    
    `ASAuthorizationPlatformPublicKeyCredentialProvider.createCredentialAssertionRequest(challenge:)` takes a `Data` parameter. With the challenge now a lowercase hex string, passing `challengeResp.challenge` directly will either fail to compile (type mismatch) or — if the backend model decodes it as `Data` via base64 — produce the wrong bytes, silently breaking iOS passkey auth. The fix is `challengeResp.challenge.data(using: .utf8)!` as the argument, mirroring the JS `new TextEncoder().encode(gridChallenge)` pattern added in this PR.
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. mintlify/snippets/global-accounts/authentication.mdx, line 224-229 (link)

    P1 Android challenge encoding not updated

    The Kotlin snippet delegates to buildWebAuthnGetOptionsJson(challenge = challengeResp.challenge, ...) with no comment about the encoding change. Any developer who implements that helper using the old mental model (treating the challenge as a base64url string to decode) will pass the wrong bytes to the WebAuthn assertion, silently breaking passkey auth on Android. At minimum a comment should clarify that challengeResp.challenge is now a lowercase hex string that must be UTF-8-encoded — the same clarification already added in the JS snippet comment (// challenge is a lowercase hex string; UTF-8 encode it exactly as returned).

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: mintlify/snippets/global-accounts/authentication.mdx
    Line: 224-229
    
    Comment:
    **Android challenge encoding not updated**
    
    The Kotlin snippet delegates to `buildWebAuthnGetOptionsJson(challenge = challengeResp.challenge, ...)` with no comment about the encoding change. Any developer who implements that helper using the old mental model (treating the challenge as a base64url string to decode) will pass the wrong bytes to the WebAuthn assertion, silently breaking passkey auth on Android. At minimum a comment should clarify that `challengeResp.challenge` is now a lowercase hex string that must be UTF-8-encoded — the same clarification already added in the JS snippet comment (`// challenge is a lowercase hex string; UTF-8 encode it exactly as returned`).
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
mintlify/snippets/global-accounts/authentication.mdx:305-308
**iOS challenge encoding not updated**

`ASAuthorizationPlatformPublicKeyCredentialProvider.createCredentialAssertionRequest(challenge:)` takes a `Data` parameter. With the challenge now a lowercase hex string, passing `challengeResp.challenge` directly will either fail to compile (type mismatch) or — if the backend model decodes it as `Data` via base64 — produce the wrong bytes, silently breaking iOS passkey auth. The fix is `challengeResp.challenge.data(using: .utf8)!` as the argument, mirroring the JS `new TextEncoder().encode(gridChallenge)` pattern added in this PR.

### Issue 2 of 2
mintlify/snippets/global-accounts/authentication.mdx:224-229
**Android challenge encoding not updated**

The Kotlin snippet delegates to `buildWebAuthnGetOptionsJson(challenge = challengeResp.challenge, ...)` with no comment about the encoding change. Any developer who implements that helper using the old mental model (treating the challenge as a base64url string to decode) will pass the wrong bytes to the WebAuthn assertion, silently breaking passkey auth on Android. At minimum a comment should clarify that `challengeResp.challenge` is now a lowercase hex string that must be UTF-8-encoded — the same clarification already added in the JS snippet comment (`// challenge is a lowercase hex string; UTF-8 encode it exactly as returned`).

Reviews (2): Last reviewed commit: "[grid] fix passkey reauth challenge docs" | Re-trigger Greptile

@DhruvPareek DhruvPareek merged commit 4863409 into main Jun 9, 2026
10 checks passed

Copy link
Copy Markdown
Contributor Author

Merge activity

@DhruvPareek DhruvPareek deleted the dp/fix-passkey-challenge-docs branch June 9, 2026 19:26
pengying pushed a commit that referenced this pull request Jun 18, 2026
## Summary
- Fixed incorrect passkey challenge encoding in `AuthenticateAndSign.tsx`
- The Grid-issued authentication challenge is a lowercase hex string that should be UTF-8 encoded, not base64url decoded
- This aligns the sample code with the schema clarification from #561

## Changes
**Frontend Sample:**
- Changed `base64urlToBytes(challenge.challenge)` to `new TextEncoder().encode(challenge.challenge)` for the WebAuthn assertion
- Updated comment to clarify that the challenge is a hex string requiring UTF-8 encoding

## Context
PR #561 clarified that the passkey `challenge` field from `POST /auth/credentials/{id}/challenge` is:
> "Lowercase hex-encoded SHA-256 digest... Do not base64url-decode this field; pass UTF-8 bytes of the string (for example, `new TextEncoder().encode(challenge)`) as the WebAuthn challenge"

The Mintlify documentation already correctly describes this encoding (showing `new TextEncoder().encode(gridChallenge)`), but the frontend sample was using the wrong encoding method.

## Test plan
- [ ] Verify the frontend sample compiles without errors
- [ ] Test passkey authentication flow in sandbox mode
- [ ] Verify the change matches the documentation in `mintlify/snippets/global-accounts/authentication.mdx`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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