Skip to content

docs(cards): PATCH /cards/{id} is platform-authenticated, not SCA-railed - #799

Draft
kphurley7 wants to merge 1 commit into
mainfrom
kph/cards-patch-no-sca
Draft

docs(cards): PATCH /cards/{id} is platform-authenticated, not SCA-railed#799
kphurley7 wants to merge 1 commit into
mainfrom
kph/cards-patch-no-sca

Conversation

@kphurley7

Copy link
Copy Markdown
Contributor

Reason

PATCH /cards/{id} documented a 202 -> signed-retry flow that the implementation never had: it returns 200 directly, authenticated by the platform credential. One of the two has to give.

The spec should give, because the documented flow is wrong for this verb. The 202 pattern signs the challenge with the session private key of a verified authentication credential on the card's owning internal account - the end user's key. That models actions taken by a user on their own credentials or funds, which is why DELETE /auth/credentials/{id} and POST /internal-accounts/{id}/export use it.

Freezing or closing a card is routinely an action taken about a user and without them present: fraud response, offboarding, an ops-driven freeze. Under the documented flow none of those are possible through the public API, and the cardholder may be the adversary. We would have had to add a platform-authenticated bypass almost immediately, and that bypass would have become the path everyone actually used.

Overview

  • Drops the 202 -> signed-retry prose and replaces it with why this endpoint is platform-authenticated.
  • Drops the Grid-Wallet-Signature and Request-Id header parameters.
  • Drops the 202 response.
  • 200 is no longer described as "signed retry accepted".
  • Rewrites the 401 description, which described signature and challenge failures.

Sensitive-data operations stay SCA-railed: POST /cards/{id}/reveal and 3DS password retrieval are unchanged, because there the cardholder is the party being served and user-present signing is the right model.

Notes

No implementation change accompanies this - sparkcore already behaves this way, so this closes the divergence rather than opening one. Nothing is affected downstream: the card program is gated behind GRID_CARD_PROGRAM_ENABLED and is not public.

Redocly validates clean; warning count unchanged at 50, none in this file. Spectral does not run locally (see #795).

The spec described a 202 -> signed-retry flow that the implementation never
had. Rather than build it, drop it: the pattern signs with the session key of
a credential on the owning internal account, so requiring it would make a
platform unable to freeze or close a card without the cardholder present -
which is exactly the fraud-response and offboarding case the verb exists for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsJUrc9YRcfxEFqgXQEYvD
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

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

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Aug 5, 2026 1:45am
grid-wallet-demo Ignored Ignored Aug 5, 2026 1:45am

Request Review

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