Token Flows

ZeroID supports multiple OAuth-style grant flows because agent systems do not all look the same. Pick the flow that matches how authority enters the system and how it needs to propagate.

Quick Flow Selection

Scenario
Recommended Flow

Autonomous agent authenticates as itself

api_key

Service authenticates with an OAuth client

client_credentials

Agent proves identity with its own signed assertion

jwt_bearer

Orchestrator delegates to sub-agent

token_exchange

Human authorizes an agent once with PKCE

authorization_code

Long-running job renews access without full re-authentication

refresh_token

Public Token Endpoint

All flows below use the public token endpoint:

POST /oauth2/token

Related public endpoints:

  • POST /oauth2/token/introspect

  • POST /oauth2/token/revoke

  • GET /.well-known/jwks.json

  • GET /.well-known/oauth-authorization-server

api_key

Use this when an agent has already been registered and you want a straightforward bootstrap path.

How it works:

  1. Register an agent through the admin API.

  2. Save the returned zid_sk_* API key securely.

  3. Exchange that API key for a short-lived JWT at /oauth2/token.

Why it exists:

  • Great developer experience for first integration

  • Good fit for autonomous agents and local development

  • Keeps runtime auth on short-lived JWTs even if bootstrap uses a long-lived secret

client_credentials

Use this when you want a classic OAuth client flow for a service or application identity.

You provide:

  • client_id

  • client_secret

  • tenant context in the request body for lookup

Good fit:

  • backend services

  • scheduled jobs

  • infrastructure components that are not modeled as signed assertion holders

jwt_bearer

Use this when the identity should prove possession of its own key pair.

You provide:

  • subject as a signed JWT assertion

  • a registered public_key_pem on the identity

Good fit:

  • stronger non-human identity proof

  • agents with managed key material

  • scenarios where you want to avoid shared secrets at issuance time

token_exchange

Use this when one agent delegates authority to another.

You provide:

  • subject_token for the delegating credential

  • actor_token for the sub-agent's signed assertion

  • optional requested scope

ZeroID then:

  • verifies the delegating token

  • verifies the sub-agent assertion

  • intersects scope

  • increments delegation depth

  • preserves the chain in act.sub

This is the flow that makes multi-agent delegation explicit and auditable.

authorization_code

Use this when a human authorizes an agent through a more traditional OAuth flow, and the agent continues operating after that initial step.

Good fit:

  • user-approved agent apps

  • enterprise applications that want a familiar OAuth control point

refresh_token

Use this when tokens need to be renewed across a long-running execution.

ZeroID treats refresh tokens as rotating credentials and supports reuse detection, so refresh tokens are not just long-lived bearer strings with no guardrails.

Claims You Will See Across Flows

These claims matter most when you design downstream authorization:

Claim
Meaning

sub

The principal currently authenticated by the token

act.sub

The delegating principal or acting user

grant_type

The flow used to issue the token

scopes

Granted scopes

delegation_depth

How deep the current delegation chain is

trust_level

Trust level of the current identity

identity_type

Agent, service, application, or MCP server

sub_type

Operational role like orchestrator or tool agent

Practical Guidance

Prefer:

  • api_key for first adoption and OSS quickstarts

  • jwt_bearer or token_exchange when agent identity proof and delegation matter

  • client_credentials for conventional service-to-service flows

Avoid:

  • treating api_key as the runtime credential

  • passing one agent's token to another agent as a shared secret

  • skipping delegation and collapsing multiple agents into a single principal

What's Next?

Last updated