Skip to content

add DELETE /auth/credentials/{id} to revoke authentication credentials#369

Open
DhruvPareek wants to merge 1 commit into04-22-feat_add_get__auth_credentials_to_list_authentication_credentialsfrom
04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials
Open

add DELETE /auth/credentials/{id} to revoke authentication credentials#369
DhruvPareek wants to merge 1 commit into04-22-feat_add_get__auth_credentials_to_list_authentication_credentialsfrom
04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials

Conversation

@DhruvPareek
Copy link
Copy Markdown
Contributor

@DhruvPareek DhruvPareek commented Apr 22, 2026

New revocation endpoint for the Embedded Wallet Auth surface. Revocation is a two-step signed-retry flow (same pattern as the add-additional-credential flow on POST /auth/credentials), because it must be authorized by a session on a different credential on the same internal account.

Flow

  1. DELETE /auth/credentials/{id} with no headers → 202 AuthCredentialDeleteChallenge (id, type, payloadToSign, requestId, expiresAt).
  2. Client signs payloadToSign with the session private key of another verified credential on the same internal account and retries the request with Grid-Wallet-Signature + Request-Id headers → 204.

Schemas added

  • SignedRequestChallenge (common) — shared base for two-step signed-retry challenge responses. Holds the three fields every challenge variant carries: payloadToSign, requestId, expiresAt. Each variant composes this base via allOf and adds its own resource id (and type, when applicable) with variant-specific description and example.
  • AuthCredentialDeleteChallengeallOf(SignedRequestChallenge, { id, type: AuthMethodType }). id points at the credential being revoked.

Wire-up

  • New path file openapi/paths/auth/auth_credentials_{id}.yaml with the delete operation plus shared Grid-Wallet-Signature and Request-Id headers, modelled on POST /auth/credentials.

Design notes

Notes

  • The account must retain at least one credential after revocation; revoking the last remaining credential is rejected with 400.

@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 23, 2026 2:39am

Request Review

Copy link
Copy Markdown
Contributor Author

DhruvPareek commented Apr 22, 2026

@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 list and revoke methods to credentials

openapi

feat(api): add revoke method to auth credentials

python

feat(api): add list and revoke methods to auth credentials

typescript

feat(api): add list and revoke methods to auth credentials

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 "error" diagnostic, but this did not represent a regression.
generate ❗build ✅lint ✅test ✅

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

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

npm install https://pkg.stainless.com/s/grid-typescript/37dd1e49ffd74de0d9d6a90027e24add77a873fd/dist.tar.gz
grid-openapi studio · code · diff

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

grid-kotlin studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
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-04-23 02:45:30 UTC

@DhruvPareek DhruvPareek changed the title feat: add DELETE /auth/credentials/{id} to revoke authentication credentials add DELETE /auth/credentials/{id} to revoke authentication credentials Apr 22, 2026
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from 79a749a to d0f0803 Compare April 22, 2026 20:02
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from 108f6cf to fec18b2 Compare April 22, 2026 20:02
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from d0f0803 to 4517a0d Compare April 22, 2026 20:07
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from fec18b2 to 088d2dc Compare April 22, 2026 20:07
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from 4517a0d to b280a16 Compare April 22, 2026 20:18
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from 088d2dc to 9f6c7a1 Compare April 22, 2026 20:18
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from 9f6c7a1 to 52fcd4f Compare April 22, 2026 20:23
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from b280a16 to 2da0bb2 Compare April 22, 2026 20:23
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from 52fcd4f to 9198355 Compare April 22, 2026 20:49
@DhruvPareek DhruvPareek marked this pull request as ready for review April 22, 2026 21:00
@DhruvPareek DhruvPareek requested a review from pengying April 22, 2026 21:01
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 22, 2026

Greptile Summary

This PR adds DELETE /auth/credentials/{id} to revoke Embedded Wallet authentication credentials via a two-step signed-retry flow, modelled closely on the existing POST /auth/credentials additional-credential pattern. It introduces a reusable SignedRequestChallenge base schema and the AuthCredentialDeleteChallenge response schema, wires everything into Stainless config, and ships the regenerated bundles.

