HomeJournalThis post

Agent Token Exchange With RFC 8693

Bind subject, actor, audience, resource, scope, lifetime, and approval into an authority ledger for every delegated tool credential.

JP
JP Casabianca
AI Engineer and Product Designer · full-stack delivery · Bogotá

Agent token exchange should turn a broad user or workload credential into a narrower, short-lived credential for one agent tool call path. This guide builds an authority ledger around RFC 8693 and proves that subject, actor, audience, resource, scope, lifetime, and originating approval never expand during exchange.

Agent token exchange is a policy decision

RFC 8693 defines a protocol for exchanging one security token for another and represents delegation through subject and actor claims. It does not promise that the issued token is narrower. An authorization server could issue equivalent or broader authority unless local policy prevents it, so agent token exchange must be treated as an authorization decision with a denial corpus, not as a mechanical token-format conversion.

Name the parties before configuring grants. The subject is the user or workload whose authority is being exercised; the actor is the agent runtime performing the work; the client is the component requesting exchange; the tool API is the resource server; and the authorization server judges the exchange. Keeping those roles separate prevents delegated agent credentials from collapsing human approval, runtime identity, and tool permissions into one opaque “agent” principal.

Add a trust-boundary diagram to the protocol review. It should show which component validates the parent token, reads approval, authenticates the actor, chooses resource and scope, signs the child token, and consumes it.

Start with one low-risk read tool before enabling writes. The narrow pilot makes actor, resource, and receipt errors visible without testing delegation semantics against an irreversible operation.

Delegation narrows through an authority ledgerA user subject and agent actor enter an authorization server that emits a resource-bound short-lived tool token after approval and scope checks.subjectactorexchange policy+ approvaltool token
  • Subject: originating user or workload
  • Actor: identified agent runtime
  • Policy: narrowing and approval checks
  • Tool: one audience and resource
Figure 1: Exchange records who acts for whom and what authority was removed.

Model the authority ledger before tokens

For each exchange, store a correlation ID, subject identity, actor identity, client, issuer, requested and issued audience, resource, scopes, issued-at time, expiry, proof-key thumbprint, approval ID, policy version, and parent-token fingerprint. The ledger should contain hashes or stable references rather than raw bearer tokens. Its purpose is to explain why the authorization server believed a particular agent token exchange was allowed and what authority was removed.

Record requested and issued values side by side. A statement such as requested=[calendar.read, calendar.write], issued=[calendar.read], resource=calendar.example, ttl=300s makes narrowing reviewable. If policy cannot prove that every issued permission is contained by the parent authority and originating approval, deny. A downscoped access token is an outcome of that containment rule, not an inherent product feature of OAuth token exchange.

Give each ledger field a source of truth and retention rule. The approval service owns consent, workload identity owns the actor, policy owns containment, and the exchange service records only references needed for audit and revocation.

Make ledger queries part of incident drills. A responder should locate every child credential descended from one approval and identify their expiry and proof keys without searching raw logs manually.

CaseSubject/actorResourceScopeDecision
Read calendarApprovedcalendarreadIssue
Write calendarApprovedcalendarwriteDeny
Read payrollApprovedpayrollreadDeny
Unknown actorMissingcalendarreadDeny
Figure 2: The exchange matrix fails closed when any authority dimension widens.

Bind the token to resource and audience

Audience names who may accept the token; resource identifies the protected service for which authorization is requested. Use RFC 8707 Resource Indicators so the request names the intended tool API and policy rejects ambiguous or multiple-resource expansion. The issued token should be useless at a sibling API even when both services recognize the same issuer.

Keep resource vocabulary precise enough for policy but stable enough for operations. Agent token exchange for calendar.example may still be too broad if read and write routes have very different risk; scopes or rich authorization details can narrow the action. Pair this with OAuth RAR least authority when an operation needs structured limits such as a date window, recipient, or maximum amount rather than a bag of coarse strings.

Test confused-deputy cases in which a valid token intended for one resource is presented through another client or gateway. Exact audience and resource validation should deny before route-level business logic interprets the payload.

Represent multiple resources as multiple exchanges unless policy explicitly understands the combined request. Smaller tokens reduce confused-deputy risk and make denial, revocation, and audience checks easier to explain.

Preserve subject and actor through delegation

The tool needs to know both whose authority is involved and which runtime acted. Preserve the subject in sub and represent the current actor according to the trust contract, including the delegation chain when necessary. Do not overwrite the user with a service identity or treat the agent's workload credential as proof of user consent. The AI agent workload identity guide covers how the runtime proves its own identity independently.

Set a maximum delegation depth and reject loops, unknown issuers, stale approvals, and actor substitutions. If agent A delegates to agent B, policy should explain whether that hop is allowed and whether every scope remains within the original grant. Agent token exchange telemetry must make the chain queryable without forcing a responder to reconstruct it from unrelated application logs after an incident.

Render the subject and actor distinctly in user and operator surfaces. “JP via calendar-agent-3” communicates delegation far better than a single display name that makes service behavior look like a direct human action.

If an actor chain is too large for routine tokens, store a signed lineage reference with bounded retrieval. Do not silently truncate delegation history and leave the resource server believing the last actor acted directly.

The authority-ledger fixture checks containment across subject, actor, audience, resource, scope, lifetime, and approval before issuing a derived credential.

