Secure your AgentOS with fine-grained permissions.
AgentOS validates the JWT on every request, then checks its scopes against the permissions each endpoint requires. This controls who can access and run your agents, teams, and workflows.
authorization=True only tells AgentOS to enforce JWT authorization. To verify tokens, AgentOS also needs a public key. Generate one from the control plane and wire it in.
1
Toggle JWT authorization
Enable JWT authorization when connecting a new AgentOS, or later from the OS Settings page.
2
Copy the public key
Copy the public key for your AgentOS from the modal
3
Set the verification key
Set the JWT_VERIFICATION_KEY environment variable to your public key in your .env file or export it directly in your terminal:
export JWT_VERIFICATION_KEY="your-public-key"
Or, if you manage keys via a JWKS file, point AgentOS at it instead:
export JWT_JWKS_FILE="/path/to/jwks.json"
Authorization is now active for your AgentOS.
The control plane only issues RS256 keys, which is also the default. See authorization troubleshooting for common setup issues.
The control plane is one way to issue verification keys, not the only way. AgentOS verifies any JWT signed with a key you provide, so you can mint and verify tokens entirely on your own infrastructure.
AgentOS verifies tokens but doesn’t issue them. Generate them in your backend or identity provider, signed with the key whose public half or shared secret you set as a verification key. Include the claims from JWT Token Structure; scopes is the claim RBAC checks.Send the token in the Authorization header:
verification_keys is a list. AgentOS tries each key in order until one verifies the token. Pass a second key to accept tokens from both the Agno control plane and your own backend at the same time.
authorization_config=AuthorizationConfig( verification_keys=[ AGNO_CONTROL_PLANE_PUBLIC_KEY, # tokens issued by os.agno.com YOUR_BACKEND_PUBLIC_KEY, # tokens minted by your service ], algorithm="RS256",)
This keeps the AgentOS UI working through the control plane while your backend mints its own tokens for service-to-service or production traffic. All keys in the list must use the algorithm set in algorithm.
Scopes split across two enforcement layers. Platform scopes are checked by the control plane. AgentOS scopes are checked by your runtime against incoming requests.Any resource:action scope also accepts a resource:<id>:action form to limit access to a specific resource. See Scope Format.The agent_os:admin scope grants full access to every AgentOS endpoint below.
Custom roles and scopes are available on the Enterprise plan. Book a call or email support@agno.com to enable.
Custom roles require JWT authentication. Without it, scope enforcement is skipped entirely by AgentOS and assigned roles have no effect.
Compose scopes into named roles in the control plane and assign them to users in your organization. Members inherit the scopes of every role assigned to them.
RBAC controls which operations a caller can perform. Per-user data isolation controls which rows a caller can see and write. Opt in with user_isolation=True:
When enabled, AgentOS uses the JWT sub claim as the user_id for every non-admin caller:
Operation
Behavior with user_isolation=True
Reads (sessions, memory, traces)
Scoped to the caller’s user_id. Other users’ rows are not returned.
Writes (sessions, memories, traces)
user_id is coerced to the caller’s sub. A caller cannot persist rows attributed to another user.
Cancel / resume / continue routes
Require session_id and verify the caller owns the run.
WebSocket reconnect
Requires session_id (and workflow_id) for non-admins.
A caller holding admin_scope (default agent_os:admin) bypasses isolation and sees all data. Set a custom override with admin_scope="ops:admin".
Isolation is off by default. JWT/RBAC still apply when user_isolation=False, but routes operate on the unscoped database and add no per-user ownership gates on top of RBAC. Per-user isolation requires a database that records user_id (PostgreSQL recommended for production).