Scope an agent
Give an AI workload its own identity: a short-lived, narrowly scoped credential delegated from a real person, fully traceable in the audit log and revocable at any time.
An agent is a third kind of actor in OrthID, alongside humans and organisations. Instead of handing an agent a static API key with broad access, you issue it a credential that is scoped to a few permissions, short-lived, and delegated from the human who triggered the work. Every action the agent takes carries an actclaim recording that person, so the audit trail always answers “who is this really acting for?”
Under the hood this is OAuth token exchange (RFC 8693): OrthID exchanges the user’s session for a derived, constrained token rather than minting a fresh standing identity.
1. Issue a scoped credential
Call orthid.agents.issue from your backend with the user on whose behalf the agent acts, the exact scopes it needs, a TTL, and the region the work must stay in. Issue the credential as late as possible - ideally per task - so its lifetime maps to one unit of work.
import { orthid } from "@orthid/sdk";
// A user asked their assistant to reconcile this month's claims.
const credential = await orthid.agents.issue({
onBehalfOf: "user_8sQ1", // the real person delegating
scope: ["claims:read", "claims:reconcile"], // least privilege
ttl: "15m", // expires fast
region: "au-syd-1", // pinned to a data boundary
});
// credential.token -> hand to the agent for this task
// credential.expiresAt
// credential.actorId -> the agent identity OrthID createdLeast privilege scopes
Scopes are the permissions the credential may exercise, and they can never exceed what the delegating user holds - OrthID intersects the requested scope with the user’s own grants. Ask only for what the task needs. An agent that reconciles claims should not be able to delete them, so request claims:reconcile, not claims:*.
TTL
The ttl is how long the credential lives, expressed as a short duration such as 5m or 15m. A short TTL means a leaked token is useless minutes later and there is rarely anything to clean up. Match the TTL to the expected task length rather than to the whole user session.
2. Use the credential
The agent presents its token like any other bearer credential. OrthID enforces the scope, the expiry and the region on every call, and rejects anything outside them.
import { orthid } from "@orthid/sdk";
// Initialise an agent-scoped client with the issued token.
const agentClient = orthid.withToken(credential.token);
// Allowed: within scope.
const open = await agentClient.claims.list({ status: "open" });
await agentClient.claims.reconcile({ ids: open.map((c) => c.id) });
// Denied: outside scope -> throws OrthIDScopeError, nothing happens.
await agentClient.claims.delete({ id: "clm_1" });3. See it in the audit trail
Every agent action is recorded with both the agent actor and the human it acted for. Filter the audit log by the delegating user or by the agent actor to reconstruct exactly what happened.
import { orthid } from "@orthid/sdk";
const events = await orthid.audit.list({
actorId: credential.actorId, // this agent
// or: onBehalfOf: "user_8sQ1" to see all agents for a person
});
console.log(events[0]);
// {
// action: "claims.reconcile",
// actor: { type: "agent", id: "agt_5kP", scope: ["claims:reconcile"] },
// act: { type: "user", id: "user_8sQ1" }, // RFC 8693 act claim
// region: "au-syd-1",
// at: "2026-06-22T03:14:07Z"
// }The act claim (RFC 8693)
The actclaim is the heart of delegation. It is carried inside the agent’s token and copied onto every audit event, so an agent identity can never hide behind itself - it always names the human principal it descends from. If an agent in turn delegates to another agent, the chain nests, and OrthID preserves the full lineage back to the original person.
4. Revoke early
Most agent credentials simply expire when their TTL elapses. When you need to cut access immediately - a task is cancelled, or a token is suspected leaked - revoke it. Revocation is instant and applies to the credential everywhere it would be accepted.
import { orthid } from "@orthid/sdk";
// Revoke a single agent credential now.
await orthid.agents.revoke({ actorId: credential.actorId });
// Or revoke every live agent credential delegated from a user.
await orthid.agents.revokeAll({ onBehalfOf: "user_8sQ1" });Next steps
- Tokens & token exchange explains the JWT structure and how the
actclaim is derived. - OrthID for agents covers the wider agent identity model and what it unlocks for AI workloads.