This example demonstrates how to use JWT middleware with AgentOS for authentication and automatic parameter injection using Authorization headers.

Code

jwt_middleware.py
from datetime import UTC, datetime, timedelta

import jwt
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.middleware import JWTMiddleware

# JWT Secret (use environment variable in production)
JWT_SECRET = "a-string-secret-at-least-256-bits-long"

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


# Define a tool that uses dependencies claims
def get_user_details(dependencies: dict):
    """
    Get the current user's details.
    """
    return {
        "name": dependencies.get("name"),
        "email": dependencies.get("email"),
        "roles": dependencies.get("roles"),
    }


# Create agent
research_agent = Agent(
    id="user-agent",
    model=OpenAIChat(id="gpt-5-mini"),
    db=db,
    tools=[get_user_details],
    instructions="You are a user agent that can get user details if the user asks for them.",
)


agent_os = AgentOS(
    description="JWT Protected AgentOS",
    agents=[research_agent],
)

# Get the final app
app = agent_os.get_app()

# Add JWT middleware to the app
# This middleware will automatically inject JWT values into request.state and is used in the relevant endpoints.
app.add_middleware(
    JWTMiddleware,
    secret_key=JWT_SECRET, # or use JWT_SECRET_KEY environment variable
    algorithm="HS256",
    user_id_claim="sub",  # Extract user_id from 'sub' claim
    session_id_claim="session_id",  # Extract session_id from 'session_id' claim
    dependencies_claims=["name", "email", "roles"],
    # In this example, we want this middleware to demonstrate parameter injection, not token validation.
    # In production scenarios, you will probably also want token validation. Be careful setting this to False.
    validate=False,
)

if __name__ == "__main__":
    """
    Run your AgentOS with JWT parameter injection.
    
    Test by calling /agents/user-agent/runs with a message: "What do you know about me?"
    """
    # Test token with user_id and session_id:
    payload = {
        "sub": "user_123",  # This will be injected as user_id parameter
        "session_id": "demo_session_456",  # This will be injected as session_id parameter
        "exp": datetime.now(UTC) + timedelta(hours=24),
        "iat": datetime.now(UTC),
        # Dependency claims
        "name": "John Doe",
        "email": "john.doe@example.com",
        "roles": ["admin", "user"],
    }
    token = jwt.encode(payload, JWT_SECRET, algorithm="HS256")
    print("Test token:")
    print(token)
    agent_os.serve(app="jwt_middleware:app", port=7777, reload=True)

Usage

1

Create a virtual environment

Open the Terminal and create a python virtual environment.
python3 -m venv .venv
source .venv/bin/activate
2

Set Environment Variables

export OPENAI_API_KEY=your_openai_api_key
3

Install libraries

pip install -U agno openai pyjwt fastapi["standard"] uvicorn sqlalchemy pgvector psycopg
4

Setup PostgreSQL Database

# Using Docker
docker run -d \
  --name agno-postgres \
  -e POSTGRES_DB=ai \
  -e POSTGRES_USER=ai \
  -e POSTGRES_PASSWORD=ai \
  -p 5532:5432 \
  pgvector/pgvector:pg17
5

Run Example

python jwt_middleware.py
The server will start and print a test JWT token to the console.
6

Test JWT Authentication

Test with the generated token:
# Use the token printed in the console
export TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

curl --location 'http://localhost:7777/agents/user-agent/runs' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --header 'Authorization: Bearer $TOKEN' \
    --data-urlencode 'message=What do you know about me?'
Test without token (should still work since validate=False):
curl --location 'http://localhost:7777/agents/user-agent/runs' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'message=What do you know about me?'
Check the AgentOS API docs: Visit http://localhost:7777/docs to see all available endpoints.

How It Works

  1. JWT Generation: The example creates a test JWT token with user claims
  2. Middleware Setup: JWT middleware extracts claims from the Authorization: Bearer <token> header
  3. Parameter Injection: The middleware automatically injects:
    • user_id from the sub claim
    • session_id from the session_id claim
    • dependencies dict with name, email, and roles
  4. Agent Tools: The agent can access user details through the injected dependencies

Next Steps