An agent is a named, operator-provisioned workload identity with its own API key, audit trail, and bound grants. Use agents when one app key isn’t enough — when multiple distinct workloads should be revocable, rotatable, and auditable independently.Documentation Index
Fetch the complete documentation index at: https://docs.alterauth.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use Agents (vs just App)
| Use case | Use… |
|---|---|
| Single backend service that calls third-party APIs | App |
| Cron job or webhook handler | App |
| Multi-step research workflow where each step is audited under its own name | Agent per role |
| LangGraph supervisor with named sub-agents (researcher, writer, reviewer) | Agent per sub-agent |
| Workload that should be revocable / rotatable independently of the app key | Agent |
| MCP server running in a sandbox where exposing the master key is unsafe | Agent |
App instance plus N Agent instances, each with its own key.
Two SDK shapes for the same agent
Once an operator provisions an agent in the developer portal, the SDK can reach it two ways. Both produce the same backend identity — same audit attribution, same access boundary, same grant filter. Pick based on isolation needs.Shape (a) — per-agent API key (use when isolation matters)
The operator mints a per-agent API key (alter_key_agent_…) in the portal. The agent process loads it from env, constructs Agent:
Shape (b) — master key + impersonation (use when monolithic)
The application uses the app key, callsapp.agents.list() once at boot to discover the agent’s UUID, and calls app.get_agent(uuid) per agent:
App.agents.list(), App.agents.get_by_name(), and the full operator namespace.
Cardinality and access boundary
An agent can hold many grants — operators map as many as the agent needs (one for Slack, one for Stripe, one for Drive). Each mapping is explicit. The agent can reach only the grants the operator mapped to this specific agent — not grants belonging to other agents, not grants belonging to users, not generic system grants. The filter is enforced server-side per request, regardless of which SDK shape signed it.Identity-blending rules
These are common gotchas — keep them in mind:- Per-agent key + JWT is forbidden. Calling with an
alter_key_agent_…key and auser_tokenin the same request returns HTTP 400. Agents are not user impersonators. If a flow needs both an agent identity and a user identity, run two separate requests. - App key + agent UUID + JWT is the “agent code path inside a user session” pattern. Use
App(api_key=APP_KEY, caller=AGENT_UUID, user_token_getter=…). JWT wins (the user is the principal); the agent UUID becomes audit attribution. - Bad agent UUID in
calleris rejected. A UUID-shapedcallerthat doesn’t match an active managed agent in the calling app returns HTTP 404. Free-form (non-UUID)callervalues are not subject to this check.
”But the agent code path is acting on behalf of a user…”
Common pattern: an LLM agent runs server-side as part of an end-user-driven request. The right model is NOT a separate agent principal — it’s the user principal flow with the agent’s name carried as audit metadata.Roadmap
Agent as principal for OAuth grants. Today, agents own managed-secret grants directly (phases 1–3 shipped). OAuth grants are owned by users, with agents accessing them via delegations. A future release will let agents own OAuth grants directly. Tracking in the SDK_REDESIGN planning doc.
See also
Creating agents
Operator surface: provision, list, update, get-by-name.
Keys and rotation
Mint, list, deprecate, and revoke per-agent keys.
Agent runtime
The Agent class: me(), trace(), authenticate().
Approvals
Human-in-the-loop approvals for sensitive calls.