# Identity Model

ZeroID models agents as identities, not as anonymous credentials. That distinction is what makes delegation, attribution, and revocation work cleanly across agentic systems.

### Tenant Model

Every ZeroID resource belongs to a tenant:

* `account_id`
* `project_id`

Admin APIs are tenant-scoped. In the current server design, tenant context is provided through `X-Account-ID` and `X-Project-ID` headers on `/api/v1/*` routes.

### Identity Types

ZeroID supports multiple identity types, so you can model real systems instead of collapsing everything into one generic service account:

<table><thead><tr><th width="161.95703125">Identity Type</th><th>Use It For</th></tr></thead><tbody><tr><td><code>agent</code></td><td>Autonomous agents, orchestrators, tool agents, evaluators, assistants</td></tr><tr><td><code>application</code></td><td>Apps that host or invoke agent workflows</td></tr><tr><td><code>mcp_server</code></td><td>MCP servers and tool-serving infrastructure</td></tr><tr><td><code>service</code></td><td>Internal services or non-agent workloads</td></tr></tbody></table>

#### Agent Sub-Types

When `identity_type` is `agent` ZeroID supports sub-types such as:

* `orchestrator`
* `autonomous`
* `tool_agent`
* `human_proxy`
* `evaluator`
* `chatbot`
* `assistant`
* `code_agent`
* `custom`

Use subtypes to preserve the identity's operational role in both registry data and issued tokens.

### WIMSE/SPIFFE URI

Each identity gets a stable URI in this shape:

```
spiffe://{domain}/{account_id}/{project_id}/{identity_type}/{external_id}
```

Example:

```
spiffe://zeroid.dev/acct-demo/proj-prod/agent/billing-orchestrator
```

This URI becomes the canonical machine identity. For most non-human flows, it is also the JWT `sub` claim.

### Important Identity Fields

These fields show up repeatedly across the registry, policies, and JWTs:

<table><thead><tr><th width="170.28515625">Field</th><th>Meaning</th></tr></thead><tbody><tr><td><code>external_id</code></td><td>Your stable application-level identifier</td></tr><tr><td><code>name</code></td><td>Human-readable display name</td></tr><tr><td><code>trust_level</code></td><td>How much confidence the platform has in the identity</td></tr><tr><td><code>allowed_scopes</code></td><td>Scopes the identity may request</td></tr><tr><td><code>public_key_pem</code></td><td>Public key for signed assertion flows like <code>jwt_bearer</code></td></tr><tr><td><code>framework</code></td><td>Optional framework metadata such as <code>langgraph</code>, <code>autogen</code>, or <code>crewai</code></td></tr><tr><td><code>capabilities</code></td><td>JSON metadata for what the identity can do</td></tr><tr><td><code>labels</code></td><td>Flat key-value labels for indexing and policy context</td></tr></tbody></table>

### Owner vs Principal vs Actor

These are easy to mix up. Keep them separate:

<table><thead><tr><th width="151.2109375">Field</th><th>Meaning</th></tr></thead><tbody><tr><td><code>owner_user_id</code></td><td>The user who registered or owns the identity</td></tr><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 principal that delegated authority, or the end user on whose behalf the agent is acting</td></tr></tbody></table>

Examples:

* A direct autonomous agent token usually has `sub = spiffe://.../agent/foo` and no `act`.
* A delegated token usually has `sub = sub-agent URI` and `act.sub = orchestrator URI`.
* A user-context token may have `sub = agent URI` and `act.sub = end-user ID`.

### Trust Levels

ZeroID uses trust levels as a compact signal for downstream authorization and issuance policy:

* `unverified`
* `verified_third_party`
* `first_party`

Trust level is not the same thing as authorization. It is an input into policy and a useful claim for downstream systems.

### Identity Lifecycle

Identities move through lifecycle states:

* `active`
* `suspended`
* `deactivated`

Deactivation matters operationally because tokens and keys tied to the identity may need to be rotated or revoked when the identity is no longer usable.

### Why This Model Matters

If you only keep a client ID or a service account name, you lose most of the context that agentic systems need:

* What kind of workload is acting
* Which system owns it
* Whether it is allowed to delegate
* How much should it be trusted
* Who authorized it in a multi-step chain

ZeroID keeps the identity context available at issuance and stores it within the JWT itself.

#### What's Next?

* Read [**Token Flows**](https://docs.highflame.ai/documentation/agent-identity/concepts/token-flows) to map this identity model onto actual OAuth and delegation patterns.
* Read [**Agent Delegation**](https://docs.highflame.ai/documentation/agent-identity/guides/agent-delegation) if you are building orchestrator and sub-agent workflows.
