Skip to main content

Cross-app access: Identity Assertion JWT Authorization Grant (ID-JAG)

When an enterprise puts an agent host — ChatGPT Enterprise, Claude for Work, or an internal A2A fleet — in front of Devotel Orbit, the first question is not “which endpoint?” but “which credential, and who does it blame?” ID-JAG (the IETF Identity Assertion JWT Authorization Grant draft) is the emerging standard answer: your identity provider issues a signed assertion naming the end user, the agent host redeems it for a short-lived access token, and every call is attributable to both the user and the agent that made it. This page explains the model and maps each stage onto the Orbit primitives that already implement it; the step-by-step wiring lives in Set up cross-app access with ID-JAG-style token delegation.

Section 1 — The problem: static keys can’t name a user or an agent

The default way to connect an agent host to an API is a static API key. That shape has three structural weaknesses for agent delegation:
  • The scope is wrong-sized. Agent hosts accumulate. A key minted for one workflow tends to get reused for the next, and ends up broadly scoped — a bearer whose compromise opens every surface it can reach, indefinitely.
  • The token can’t say who asked. A static key names an integration, not a person. When an enterprise employee’s chat session drives the agent, the request Orbit receives is indistinguishable from every other request that host ever makes. Audit stops at “the agent host did something” — never “which user, through which agent.”
  • Nothing expires on its own. Static keys live until someone rotates them. Delegation that began as a one-off task outlives the task by months.
The security community’s fix for all three is the same: replace the standing, broadly scoped credential with a short-lived token minted per delegation, bound to the end user and the calling agent, scoped to the actual task, and dead in minutes. ID-JAG is that fix being standardized at the IETF.

Section 2 — The flow: IdP assertion in, bound access token out

ID-JAG (draft-ietf-oauth-identity-assertion-authz-grant) defines a three-party exchange:
  1. The enterprise IdP issues an identity assertion. Your Okta, Auth0, or Microsoft Entra tenant signs a JWT that names the end user and the application the user is working through. The enterprise — not the API provider and not the agent host — is the root of identity.
  2. The agent host redeems the assertion. ChatGPT Enterprise, Claude for Work, or your own A2A coordinator presents the assertion to the resource server’s grants endpoint and receives a short-lived access token in return. The assertion is single-purpose: it exists only to be exchanged.
  3. The access token is bound to both parties. The returned token carries the end user’s identity (so the resource server can attribute and authorize per human) and the calling agent’s identity (so a fleet of agents sharing one enterprise can’t hide behind each other). It is scoped to what the delegation actually needs and expires in minutes.
The contrast with Section 1 is the point: nothing standing, nothing broad, nothing unattributable.

Section 3 — Token binding, expiry, and how resource servers validate

Three properties make the redeemed token safe to trust:
  • Binding is in the signed payload. The user and agent identities travel as claims inside the token’s signature. Tampering with either invalidates the token exactly like any other claim — there is no side-channel lookup to spoof. On the A2A path Orbit’s agent tokens carry this as the standard act (actor-chain) claim: the outermost entry is the nearest agent to the call, and walking the chain reaches the human principal accountable for it.
  • Expiry is structural, not procedural. The token carries exp and the verifier enforces it — a leaked token’s usable window is its remaining lifetime, nothing more. Orbit’s just-in-time credential broker clamps minted lifetimes to a hard ceiling of 300 seconds, regardless of what the caller requests.
  • Audience and scope are checked server-side. A resource server validates the signature first, then aud (the token must name the resource being called — a token minted for one audience never authenticates to another), then the scope claim against the specific action being attempted. On Orbit’s federated agent surface, an inbound bearer token whose audience isn’t the addressed agent, or whose scope doesn’t contain the skill being invoked, is rejected before any skill logic runs — and a present-but-invalid bearer never silently downgrades to a weaker handshake.
For external verification of Orbit-issued agent tokens, Orbit signs with Ed25519 (EdDSA) when an agent signing key is provisioned and publishes the public half as a standard JWK Set at /public/.well-known/jwks.json on the API host — so a third party can verify “this call came from tenant X’s Orbit agent, with these scopes” with no shared-secret onboarding. The signed AgentCard a federated agent serves advertises the bearer scheme (at+jwt, RFC 9068 profile) and that JWKS URI.

Section 4 — What exists on Orbit today, and how it maps to ID-JAG

The ID-JAG draft is still in progress at the IETF, and Orbit does not yet expose a literal “redeem an IdP assertion” endpoint. What ships today is the resource-server half of the model, in three primitives:
  • Authorization mandates — the control plane. A principal declares, per agent, what actions, tools, and data categories are allowed, with an invocation cap, an expiry, and a tamper-evident consent digest. Mandates can be delegated (attenuated — a child mandate can only ever narrow the parent) and revoked. This is where “the end user authorized this agent to do X” is recorded.
  • Just-in-time credential mintingPOST /api/v1/agents/agent-authorization-mandate/credential re-runs the exact same authorization gate against a declared intent (“agent X needs tool Y, for N seconds”) and, only when authorized, returns a single-scope bearer token whose lifetime is clamped to at most 300 seconds. The token names the agent as its subject and records the accountable principal in its actor chain. This is the shipped “assertion in, bound token out” stage: the mandate plus intent is the assertion Orbit consumes today.
  • RFC 9068 agent bearer tokens on A2A — federated agents accept scoped OAuth2 profile tokens (typ: "at+jwt", per-audience aud, per-skill scope) as an inbound credential alongside the legacy HMAC handshake. This is the validation posture Section 3 describes, live on a public boundary.
The MCP surface tells the same story from the other direction: an external client (Claude, ChatGPT, an IDE agent) reaches Orbit through the hosted MCP server, and its visibility of your tenant is scope-gated by the credential it presents — see the hosted server handshake for that inbound catalog. The practical takeaway: build against mandates plus the credential endpoint now, and the IdP-issued assertion the draft standardizes slots in as an alternative front door to the same gate — the gate, the binding semantics, and the audit story do not change.

Section 5 — Revocation, audit, and how this differs from API keys

Revocation is one action, not a hunt. A mandate is revocable (POST /api/v1/agents/agent-authorization-mandate/revoke) and terminal — every subsequent gate check against it denies, and any token minted from it dies within its 300-second ceiling regardless. Compare the API key story: you revoke the key, but you first have to know which of the host’s workflows hold a copy. Audit names a person. Mandate issuance, every gate decision (granted or denied), every credential mint, and revocation are each audit-logged with the principal and agent identities — the same accountability that travels inside the token’s actor chain. An API key’s audit trail, by contrast, answers “the key did this”; a mandate-backed token answers “user U, through agent A, did this.” The two models are not mutually exclusive — subaccount API keys remain the right credential for long-lived first-party integrations (messaging workers, CDP pipelines, orchestration dashboards). The decision rule: use API keys for your own services acting as themselves; use mandate-backed short-lived tokens for an agent acting on a user’s delegated authority. For the API key side of that split, see Choose and scope API keys for messaging, CCaaS agents, and the CDP; for the model underneath, the authentication model concept page. When the ID-JAG draft finalizes and IdP vendors ship assertion support, expect the runbook’s IdP-side section to simplify — the Orbit-side verification posture you build today is the same one the standard assumes.