docs: explain realistic OIDC sandbox tokens#487
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✱ Stainless preview builds for gridThis PR will update the cli csharp go kotlin openapi php python ruby typescript Edit this comment to update them. They will appear in their respective SDK's changelogs. ✅ grid-openapi studio · code · diff
✅ grid-ruby studio · code · diff
✅ grid-python studio · code · diff
✅ grid-go studio · code · diff
|
2c94a1c to
907c2cd
Compare
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Greptile SummaryThis PR updates the Global Accounts sandbox and OpenAPI docs to replace the old fixed
Confidence Score: 3/5Docs-only change; no application logic is touched. The main risk is integrators picking up the wrong example shape from the spec. The OpenAPI example JWT for OauthCredentialVerifyRequestFields has no nonce field, directly contradicting the description text that sandbox requires one. An integrator who uses this schema example as a starting point in sandbox will receive a 401 nonce failure with no clear pointer to the cause. The nonce hash encoding (hex vs. base64) is also undocumented in prose — only visible in the Node.js code block — which could trip up developers writing equivalent code in other languages. Everything else in the PR is accurate and internally consistent. openapi/components/schemas/auth/OauthCredentialVerifyRequestFields.yaml — the verify example JWT needs a nonce claim to match the documented sandbox requirement
|
| Filename | Overview |
|---|---|
| mintlify/snippets/sandbox-global-account-magic.mdx | Core sandbox docs rewrite — replaces fixed magic token with JWT-shaped OIDC requirements and adds a Node.js code example; nonce hash encoding is unspecified in prose |
| openapi/components/schemas/auth/OauthCredentialVerifyRequestFields.yaml | Updated oidcToken description adds sandbox nonce requirement; the static example JWT has no nonce claim, which contradicts the sandbox requirement for verify |
| openapi/components/schemas/auth/OauthCredentialCreateRequestFields.yaml | Updated oidcToken description to document production vs sandbox validation rules; changes are accurate and no nonce is required here |
| openapi/paths/auth/auth_credentials_{id}_verify.yaml | Operation description and 401 response updated to reflect identity/nonce checks; the OAuth verify example request still uses the non-nonce JWT example value |
| openapi/paths/auth/auth_credentials.yaml | 400 and 401 response descriptions refined to clarify OAUTH-specific error cases; changes are accurate |
| mintlify/snippets/global-accounts/authentication.mdx | Added identity-matching prose and a sandbox Note callout with a link to the sandbox testing page; clear and accurate |
| mintlify/global-accounts/platform-tools/sandbox-testing.mdx | Minor description updates to reflect OIDC flow change; accurate |
| mintlify/global-accounts/index.mdx | One-line card description update to reflect new OIDC sandbox behavior; accurate |
Sequence Diagram
sequenceDiagram
participant Dev as Integrator
participant SB as Grid Sandbox
Note over Dev,SB: OAuth Credential Registration (POST /auth/credentials)
Dev->>Dev: "Generate JWT with iss, aud, sub, iat, exp (signature = dummy value)"
Dev->>SB: "POST /auth/credentials { type: OAUTH, oidcToken }"
SB->>SB: Validate JWT structure and iss support
SB->>SB: Verify iat freshness (60s window)
SB->>SB: Store iss + aud + sub as credential identity
SB-->>Dev: "200 { id: AuthMethod:... }"
Note over Dev,SB: OAuth Credential Verification (POST /auth/credentials/{id}/verify)
Dev->>Dev: Generate ephemeral P-256 key pair
Dev->>Dev: "Compute nonce = sha256(clientPublicKey) hex-encoded"
Dev->>Dev: Generate fresh JWT with iss, aud, sub, iat, exp, nonce
Dev->>SB: "POST /auth/credentials/{id}/verify { type: OAUTH, oidcToken, clientPublicKey }"
SB->>SB: Validate JWT structure and iss support
SB->>SB: Verify iat freshness (60s window)
SB->>SB: Match iss + aud + sub against stored credential identity
SB->>SB: "Verify nonce == sha256(clientPublicKey)"
SB->>SB: Encrypt session signing key to clientPublicKey (HPKE)
SB-->>Dev: "200 { encryptedSessionSigningKey, expiresAt }"
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/sandbox-global-account-magic.mdx:68
**`nonce` hash encoding not specified — developers not using the Node.js example may compute it incorrectly**
The prose says `nonce` must equal `sha256(clientPublicKey)` but doesn't say the output is hex-encoded. The code example uses `.digest("hex")`, producing a lowercase hex string. A developer writing a Python or Go integration might reach for base64 or raw bytes instead, producing a nonce the backend won't match, and getting a 401 with no obvious pointer to the encoding mismatch. Specifying "(hex-encoded)" inline removes the ambiguity.
```suggestion
Grid stores the OAuth credential's registered identity from `iss`, `aud`, and `sub`. On `POST /auth/credentials/{id}/verify`, the fresh `oidcToken` must carry the same `iss`, `aud`, and `sub` as the credential being verified. It must also include `nonce` equal to `sha256(clientPublicKey)` (hex-encoded lowercase), where `clientPublicKey` is the exact hex public key sent in the verify request.
```
### Issue 2 of 2
openapi/components/schemas/auth/OauthCredentialVerifyRequestFields.yaml:24
**Verify example JWT is missing the `nonce` claim now required in sandbox**
The static `example` value shared between create and verify schemas has no `nonce` field in its payload. The description directly above it states that sandbox requires `nonce = sha256(clientPublicKey)` for verify. An integrator who models their token on this example and tests in sandbox will immediately get a 401 nonce-mismatch error with no obvious clue why, since the example shape itself passes no nonce. The same example is intentionally correct for the create operation (where nonce is not required), but a verify-specific example — or a note on the example — is needed to avoid this mismatch.
Reviews (1): Last reviewed commit: "docs: explain realistic OIDC sandbox tok..." | Re-trigger Greptile
| - `iat`: a numeric issued-at timestamp no more than 60 seconds before the request, with 5 seconds of clock skew allowed | ||
| - `exp`: a numeric expiration timestamp later than the request time | ||
|
|
||
| Grid stores the OAuth credential's registered identity from `iss`, `aud`, and `sub`. On `POST /auth/credentials/{id}/verify`, the fresh `oidcToken` must carry the same `iss`, `aud`, and `sub` as the credential being verified. It must also include `nonce` equal to `sha256(clientPublicKey)`, where `clientPublicKey` is the exact hex public key sent in the verify request. |
There was a problem hiding this comment.
nonce hash encoding not specified — developers not using the Node.js example may compute it incorrectly
The prose says nonce must equal sha256(clientPublicKey) but doesn't say the output is hex-encoded. The code example uses .digest("hex"), producing a lowercase hex string. A developer writing a Python or Go integration might reach for base64 or raw bytes instead, producing a nonce the backend won't match, and getting a 401 with no obvious pointer to the encoding mismatch. Specifying "(hex-encoded)" inline removes the ambiguity.
| Grid stores the OAuth credential's registered identity from `iss`, `aud`, and `sub`. On `POST /auth/credentials/{id}/verify`, the fresh `oidcToken` must carry the same `iss`, `aud`, and `sub` as the credential being verified. It must also include `nonce` equal to `sha256(clientPublicKey)`, where `clientPublicKey` is the exact hex public key sent in the verify request. | |
| Grid stores the OAuth credential's registered identity from `iss`, `aud`, and `sub`. On `POST /auth/credentials/{id}/verify`, the fresh `oidcToken` must carry the same `iss`, `aud`, and `sub` as the credential being verified. It must also include `nonce` equal to `sha256(clientPublicKey)` (hex-encoded lowercase), where `clientPublicKey` is the exact hex public key sent in the verify request. |
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/snippets/sandbox-global-account-magic.mdx
Line: 68
Comment:
**`nonce` hash encoding not specified — developers not using the Node.js example may compute it incorrectly**
The prose says `nonce` must equal `sha256(clientPublicKey)` but doesn't say the output is hex-encoded. The code example uses `.digest("hex")`, producing a lowercase hex string. A developer writing a Python or Go integration might reach for base64 or raw bytes instead, producing a nonce the backend won't match, and getting a 401 with no obvious pointer to the encoding mismatch. Specifying "(hex-encoded)" inline removes the ambiguity.
```suggestion
Grid stores the OAuth credential's registered identity from `iss`, `aud`, and `sub`. On `POST /auth/credentials/{id}/verify`, the fresh `oidcToken` must carry the same `iss`, `aud`, and `sub` as the credential being verified. It must also include `nonce` equal to `sha256(clientPublicKey)` (hex-encoded lowercase), where `clientPublicKey` is the exact hex public key sent in the verify request.
```
How can I resolve this? If you propose a fix, please make it concise.| be JWT-shaped with supported `iss`, non-empty `aud` and `sub`, numeric | ||
| `iat` and `exp`, and a `nonce` equal to `sha256(clientPublicKey)`, but | ||
| the signature segment may be a dummy value. | ||
| example: eyJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJzdWIiOiIxMTIyMzM0NDU1IiwiYXVkIjoiMTIzNDU2Ny5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSIsImlhdCI6MTc0NjczNjUwOSwiZXhwIjoxNzQ2NzQwMTA5fQ.signature |
There was a problem hiding this comment.
Verify example JWT is missing the
nonce claim now required in sandbox
The static example value shared between create and verify schemas has no nonce field in its payload. The description directly above it states that sandbox requires nonce = sha256(clientPublicKey) for verify. An integrator who models their token on this example and tests in sandbox will immediately get a 401 nonce-mismatch error with no obvious clue why, since the example shape itself passes no nonce. The same example is intentionally correct for the create operation (where nonce is not required), but a verify-specific example — or a note on the example — is needed to avoid this mismatch.
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/auth/OauthCredentialVerifyRequestFields.yaml
Line: 24
Comment:
**Verify example JWT is missing the `nonce` claim now required in sandbox**
The static `example` value shared between create and verify schemas has no `nonce` field in its payload. The description directly above it states that sandbox requires `nonce = sha256(clientPublicKey)` for verify. An integrator who models their token on this example and tests in sandbox will immediately get a 401 nonce-mismatch error with no obvious clue why, since the example shape itself passes no nonce. The same example is intentionally correct for the create operation (where nonce is not required), but a verify-specific example — or a note on the example — is needed to avoid this mismatch.
How can I resolve this? If you propose a fix, please make it concise.
Summary
sandbox-valid-oidc-tokenvalue.aud/sub, freshiat/exp, storediss/aud/subidentity matching, andnonce = sha256(clientPublicKey)on verify.openapi.yamlandmintlify/openapi.yaml.Stack
main.POST /sandbox/oidc/tokenhelper endpoint docs on top of this behavior documentation.Context
This matches the Grid behavior from the OIDC auth-method identity stack:
dp/grid-oidc-auth-method-identitydp/grid-realistic-oidc-sandboxdp/grid-verify-oauth-oidc-identityThe important customer-facing change is that sandbox skips real IdP signature verification, but it now validates the same identity/freshness shape integrators need in production.
Test Plan
make lintgit diff --check