basic.py
"""
Basic RBAC Example with AgentOS
This example demonstrates how to enable RBAC (Role-Based Access Control)
with JWT token authentication in AgentOS using middleware.
Prerequisites:
- Set JWT_VERIFICATION_KEY environment variable or pass it to middleware
- Endpoints are automatically protected with default scope mappings
"""
import os
from datetime import UTC, datetime, timedelta
import jwt
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.config import AuthorizationConfig
from agno.tools.websearch import WebSearchTools
# ---------------------------------------------------------------------------
# Create Example
# ---------------------------------------------------------------------------
# JWT Secret (use environment variable in production)
JWT_SECRET = os.getenv("JWT_VERIFICATION_KEY", "your-secret-key-at-least-256-bits-long")
# Setup database
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
# Create agents
research_agent = Agent(
id="research-agent",
name="Research Agent",
model=OpenAIResponses(id="gpt-5.5"),
db=db,
tools=[WebSearchTools()],
add_history_to_context=True,
markdown=True,
)
# Create AgentOS
agent_os = AgentOS(
id="my-agent-os",
description="RBAC Protected AgentOS",
agents=[research_agent],
authorization=True,
authorization_config=AuthorizationConfig(
verification_keys=[JWT_SECRET],
algorithm="HS256",
),
)
# Get the app and add RBAC middleware
app = agent_os.get_app()
# ---------------------------------------------------------------------------
# Run Example
# ---------------------------------------------------------------------------
if __name__ == "__main__":
"""
Run your AgentOS with RBAC enabled.
Audience Verification:
- Tokens must include `aud` claim matching the AgentOS ID
- Tokens with wrong audience will be rejected
Default scope mappings protect all endpoints:
- GET /agents/{agent_id}: requires "agents:read"
- POST /agents/{agent_id}/runs: requires "agents:run"
- GET /sessions: requires "sessions:read"
- GET /memories: requires "memories:read"
- etc.
Scope format:
- "agents:read" - List all agents
- "agents:research-agent:run" - Run specific agent
- "agents:*:run" - Run any agent
- "agent_os:admin" - Full access to everything
Test with a JWT token that includes scopes:
"""
# Create test tokens with different scopes
# Note: Include `aud` claim with AgentOS ID
user_token_payload = {
"sub": "user_123",
"session_id": "session_456",
"scopes": ["agents:read", "agents:run"],
"exp": datetime.now(UTC) + timedelta(hours=24),
"iat": datetime.now(UTC),
}
user_token = jwt.encode(user_token_payload, JWT_SECRET, algorithm="HS256")
admin_token_payload = {
"sub": "admin_789",
"session_id": "admin_session_123",
"scopes": ["agent_os:admin"], # Admin has access to everything
"exp": datetime.now(UTC) + timedelta(hours=24),
"iat": datetime.now(UTC),
}
admin_token = jwt.encode(admin_token_payload, JWT_SECRET, algorithm="HS256")
print("\n" + "=" * 60)
print("RBAC Test Tokens")
print("=" * 60)
print("\nUser Token (agents:read, agents:run):")
print(user_token)
print("\nAdmin Token (agent_os:admin - full access):")
print(admin_token)
print("\n" + "=" * 60)
print("\nTest commands:")
print(
'\ncurl -H "Authorization: Bearer '
+ user_token
+ '" http://localhost:7777/agents'
)
print(
'\ncurl -H "Authorization: Bearer '
+ admin_token
+ '" http://localhost:7777/sessions'
)
print("\n" + "=" * 60 + "\n")
agent_os.serve(app="basic:app", port=7777, reload=True)
Run the Example
1
Set up your virtual environment
uv venv --python 3.12
source .venv/bin/activate
uv venv --python 3.12
.venv\Scripts\activate
2
Install dependencies
uv pip install -U "agno[os]" "psycopg[binary]" ddgs openai
3
Export your OpenAI API key
export OPENAI_API_KEY="your_openai_api_key_here"
$Env:OPENAI_API_KEY="your_openai_api_key_here"
4
Run PgVector
docker run -d \
-e POSTGRES_DB=ai \
-e POSTGRES_USER=ai \
-e POSTGRES_PASSWORD=ai \
-e PGDATA=/var/lib/postgresql \
-v pgvolume:/var/lib/postgresql \
-p 5532:5432 \
--name pgvector \
agnohq/pgvector:18
docker run -d `
-e POSTGRES_DB=ai `
-e POSTGRES_USER=ai `
-e POSTGRES_PASSWORD=ai `
-e PGDATA=/var/lib/postgresql `
-v pgvolume:/var/lib/postgresql `
-p 5532:5432 `
--name pgvector `
agnohq/pgvector:18
5
Run the example
Save the code above as
basic.py, then run:python basic.py