Core Concepts

Agent Identities

Agents are first-class non-human identities in AuthPI, distinct from users and API keys, with their own credentials, scopes, org memberships, and audit trail.

Last updated 2026-06-12

An Agent is a first-class non-human identity in AuthPI. AI agents, bots, and autonomous services get their own identifier (agt_ prefix), their own credentials, their own scopes, and their own audit trail — instead of borrowing a human user’s session or sharing a service-wide API key.

Each agent belongs to exactly one Issuer, just like users. Agents can carry descriptive attributes (model, provider, version) so you know which AI system is acting, not just that something acted.

Why a separate identity type

Before agent identities, teams typically gave AI agents either a human user account (so the agent inherits a person’s permissions and pollutes their audit history) or a shared API key (so every agent looks identical in logs and revoking one means revoking all). Agents fix both problems:

UserAPI keyAgent
Who it representsA humanYour own backend calling AuthPI’s management APIAn autonomous non-human actor in your product
Identifierusr_…key_…agt_…
Credential typePassword, passkey, magic link, social/SSOKey ID + secret sent via HTTP Basic authSecret verifier (client_credentials) and/or wallet verifier (blockchain address)
Token lifetimeSession-based access tokens with rotating refresh tokensNone — the key authenticates each request directlyFixed 5-minute access tokens; no refresh tokens
Organization membershipYes — memberships with scopesNoYes — same membership model as users
Audit identityEvents carry user_idRequests attributed to the keyEvents carry agent_id

Because each agent is individually addressable, you can scope, suspend, audit, and delete one agent without touching anything else.

The verifier model

Agents authenticate through verifiers — credentials attached to the agent. An agent can hold up to 20 verifiers, of two types, and can hold both types at once:

Secret verifiers power the OAuth 2.0 client_credentials grant. When you add a secret verifier, AuthPI generates a 42-character random secret, stores only its SHA-256 hash, and returns the plaintext exactly once. (High-entropy random secrets don’t need a work-factor hash like Argon2 — SHA-256 is sufficient and fast to verify.) At the token endpoint, the presented secret is hashed and compared in constant time against all of the agent’s active secret verifiers, which is what makes zero-downtime rotation possible: add a new secret, migrate, then remove the old one.

Wallet verifiers register a blockchain address as the agent’s on-chain identity for x402-style payment flows. The address is stored with its CAIP-2 network identifier (for example eip155:8453), and AuthPI maintains a reverse lookup from (network, address) to the agent — so activity observed for a wallet can be resolved back to the agent that controls it. Wallet verifiers do not mint tokens at the token endpoint; token issuance uses secret verifiers.

Every verifier tracks usage_count and last_used_at, so you can see whether a credential is actually in use before removing it.

Agent scopes

Agents carry their own scope list — up to 256 opaque strings (printable ASCII, no whitespace, max 256 characters each). AuthPI doesn’t interpret these strings; your application defines their meaning, exactly as with OAuth scopes generally (RFC 6749 §3.3).

At the token endpoint, an agent may request a subset of its scopes (scope=tickets:read). Requesting a scope the agent doesn’t hold fails with invalid_scope; requesting no scope grants the agent’s full allowed set. The openid scope is always filtered out — agents are not OIDC subjects and never receive ID tokens.

Agents in organizations

Agents can join Organizations as members alongside humans. The membership API accepts an agt_ ID anywhere a member_id is expected, and the resulting membership carries member_type: "agent", plus membership scopes, groups, and metadata — the same shape as a user membership. Agent members count toward the organization’s member limit.

This lets you model “the deploy bot is a member of the Platform org with deploys:execute” with the same primitives you use for people, and query an org’s roster — humans and agents together — through one API.

One honest caveat: agent access tokens do not embed organization membership claims. The client_credentials grant mints a token from the agent’s own scopes only — no session, no user, no memberships. If your resource server needs to enforce org-level permissions for an agent, look the membership up via the Core API members endpoints.

Agent token properties

Agent tokens are minted via the client_credentials grant at the issuer’s token endpoint (https://idp.authpi.com/{issuer_id}/token) and have deliberately narrow semantics:

Fixed 5-minute TTL. Agent access tokens always expire in 300 seconds — this is not configurable. Agents are expected to re-mint a token per work cycle. The short TTL is the propagation mechanism: change an agent’s scopes, suspend it, or remove its secret, and the change takes full effect within one TTL window, with no token revocation infrastructure needed.

No refresh tokens, no ID tokens. The grant returns only an access token (RFC 6749 §4.4). There is no long-lived credential derived from a token to leak or revoke.

The dat attestation claim. Every agent token carries a top-level dat (data attestation) claim:

{
  "iss": "https://idp.authpi.com/i_x7Kp2mQv9LbRwS",
  "sub": "agt_7c1de2f3a4b5c6d7e8f9a0b1c2d3e4f5",
  "aud": "https://api.example.com/tickets",
  "exp": 1781222700,
  "iat": 1781222400,
  "client_id": "agt_7c1de2f3a4b5c6d7e8f9a0b1c2d3e4f5",
  "dat": { "type": "agent" },
  "scope": "tickets:read tickets:triage"
}

dat.type declares what kind of identity the token represents (identity for human users, key for API-key-derived tokens, agent for agents). Resource servers should treat dat.type === "agent" as the primary semantic guard for distinguishing agent tokens from user tokens, with the agt_ prefix on sub as a secondary structural check — accept the token as an agent token only when both agree. This is stronger than a prefix heuristic alone and means user tokens can never be mistaken for agent tokens (or vice versa), even if scope strings overlap.

The aud claim is the resource parameter from the token request (RFC 8707), defaulting to the agent’s own ID. The scope claim is omitted entirely when an agent has no scopes — no misleading openid default.

Status and lifecycle

Agents have a status: active, suspended, or blocked. Suspension requires a status_reason. When an agent is not active:

  • Secret validation fails, so no new tokens can be minted — effective immediately.
  • Verifiers cannot be added.
  • Outstanding tokens are not revoked, but expire within 5 minutes.

Suspension is reversible (patch status back to active); deletion is not. Deleting an agent removes its verifiers, its wallet reverse lookups, and its listing entry.

Audit events

Every agent mutation emits an event you can consume via webhooks or the Events API, with the agent’s ID as subject:

EventWhen
agent.createdAgent created
agent.updatedProfile, scopes, or status changed
agent.deletedAgent deleted
agent.verifier.addedSecret or wallet verifier added
agent.verifier.removedVerifier removed

Organization membership changes involving agents emit the standard organization.membership.* events, with the agent identified in the event subject.

Next steps