Skip to content

feat(identity): RFC-8693 token exchange for delegated agent tokens (#43)#77

Merged
amitpaz1 merged 1 commit into
mainfrom
feat/rfc8693-token-exchange
Jul 7, 2026
Merged

feat(identity): RFC-8693 token exchange for delegated agent tokens (#43)#77
amitpaz1 merged 1 commit into
mainfrom
feat/rfc8693-token-exchange

Conversation

@amitpaz1

@amitpaz1 amitpaz1 commented Jul 7, 2026

Copy link
Copy Markdown
Member

Tier 1: DELEGATION. An actor agent B exchanges its own agent token
(actor_token) + a subject agent's token (subject_token) at
POST /api/agents/token for a short-lived DELEGATED token that says
"B acting on behalf of A".

Strict RFC-8693 §4.1 claim shape: sub = the on-behalf-of principal, the
current actor in the top-level act.sub (chains nest inward). Every consumer
reads the ACTOR via actingAgentOf() (act.sub ?? sub), so budgets (#13), MCP
guardrails (#14), virtual-key binding and lens attribution all target the
actor, while sub records who it acts for. A plain token has no act, so sub is
the actor — existing tokens/verifiers are byte-for-byte unchanged.

- lib/agent-tokens.ts: verifyAgentTokenClaims exposes {sub, act}; verifyAgentToken
  now returns the acting agent; actingAgentOf/onBehalfOfAgent helpers.
- lib/token-exchange.ts (new): mint an RS256 delegated token (act chain,
  depth-capped), fail-safe.
- routes/agent-tokens.ts: the token-exchange grant (opt-in + RS256-only;
  requires both subject_token + actor_token — no impersonation; actor must be a
  live agent; possession of both tokens is the authorization, may_act is Tier 2).
- config.ts: AGENT_TOKEN_EXCHANGE_ENABLED (default off) + warn-if-partial.
- docs/agent-identity.md: new section + config row + Future-work flip.

Deferred (documented): may_act restriction (Tier 2), scope/audience narrowing
(Tier 3). Must ship in lockstep with the AgentLens verifiedOnBehalfOf mirror.

15 new tests; full server suite green (bar the pre-existing rate-limiter flake).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKkfVA3iY5G3Q43Mg4Xsu2
@amitpaz1
amitpaz1 merged commit fbfae7e into main Jul 7, 2026
4 checks passed
@amitpaz1
amitpaz1 deleted the feat/rfc8693-token-exchange branch July 7, 2026 13:00
amitpaz1 added a commit to agentkitai/agentlens that referenced this pull request Jul 7, 2026
) (#330)

Mirror of the AgentGate RFC-8693 token-exchange feature (agentkitai/agentgate#77)
— must ship in lockstep so a delegated token verifies identically in both.

A delegated agent token carries the on-behalf-of principal in sub and the actor
in the top-level act.sub. AgentLens now reads the ACTOR (act.sub ?? sub) as the
verified identity — so verifiedAgentId + the whole attribution surface target the
acting agent, exactly like AgentGate's actingAgentOf() — and stamps the principal
into a new server-set verifiedOnBehalfOf metadata key. A plain (non-delegated)
token has no act, so sub is the actor: unchanged.

- lib/agent-identity.ts: readActor() extraction; verifyAgentTokenWithMethod returns
  { id: actor, method, onBehalfOf? }; stampVerifiedAgent stamps verifiedOnBehalfOf;
  added to VERIFIED_AGENT_META_KEYS (strip-list) so a client can't forge it.
- routes/events.ts + routes/otlp.ts: thread onBehalfOf into the stamp.

Delegated purchases now read as "B acting for A" in the tamper-evident trail.
5 new tests; full server suite green (2510 passed).


Claude-Session: https://claude.ai/code/session_01CKkfVA3iY5G3Q43Mg4Xsu2

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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