Identity & Delegation
How Agent Identity Tokens (AITs) authenticate agents, and how OAuth Device Flow gates sensitive mutations behind buyer approval.
Agent Identity Tokens (AIT)
An AIT is an RS256-signed JSON Web Token issued by the gateway. It encodes:
agent_id— UUID of the agent record in Postgresscopes— array of allowed actions (read_products,manage_cart,execute_checkout,read_orders)iat/exp— standard timestamps
Public keys are published at /.well-known/jwks.json so any service can verify a token without round-tripping to the gateway.
Issue an AIT
curl -X POST https://api.synchronity.app/v1/auth/agents/register \
-H 'content-type: application/json' \
-d '{
"name": "my_claude_agent",
"scopes": ["read_products", "manage_cart", "execute_checkout"]
}'Returns { agent_id, token }. The token goes into your MCP client's Authorization: Bearer <token> header (the SDK handles this automatically).
Scope enforcement
Every gateway route declares a required scope. The gateway rejects requests whose AIT doesn't cover that scope with 403 forbidden_scope — an agent with only read_products is denied execute_checkout.
Human delegation (OAuth Device Flow)
Read-only actions go through immediately. Mutations that move money — and any action against a site marked require_human_delegation: true — require an explicit buyer signature obtained via a modified OAuth Device Flow.
Flow
-
Agent calls
execute_checkout. Gateway returns401 delegation_required:{ "error": "delegation_required", "verification_uri": "https://api.synchronity.app/authorize", "user_code": "PRN-456", "device_code": "...", "expires_in": 600 } -
Agent surfaces the
user_codeto the buyer in chat. Buyer visits the verification URI (Claude renders this inline; ChatGPT will open a browser). -
Buyer reviews the cart summary (merchant, items, total, agent name) and clicks Approve.
-
Agent polls
GET /v1/auth/delegate/status?device_code=.... Once approved, the response contains a one-shotdelegation_token. -
Agent retries
execute_checkoutwith thedelegation_tokenin the body. Gateway exchanges it for an order.
Approving with an emailed OTP
For flows where opening the verification page is awkward (e.g. a phone-based chat), approval can also be completed with a one-time passcode sent to the buyer's email. The buyer reads back the code, the agent submits it via the submit_delegation_otp MCP tool (or POST /v1/auth/delegate/otp), and the gateway returns the same one-shot delegation_token. The code is delivered as a plain OTP — not a clickable link — and is designed so an agent cannot approve its own request: the passcode is sent only to the buyer's verified email. In-chat payments use the same pattern via submit_payment_otp.
Why this matters
- Buyers see exactly what they're approving. The verification page shows the merchant, the line items, the total, and the agent identity — no surprises.
- Agents shouldn't be able to extract money silently. The flow is designed so that checkout requires buyer interaction, even with a valid agent token.
- Tokens are single-use and short-lived. A
delegation_tokenis good for one mutation, expires in 10 minutes, and is invalidated on use.
Connector keys
Separate from AITs and delegation tokens, the gateway holds a per-site connector key — the shared secret that lets the gateway talk to the connector behind a site. The raw key never leaves the gateway → connector wire; the gateway stores only an HMAC-SHA256 hash of it. Rotating a key requires admin authentication.