# 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

<table><thead><tr><th width="508.13671875">Scenario</th><th>Recommended Flow</th></tr></thead><tbody><tr><td>Autonomous agent authenticates as itself</td><td><code>api_key</code></td></tr><tr><td>Service authenticates with an OAuth client</td><td><code>client_credentials</code></td></tr><tr><td>Agent proves identity with its own signed assertion</td><td><code>jwt_bearer</code></td></tr><tr><td>Orchestrator delegates to sub-agent</td><td><code>token_exchange</code></td></tr><tr><td>Human authorizes an agent once with PKCE</td><td><code>authorization_code</code></td></tr><tr><td>Long-running job renews access without full re-authentication</td><td><code>refresh_token</code></td></tr></tbody></table>

### 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:

<table><thead><tr><th width="195.3203125">Claim</th><th>Meaning</th></tr></thead><tbody><tr><td><code>sub</code></td><td>The principal currently authenticated by the token</td></tr><tr><td><code>act.sub</code></td><td>The delegating principal or acting user</td></tr><tr><td><code>grant_type</code></td><td>The flow used to issue the token</td></tr><tr><td><code>scopes</code></td><td>Granted scopes</td></tr><tr><td><code>delegation_depth</code></td><td>How deep the current delegation chain is</td></tr><tr><td><code>trust_level</code></td><td>Trust level of the current identity</td></tr><tr><td><code>identity_type</code></td><td>Agent, service, application, or MCP server</td></tr><tr><td><code>sub_type</code></td><td>Operational role like orchestrator or tool agent</td></tr></tbody></table>

### 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?

* Use [**Agent Delegation**](https://docs.highflame.ai/documentation/agent-identity/guides/agent-delegation) for a concrete RFC 8693 flow.
* Use [**Credential Policies**](https://docs.highflame.ai/documentation/agent-identity/guides/agent-delegation) to control which flows are permitted.
