Security & Auth
Authentication modes, scope enforcement, and policies for AgentOS API, MCP, and interface requests.
AgentOS selects a central authentication mode for protected REST, MCP, A2A, AG-UI, and WebSocket requests. Public discovery routes and interfaces with their own authentication have separate policies.
| Mode | Active when | Behavior |
|---|---|---|
jwt | authorization=True, JWT env vars (JWT_VERIFICATION_KEY / JWT_JWKS_FILE), or a manually installed JWTMiddleware | JWTs prove identity. Enable authorization separately to enforce their scopes. |
security_key | OS_SECURITY_KEY is set and no JWT source is configured | A shared key proves identity. No per-endpoint permissions. |
none | Neither is configured | No central credential requirement. Use for local development or explicitly bounded public serving. |
JWT configuration takes precedence over the security key. REST routes that use Agno's authentication dependency verify presented service-account tokens in all three modes. An otherwise anonymous MCP server needs an authentication layer to verify PATs.
JWT environment variables alone enable authentication. Set authorization=True on AgentOS, or on a manually configured JWTMiddleware, to enable JWT scope checks. Verified service account grants are enforced independently.
Surface-Specific Policies
- Slack, Telegram, and WhatsApp interfaces verify their own webhook requests and are excluded from central authentication at their configured prefixes. A2A and AG-UI remain centrally protected.
- With
mcp_auth, the FastMCP provider authenticates MCP requests and serves OAuth discovery. Agno PATs and configured JWTs can coexist with that provider. Provider-issued scopes are enforced even when JWT authorization is off. The MCP Server Card is public discovery by default. See MCP authentication. - Public Surface selects callable components and bounds public requests using shared PostgreSQL admission. It does not bypass an outer JWT or security-key middleware. Selected public workflows still require verified authentication.
AuthorizationConfig.excluded_route_pathsadds paths that bypass authentication. See excluded routes before configuring it.
Authorization (JWT)
AgentOS validates JWT tokens and checks scopes against required permissions for each endpoint. Enable it with authorization=True:
from agno.os import AgentOS
agent_os = AgentOS(
id="my-agent-os",
agents=[my_agent],
authorization=True,
)Tokens can be issued by the AgentOS control plane, your own backend, or a third-party identity provider like WorkOS, Auth0, or Okta. Protected requests without a valid credential return 401 Unauthorized; insufficient scopes usually return 403 Forbidden. Agent, team, and workflow listings can instead return a filtered or empty list.
See Authorization for the full setup.
Service Accounts (Machine Tokens)
Machine callers such as coding agents, chat apps, and CI pipelines authenticate with opaque agno_pat_... tokens instead of JWTs. Tokens are minted through the API or agno tokens create, carry their own scopes, and attribute every run to an sa:<name> principal:
curl -X POST http://localhost:7777/agents/my-agent/runs \
-H "Authorization: Bearer agno_pat_..." \
-d "message=hello" -d "stream=false"Service account scopes are ACL data stored in your database. REST authentication dependencies enforce verified grants in every mode, including security_key and none. For MCP, configure JWT, a security key, mcp_auth, or an appropriate auth middleware. Adding a database or sending a PAT to an otherwise anonymous MCP server does not activate PAT identity or scope enforcement.
See Service Accounts for minting, scoping, and revocation.
Security Key
Set a shared secret in the OS_SECURITY_KEY environment variable:
export OS_SECURITY_KEY="your-secret-key"Requests without a valid Authorization: Bearer <key> header return 401 Unauthorized. This is the simplest path to a protected AgentOS, suitable for local development or single-team prototypes. A valid key is a trusted root for centrally protected endpoints and can mint service account tokens. Separately authenticated webhooks and MCP OAuth retain their own policies.
For production deployments, use Authorization instead.