Confidence Score: 5/5

Safe to merge; only P2 style findings remain.

All findings are P2: a stale example timestamp in SignedRequestChallenge and a missing base64 == padding on payloadToSign. Neither affects runtime behavior or API correctness. The endpoint design, schema composition, Stainless wiring, and generated bundles all look correct and consistent with existing patterns.

openapi/components/schemas/common/SignedRequestChallenge.yaml — minor example inconsistencies noted above.

Important Files Changed

Filename Overview
openapi/paths/auth/auth_credentials_{id}.yaml New DELETE operation implementing the two-step signed-retry revocation flow; mirrors the POST /auth/credentials pattern correctly, with well-documented parameters and all expected response codes.
openapi/components/schemas/common/SignedRequestChallenge.yaml New reusable base schema for signed-retry challenges; minor issues: payloadToSign example is missing base64 == padding (inconsistent with existing examples), and expiresAt example date is already in the past.
openapi/components/schemas/auth/AuthCredentialDeleteChallenge.yaml Correct allOf composition of SignedRequestChallenge + credential-specific fields (id, type); required fields and $ref to AuthMethodType are properly set.
.stainless/stainless.yml Adds delete method and auth_credential_delete_challenge/signed_request_challenge models to Stainless config; follows existing patterns.
openapi/openapi.yaml Adds the /auth/credentials/{id} path reference in the correct position; no issues.
openapi.yaml Generated bundle updated with the new DELETE endpoint and schemas; expected artifact from running make build.
mintlify/openapi.yaml Generated Mintlify bundle updated with the new DELETE endpoint and schemas; expected artifact from running make build.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as DELETE /auth/credentials/{id}

    Client->>API: DELETE /auth/credentials/{id} (no headers)
    API-->>Client: 202 AuthCredentialDeleteChallenge
    Note right of API: payloadToSign, requestId, expiresAt

    Note over Client: Sign payloadToSign with session
    Note over Client: private key of a *different*
    Note over Client: verified credential

    Client->>API: DELETE /auth/credentials/{id}
    Note right of Client: + Grid-Wallet-Signature header
    Note right of Client: + Request-Id header

    alt Signature valid & different credential
        API-->>Client: 204 No Content (revoked)
    else Last remaining credential
        API-->>Client: 400 Bad Request
    else Invalid/expired signature
        API-->>Client: 401 Unauthorized
    else Credential not found
        API-->>Client: 404 Not Found
    end
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/SignedRequestChallenge.yaml
Line: 34-36

Comment:
**`expiresAt` example timestamp is already in the past**

The example value `'2026-04-08T15:35:00Z'` predates the current date (2026-04-22), which means docs and SDK tooling will render a stale timestamp that looks incorrect to readers. Consider advancing it to a future date that won't expire immediately on publication.

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

---

This is a comment left during a code review.
Path: openapi/components/schemas/common/SignedRequestChallenge.yaml
Line: 22

Comment:
**`payloadToSign` example missing base64 padding**

The example `Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg` is missing the standard `==` padding. Existing uses of the same logical value in `openapi/paths/auth/auth_credentials.yaml` (lines 140/147) consistently include the trailing `==`. Strict base64 parsers will reject the unpadded form; aligning with the existing examples avoids any confusion.

```suggestion
    example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==
```

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

Reviews (1): Last reviewed commit: "feat: add DELETE /auth/credentials/{id} ..." | Re-trigger Greptile

Comment on lines +34 to +36
Timestamp after which this challenge is no longer valid. The
signed retry must be submitted before this time.
example: '2026-04-08T15:35:00Z'
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 expiresAt example timestamp is already in the past

The example value '2026-04-08T15:35:00Z' predates the current date (2026-04-22), which means docs and SDK tooling will render a stale timestamp that looks incorrect to readers. Consider advancing it to a future date that won't expire immediately on publication.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/SignedRequestChallenge.yaml
Line: 34-36

Comment:
**`expiresAt` example timestamp is already in the past**

The example value `'2026-04-08T15:35:00Z'` predates the current date (2026-04-22), which means docs and SDK tooling will render a stale timestamp that looks incorrect to readers. Consider advancing it to a future date that won't expire immediately on publication.

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