Runnable artifact — agent-token-narrowing.test.mjs

import assert from "node:assert/strict";
const parent={sub:"u7",actor:"agent-a",aud:"broker",resources:["calendar"],scopes:["read","list"],exp:1000,approval:"ap-9"};
const allowed=x=>x.sub===parent.sub&&x.actor===parent.actor&&x.aud==="calendar-api"&&parent.resources.includes(x.resource)&&x.scopes.every(s=>parent.scopes.includes(s))&&x.exp<=parent.exp&&x.approval===parent.approval;
const good={sub:"u7",actor:"agent-a",aud:"calendar-api",resource:"calendar",scopes:["read"],exp:700,approval:"ap-9"};assert.equal(allowed(good),true);
for(const change of [{scopes:["write"]},{resource:"payroll"},{exp:1200},{actor:"agent-b"},{approval:"ap-x"}])assert.equal(allowed({...good,...change}),false);
console.log("PASS: exchange policy denies every widening mutation");

Run node agent-token-narrowing.test.mjs. Expected receipt: PASS: exchange policy denies every widening mutation.

Use short lifetime and sender constraint together

Short expiry limits the replay window but does not stop a stolen bearer token from being used immediately. Bind sensitive tool credentials to a key held by the agent runtime and verify a fresh proof at the resource server. RFC 9449 specifies DPoP, while OAuth DPoP for agent tools covers method, URI, nonce, replay, and gateway details.

The authorization server must bind the proof-key thumbprint into the issued token, and the resource server must compare it with each request proof. Rotate keys deliberately rather than accepting an arbitrary new thumbprint during retry. An agent token exchange receipt should show expiry and key binding together: a five-minute token copied away from its private key remains unusable, while the ledger still identifies the runtime authorized to hold that key.

Exercise clock skew and nonce challenge behavior across the same gateways used in production. A theoretically sender-constrained token still fails operationally if proxies rewrite targets or replicas disagree about replay state.

Keep sender-constrained keys non-exportable where the platform supports it and scope them to one agent session. The threat model should still cover compromised runtimes that can invoke the key without extracting it.

  1. 1Approve

    Capture human or workload authority

  2. 2Exchange

    Evaluate subject, actor, resource, scope, and TTL

  3. 3Bind

    Attach the agent proof-key thumbprint

  4. 4Verify

    Check token, proof, policy, and one tool effect

Figure 3: Approval becomes one bounded, sender-constrained tool session.

Enforce narrowing at both server boundaries

The authorization server decides whether to issue, but the resource server still validates issuer, signature, audience, time, proof binding, and local policy. Never infer that possession of an exchanged token makes every route under its audience valid. The tool should map scopes and structured grants to named operations and deny unknown values. Compare those rules with Cedar vs OPA agent authorization when selecting an evaluation layer.

Keep issuance and use receipts correlated. A successful agent token exchange followed by ten denied tool calls may indicate a stale policy mapping, an attempted escalation, or a confused agent plan. Log denial categories without raw tokens, and cap retries so a policy denial cannot be converted into a broad search across scopes, resources, or actors. Authorization failures are terminal evidence for that proposed action until trusted context changes.

Compare the exchange policy and resource policy with a shared conformance corpus. They need not use identical engines, but every issued scope must have one understood enforcement meaning at the tool boundary.

Return a stable authorization decision ID to the resource server. That reference connects issuance policy to later use without requiring every service to retain the same verbose explanation or sensitive approval fields.

Test the denial corpus before the happy path

Mutate each ledger dimension independently: different subject, unregistered actor, unexpected audience, sibling resource, added scope, extended lifetime, missing approval, expired parent, unknown issuer, altered proof key, and excessive delegation depth. Then combine mutations because attackers and bugs rarely change one field politely. Agent token exchange should deny by default when containment cannot be evaluated, including when a policy dependency is unavailable.

Also test replay and race behavior. Reusing an exchange request may be acceptable if it returns an equivalent bounded grant, but it must not create a token with later expiry or different key binding. An approval revoked between exchange and tool use must be enforced according to the declared revocation model. Document unavoidable propagation windows instead of claiming immediate revocation the architecture cannot deliver.

Load-test the denial path as well as issuance. A dependency outage should fail closed with bounded latency and useful telemetry, not exhaust the service until operators are tempted to bypass containment checks.

Exercise stale caches and regional policy divergence. A token issued in one region must not gain authority merely because another resource-server replica has an older scope or revocation mapping.

Make delegated authority visible to people

Show the user what the agent can access, for which operation, until what time, and under which approval. A review surface should say “Calendar assistant may read events for five minutes,” not “OAuth granted.” Provide revocation that targets the approval or agent session without disabling unrelated applications. That interface turns the authority ledger into a product contract rather than a security artifact no one sees.

Revisit agent token exchange whenever tool resources, scope semantics, actor identity, or approval UX changes. Audit one real trace from consent through exchange and tool decision, then prove the issued credential is narrower along every dimension. The durable claim is not that RFC 8693 downscopes; it is that your authorization policy issued one bounded credential and preserved enough evidence to explain why.

Include a plain-language session history beside the machine ledger. Users should recognize which approval produced which tool access, while responders retain precise identifiers and policy versions for investigation.

Include denial explanations that are safe for each audience. Users need an actionable summary, agents need a bounded terminal category, and responders need the exact failed containment dimension and policy version.