Skip to main content
UCPSigned intents
UCP

Signed intents

Let agents prove what they meant to do so high-value commerce actions are traceable.

JWS-signed Request-Signature headers, JWKS-resolved verification, replay protection, identity linking.

UCP requests can be signed. Agents that want non-repudiable transcripts — “this agent created this checkout for this user at this time” — attach a JWS-signed Request-Signature header. The server validates the signature, records the agent identity, and signs its response symmetrically.

Optional, but recommended for production agents
Signature validation is non-blocking by default — calls without a signature still succeed. Operators can require signatures per-store; if your agent will ever transact across multiple UCP servers, signing from day one keeps you compatible.

Algorithm

JWS in compact form, RS256. The signed payload is a SHA-256 digest of the canonicalized request: method, path, body hash, and selected headers (Content-Type, Idempotency-Key, UCP-Agent).

Request header

http
POST /api/ucp/v1/checkout-sessions HTTP/1.1Host: aly.storeAuthorization: Bearer aly_oauth_...Content-Type: application/jsonIdempotency-Key: 9e3f8a-...UCP-Agent: agent-vendor/1.4 (https://agent.example/info)Request-Signature: eyJhbGciOiJSUzI1NiIsImtpZCI6ImsxIn0.eyJodHRwIjp7Im0iOiJQT1NUIiwidSI6Ii9hcGkvdWNwL3YxL2NoZWNrb3V0LXNlc3Npb25zIn0sImJoIjoidHc... { ... body ... }

The JWS header carries kid — the agent's key id, resolvable via the agent's jwks_uri (published in the A2A agent card).

What gets signed

json
{  "iat": 1748112000,  "exp": 1748112300,  "iss": "https://agent.example",  "sub": "agent_pub_id_42",  "http": {    "m": "POST",    "u": "/api/ucp/v1/checkout-sessions",    "h": "Content-Type:application/json|Idempotency-Key:9e3f8a-...|UCP-Agent:agent-vendor/1.4"  },  "bh": "<base64url(sha256(body))>",  "nonce": "<random-128-bit>"}

Response signature

If the request was signed, the server signs its response with the store's key and returns:

http
HTTP/1.1 200 OKContent-Type: application/jsonResponse-Signature: eyJhbGciOiJSUzI1NiIsImtpZCI6Imo3In0...JWKS-Url: https://aly.store/.well-known/ucp/jwks.json

Pull the JWK by kid from the jwks_uri and verify. Cache the JWKS aggressively — keys rotate on a schedule broadcast in the discovery doc.

Verifying a signature

  1. Parse the compact JWS. Read kid from the header.
  2. Fetch jwks_uri and resolve the JWK for that kid.
  3. Verify the JWS signature against the JWK.
  4. Recompute the body hash and compare to bh.
  5. Verify iat/exp are within tolerance and nonce has not been seen before.

Failure modes

  • Signature missing on a store that requires it → HTTP 401 with error.code = signature_required.
  • Signature invalid → HTTP 401 with error.code = signature_invalid and a hint (clock skew, unknown kid, body mismatch).
  • Replay — same nonce + iat within window → HTTP 409.

Identity linking

Successfully signed requests log an identity_linkingrecord tying the agent's cryptographic identity to the resulting checkout session. Operators can audit which agent created which order, and a buyer can challenge a transaction that doesn't carry the expected signature.

Updated

Was this page helpful?