Fix in Claude Code

verified authentication credential. The resulting signature is
passed as the `Grid-Wallet-Signature` header on the retry of the
originating request to complete the operation.
example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg
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 payloadToSign example missing base64 padding

The example Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg is missing the standard == padding. Existing uses of the same logical value in openapi/paths/auth/auth_credentials.yaml (lines 140/147) consistently include the trailing ==. Strict base64 parsers will reject the unpadded form; aligning with the existing examples avoids any confusion.

Suggested change
example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg
example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/SignedRequestChallenge.yaml
Line: 22

Comment:
**`payloadToSign` example missing base64 padding**

The example `Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg` is missing the standard `==` padding. Existing uses of the same logical value in `openapi/paths/auth/auth_credentials.yaml` (lines 140/147) consistently include the trailing `==`. Strict base64 parsers will reject the unpadded form; aligning with the existing examples avoids any confusion.

```suggestion
    example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==
```

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

Fix in Claude Code

@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from 9198355 to b8d867f Compare April 22, 2026 23:36
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from 2da0bb2 to 5d420cd Compare April 22, 2026 23:36
…entials

New revocation endpoint for the Embedded Wallet Auth surface. Revocation is a two-step signed-retry flow (same pattern as the add-additional-credential flow on POST /auth/credentials), because it must be authorized by a session on a *different* credential on the same internal account.

**Flow**
1. `DELETE /auth/credentials/{id}` with no headers → `202` `AuthCredentialDeleteChallenge` (`id`, `type`, `payloadToSign`, `requestId`, `expiresAt`).
2. Client signs `payloadToSign` with the session private key of another verified credential on the same internal account and retries the request with `Grid-Wallet-Signature` + `Request-Id` headers → `204`.

**Schemas added**
- `SignedRequestChallenge` (common) — shared base for two-step signed-retry challenge responses. Holds the three fields every challenge variant carries: `payloadToSign`, `requestId`, `expiresAt`. Each variant composes this base via `allOf` and adds its own resource `id` (and `type`, when applicable) with variant-specific description and example.
- `AuthCredentialDeleteChallenge` — `allOf(SignedRequestChallenge, { id, type: AuthMethodType })`. `id` points at the credential being revoked.

**Wire-up**
- New path file `openapi/paths/auth/auth_credentials_{id}.yaml` with the `delete` operation plus shared `Grid-Wallet-Signature` and `Request-Id` headers, modelled on `POST /auth/credentials`.
- `openapi/openapi.yaml` registers the new path.
- `.stainless/stainless.yml` adds `delete: delete /auth/credentials/{id}` to the `auth.credentials` methods and registers `AuthCredentialDeleteChallenge` + the shared `SignedRequestChallenge` (under `$shared`) as models.
- Bundled `openapi.yaml` + `mintlify/openapi.yaml` regenerated.

**Design notes**
- `id` is kept in the variant (not the base) so each variant owns its resource-specific description and example (`AuthMethod:…`, `Session:…`, `InternalAccount:…`). Avoids relying on `allOf` property overrides, which tooling (Mintlify, Stainless) handles inconsistently.
- `SignedRequestChallenge` is also used by the next two PRs in the stack (`SessionDeleteChallenge`, `InternalAccountExportChallenge`). Refactored up-front rather than deferred so the three sites land on the same base from day one.
- `AuthCredentialAdditionalChallenge` (already in main) has an overlapping shape but a different semantic role (registering vs. revoking). Leaving it alone for now; it can be migrated onto `SignedRequestChallenge` as a follow-up if desired.

**Notes**
- The account must retain at least one credential after revocation; revoking the last remaining credential is rejected with `400`.
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_delete__auth_credentials__id_to_revoke_authentication_credentials branch from b8d867f to 65bd260 Compare April 23, 2026 02:38
@DhruvPareek DhruvPareek force-pushed the 04-22-feat_add_get__auth_credentials_to_list_authentication_credentials branch from 5d420cd to 05ba4d6 Compare April 23, 2026 02:38
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