04

Bind the Authorization Transaction End to End

Bind browser intent, callback, code exchange, and target resource as one short-lived transaction. • Lab status: conceptual reconstruction. Receipts are expected simulated outputs, not deployed-system measurements.

System map · Day 04

Whole-system design

Five stable layers. Today's work is expanded and linked; the rest stays in context.

Entry and policy

Client entry

Design target · not proved

Chooses the public or confidential client posture and the resource the token must reach.

Browser and callback

Design target · not proved

Binds state, authorization code, and the S256 verifier to one browser transaction.

Onboarding and control

Covered — Connector control plane

Authorization services

Authorization server

Design target · not proved

Issues a code and token only for the registered redirect and requested resource.

Compute and execution

Covered — Connector runtime compute · External resource serverAhead — Refresh coordinator compute

Storage and evidence

Covered — Specification draft store · Connector configuration store · Sanitized discovery cacheAhead — Ordered migration log

Secret and token vault

Design target · not proved

Keeps the verifier and resulting token material outside model and browser-visible state.

Evidence plane

Source-backed today

Records success plus wrong-state, verifier, and resource denials without token bytes.

Traversed today

authorize · Browser and callbackAuthorization servertoken · Authorization serverSecret and token vaultobserve · Connector runtime computeEvidence plane

Overview

Why a redirect is not yet an authorization result

Day 03 established sanitized authorization and token endpoints. The remaining risk is transaction substitution: a callback can carry the wrong state, a stolen authorization code can be redeemed with the wrong client, or a token can target a different resource. Today you will apply an OAuth 2.1 security posture using authorization code, S256 Proof Key for Code Exchange (PKCE), state, exact redirect URI, and a resource indicator.

OAuth 2.1 is still an Internet-Draft, currently draft-15, not a finalized RFC and not a blanket compliance label. PKCE is defined by RFC 7636, resource indicators by RFC 8707, and current security guidance by RFC 9700.

Create one short-lived authorization transaction

The client entry creates a random state and PKCE verifier. Only the S256 challenge leaves the client-side secure transaction context. The authorization coordinator stores a hash-bound transaction with issuer, client, redirect URI, resource, expiry, and unused status.

GET /authorize?response_type=code&client_id=calendar-cli&redirect_uri=http%3A%2F%2F127.0.0.1%3A43121%2Fcallback&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&state=s-example&resource=https%3A%2F%2Fcalendar.example%2Fmcp HTTP/1.1
Host: auth.example

{
  "transactionId": "tx-d04",
  "issuer": "https://auth.example",
  "clientId": "calendar-cli",
  "redirectUri": "http://127.0.0.1:43121/callback",
  "resource": "https://calendar.example/mcp",
  "stateHash": "example-state-hash",
  "status": "unused",
  "expiresInSeconds": 300
}

Redeem once and store only a credential reference

The callback first compares state in constant time, checks expiry and unused status, then redeems the code with the exact verifier, redirect URI, client ID, and resource. Successful redemption marks the transaction used before the gateway exposes success. The vault owns token material; the evidence plane receives only a credential reference and safe metadata.

{
  "credentialRef": "vault://calendar-lab/grants/grant-d04",
  "tokenType": "Bearer",
  "resource": "https://calendar.example/mcp",
  "scopes": ["calendar.read"],
  "accessToken": "not-recorded-here"
}

{
  "receipt": "SCG-R04",
  "normal": "code_redeemed_once",
  "denials": ["state_mismatch", "pkce_mismatch", "resource_mismatch"],
  "unaffectedControl": "public-status:200"
}

Run three bounded denials by changing exactly one fact: state, verifier, or resource. Recovery abandons the failed transaction and creates a new one; it never reuses a code or verifier. Cleanup revokes the disposable grant where supported, deletes the vault record, expires the callback listener, and preserves only the redacted receipt.

Score one grant decision

Given the client deployment, selected grant, supplied transaction facts, and one candidate verifier result, decide only redeem or deny, with one reason. The scored unknown is the verifier decision; all other facts are supplied. Matching state, unexpired unused transaction, exact redirect, exact resource, and valid S256 proof permits redemption.

The misconception is “the authorization code is the authorization.” Replay the wrong-resource case: the code can be genuine and still be unusable for this protected resource. Decline cryptography implementation, identity inference, or broad scope design because they introduce unsafe or multiple unknowns.

Carry the grant contract forward

SCG-R04 contains the selected security posture, transaction fields, credential reference, single-use proof, three one-variable denials, positive control, and cleanup. Day 05 uses the same discovered registration endpoint and client posture to register without weakening confidentiality.