Skip to main content
AgentOS provides built-in Role-Based Access Control (RBAC) that validates JWT scopes against required permissions for each endpoint of the API. This allows you to control who can access and run your agents, teams, and workflows, as well as other functions on the AgentOS API. This functionality enables you to control access when building your own applications on AgentOS. Visualize how identity and authorization flow in AgentOS RBAC: JWT verification flow
  • The Control Plane (or your auth system) generates signed JWT tokens which encode user identity and permissions.
  • JWT tokens are presented on every API call from your application’s backend, UI, or integrations.
  • AgentOS validates each JWT and checks for the required scopes before granting access to agents, teams, or workflows, and other internal resources.

Quick Start

Enable RBAC when initializing AgentOS:
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIChat
from agno.os import AgentOS
from agno.os.config import AuthorizationConfig

db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

agent = Agent(
    id="my-agent",
    model=OpenAIChat(id="gpt-4o"),
    db=db,
)

agent_os = AgentOS(
    id="my-agent-os",
    agents=[agent],
    authorization=True,
)

app = agent_os.get_app()
It is required to set the JWT_VERIFICATION_KEY environment variable to the public key of the JWT verification key in the default case.If you want more control, you can use the AuthorizationConfig class:
from agno.os.config import AuthorizationConfig

agent_os = AgentOS(
    id="my-agent-os",
    agents=[agent],
    authorization=True,
    authorization_config=AuthorizationConfig(
      verification_keys=["your-jwt-verification-key"],
      algorithm="RS256",
  ),
)
You can also use a JWKS (JSON Web Key Set) file to verify JWTs instead of directly passing verification keys. To do this, provide the jwks_file parameter in the AuthorizationConfig:
from agno.os.config import AuthorizationConfig

agent_os = AgentOS(
    id="my-agent-os",
    agents=[agent],
    authorization=True,
    authorization_config=AuthorizationConfig(
        jwks_file="/path/to/jwks.json",
        algorithm="RS256",
    ),
)
or set the JWT_JWKS_FILE environment variable to point to a JWKS file.
export JWT_JWKS_FILE="/path/to/jwks.json"

Scope Format

RBAC uses a hierarchical scope format with three levels:

Global Resource Scopes

Format: resource:action Grants access to all resources of a type.
agents:read      # Read/list all agents
agents:run       # Run any agent
teams:read       # Read/list all teams
workflows:run    # Run any workflow
sessions:write   # Create/update any session

Per-Resource Scopes

Format: resource:<resource-id>:action Grants access to a specific resource.
agents:my-agent:read      # Read specific agent
agents:web-search:run     # Run specific agent
teams:research-team:run   # Run specific team
workflows:etl-pipeline:run # Run specific workflow

Wildcard Scopes

Format: resource:*:action Grants access to any resource of a type (equivalent to global).
agents:*:read     # Read any agent
teams:*:run       # Run any team

Admin Scope

The agent_os:admin scope grants full access to all endpoints.
agent_os:admin    # Full admin access

Complete Scope Reference

All available scopes for AgentOS RBAC. Scopes follow the format resource:action for global access or resource:<id>:action for per-resource access.

Admin Scopes

ScopeDescription
agent_os:adminFull admin access - grants access to all endpoints

System Scopes

ScopeDescription
system:readView system configuration and available models (GET /config, GET /models)

Agent Scopes

ScopeDescription
agents:readList and view all agents
agents:writeCreate and update agents
agents:deleteDelete agents
agents:runRun any agent
agents:<agent-id>:readView a specific agent
agents:<agent-id>:runRun a specific agent
agents:*:readView any agent (wildcard)
agents:*:runRun any agent (wildcard)

Team Scopes

ScopeDescription
teams:readList and view all teams
teams:writeCreate and update teams
teams:deleteDelete teams
teams:runRun any team
teams:<team-id>:readView a specific team
teams:<team-id>:runRun a specific team
teams:*:readView any team (wildcard)
teams:*:runRun any team (wildcard)

Workflow Scopes

ScopeDescription
workflows:readList and view all workflows
workflows:writeCreate and update workflows
workflows:deleteDelete workflows
workflows:runRun any workflow
workflows:<workflow-id>:readView a specific workflow
workflows:<workflow-id>:runRun a specific workflow
workflows:*:readView any workflow (wildcard)
workflows:*:runRun any workflow (wildcard)

Session Scopes

ScopeDescription
sessions:readView all sessions and session data
sessions:writeCreate, update, and rename sessions
sessions:deleteDelete sessions

Memory Scopes

ScopeDescription
memories:readView memories, memory topics, and user memory stats
memories:writeCreate, update, and optimize memories
memories:deleteDelete memories

Knowledge Scopes

ScopeDescription
knowledge:readView knowledge content, config, and search knowledge
knowledge:writeAdd and update knowledge content
knowledge:deleteDelete knowledge content

Metrics Scopes

ScopeDescription
metrics:readView metrics
metrics:writeRefresh metrics

Evaluation Scopes

ScopeDescription
evals:readView evaluation runs
evals:writeCreate and update evaluation runs
evals:deleteDelete evaluation runs

Default Scope Mappings

AgentOS automatically maps endpoints to required scopes. Here are all default mappings:
EndpointRequired Scope
GET /configsystem:read
GET /modelssystem:read

Custom Scope Mappings

You can customize or extend the default scope mappings using the JWT middleware directly:
custom_scopes.py
from agno.os import AgentOS
from agno.os.middleware import JWTMiddleware

agent_os = AgentOS(
    id="my-agent-os",
    agents=[my_agent],
    # Don't use built-in authorization - we'll configure JWT middleware manually
)

app = agent_os.get_app()

# Add JWT middleware with custom scope mappings
app.add_middleware(
    JWTMiddleware,
    verification_keys=["your-jwt-key"],
    algorithm="RS256",
    authorization=True,  # Enable RBAC
    scope_mappings={
        # Override default scope for this endpoint
        "GET /agents": ["custom:read"],
        # Add scope for custom endpoint
        "POST /custom/endpoint": ["custom:write"],
        # Allow access without scopes (empty list)
        "GET /public/stats": [],
    }
)
Custom scope mappings are additive to the default mappings. To override a default mapping, specify the same route pattern with your custom scopes.

JWT Token Structure

When using RBAC, your JWT tokens should include:
{
  "sub": "user-123",
  "scopes": ["agents:read", "agents:my-agent:run"],
  "exp": 1735689600,
  "iat": 1735603200
}

Required Claims

ClaimDescription
scopesArray of permission scopes

Optional Claims

ClaimDescription
subUser ID (extracted as user_id)
session_idSession ID for session tracking
audAudience - must match AgentOS id (when verify_audience=True)

Examples

Grant Read-Only Access

{
  "scopes": ["agents:read", "teams:read", "sessions:read"]
}

Grant Run and Read Access to Specific Agent

{
  "scopes": ["agents:my-agent:run", "agents:my-agent:read", "sessions:write"]
}

Grant Full Access to All Agents

{
  "scopes": ["agents:read", "agents:run", "sessions:read", "sessions:write"]
}

Admin Access

{
  "scopes": ["agent_os:admin"]
}

Excluded Routes

The following routes are excluded from RBAC checks by default:
  • / (home)
  • /health
  • /docs
  • /redoc
  • /openapi.json
  • /docs/oauth2-redirect

Error Responses

Status CodeDescription
401 UnauthorizedMissing or invalid JWT token
401 UnauthorizedInvalid audience (token not for this AgentOS)
403 ForbiddenInsufficient scopes for the requested operation

Examples

Developer Resources