AuthMiddleware is the AgentOS authentication middleware. It handles JWTs, service account tokens (agno_pat_...), the internal service token, and the OS security key, with optional RBAC (Role-Based Access Control) for JWTs. JWTMiddleware still works as an alias for the manual app.add_middleware(JWTMiddleware, ...) setup path.
Import
from agno.os.middleware.jwt import AuthMiddleware
from agno.os.middleware import JWTMiddleware # alias of AuthMiddleware
from agno.os.middleware.jwt import TokenSource
AuthMiddleware Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
app | - | Required | The FastAPI app instance. Supplied automatically by app.add_middleware |
verification_keys | Optional[List[str]] | None | Explicit JWT verification keys. If JWT_VERIFICATION_KEY is set, its value is appended even when this list is supplied. Unset the environment variable to stop trusting that key. Each key is tried in order. |
jwks_file | Optional[str] | JWT_JWKS_FILE env var | Path to a static JWKS (JSON Web Key Set) file. Keys are looked up by kid (key ID) from the JWT header. |
algorithm | str | "RS256" | JWT algorithm (RS256, HS256, ES256, etc.) |
validate | bool | True | Verify token signatures and reject invalid or expired tokens. False disables signature verification and is limited to development or deployments with a trusted upstream validator. |
authorization | Optional[bool] | None | Enable RBAC scope checking. If left None and scope_mappings is provided, RBAC is auto-enabled. |
token_source | TokenSource | TokenSource.HEADER | Where to extract JWT token from |
token_header_key | str | "Authorization" | Header key for Authorization |
cookie_name | str | "access_token" | Cookie name for JWT token |
scopes_claim | str | "scopes" | JWT claim name for scopes |
user_id_claim | str | "sub" | JWT claim name for user ID |
session_id_claim | str | "session_id" | JWT claim name for session ID |
audience_claim | str | "aud" | JWT claim name for audience/OS ID |
audience | Optional[Union[str, Iterable[str]]] | None | Expected audience(s) to validate the token’s aud claim against. Accepts a string or a list of strings; the token matches if its audience matches any of them. Defaults to the AgentOS ID. |
verify_audience | bool | False | Verify aud claim matches AgentOS ID |
dependencies_claims | Optional[List[str]] | None | Claims to extract for dependencies parameter |
session_state_claims | Optional[List[str]] | None | Claims to extract for session_state parameter |
scope_mappings | Optional[Dict[str, List[str]]] | None | Custom route-to-scope mappings (additive to defaults) |
excluded_route_paths | Optional[List[str]] | See below | Routes that bypass all AuthMiddleware authentication, authorization, and request-state population. |
admin_scope | Optional[str] | None | Scope that grants full admin access. Defaults to "agent_os:admin" when unset |
user_isolation | bool | False | Opt-in per-user isolation for user-owned data and resources throughout AgentOS. When True, non-admin callers can only access data and resources associated with their JWT sub claim. |
service_account_verifier | Optional[ServiceAccountVerifier] | None | Verifier for service account tokens (agno_pat_...). When set, bearer tokens with the agno_pat_ prefix authenticate as service accounts: user_id is the account principal (sa:<name>) and scopes are the account’s stored scopes, enforced against scope mappings even when authorization is disabled. |
security_key | Optional[str] | None | Static OS security key. When no JWT source is configured, bearer tokens are compared against this key and matching requests are authenticated. |
TokenSource Enum
| Value | Description |
|---|---|
TokenSource.HEADER | Extract JWT from Authorization: Bearer <token> header |
TokenSource.COOKIE | Extract JWT from HTTP cookie |
TokenSource.BOTH | Try header first, then cookie as fallback |
Default Excluded Routes
[
"/",
"/health",
"/info",
"/docs",
"/redoc",
"/openapi.json",
"/docs/oauth2-redirect",
]
Usage
Basic JWT Validation
from agno.os import AgentOS
from agno.os.middleware import JWTMiddleware
agent_os = AgentOS(agents=[my_agent])
app = agent_os.get_app()
app.add_middleware(
JWTMiddleware,
verification_keys=["your-jwt-key"],
algorithm="RS256",
validate=True,
)
JWT with RBAC Authorization
app.add_middleware(
JWTMiddleware,
verification_keys=["your-jwt-key"],
algorithm="RS256",
authorization=True,
verify_audience=True,
)
JWT from Cookies
from agno.os.middleware.jwt import TokenSource
app.add_middleware(
JWTMiddleware,
verification_keys=["your-jwt-key"],
token_source=TokenSource.COOKIE,
cookie_name="access_token",
)
Parameter Injection
app.add_middleware(
JWTMiddleware,
verification_keys=["your-jwt-key"],
user_id_claim="sub",
session_id_claim="session_id",
dependencies_claims=["name", "email", "roles"],
session_state_claims=["preferences"],
)
Using JWKS File
# Using a static JWKS file (e.g., from your identity provider)
app.add_middleware(
JWTMiddleware,
jwks_file="/path/to/jwks.json",
algorithm="RS256",
authorization=True,
)
{
"keys": [
{
"kty": "RSA",
"kid": "my-key-id",
"use": "sig",
"alg": "RS256",
"n": "0vx7agoebGc...",
"e": "AQAB"
}
]
}
Custom Scope Mappings
app.add_middleware(
JWTMiddleware,
verification_keys=["your-jwt-key"],
authorization=True,
scope_mappings={
# Override default scope
"GET /agents": ["custom:agents:list"],
# Add new endpoint
"POST /custom/action": ["custom:write"],
# Allow without scopes
"GET /public": [],
}
)
Request State
State fields depend on the authentication path. Excluded routes andOPTIONS requests return before authentication and do not receive these fields.
| Authentication path | Populated fields |
|---|---|
| JWT | authenticated, user_id, session_id, scopes, claims, audience, token, and authorization_enabled. dependencies, session_state, and accessible_resource_ids are added only when configured or applicable. Factories read JWT claims as ctx.trusted.claims. |
Service account token (agno_pat_...) | authenticated, user_id, session_id, scopes, authorization_enabled, service_account_name, and authorization metadata. Service account requests do not include claims or token. |
| Internal scheduler token | authenticated, user_id, session_id, scopes, authorization_enabled, and scheduler authorization metadata. |
| Security key | authenticated only. |
Error Responses
| Status Code | Description |
|---|---|
401 Unauthorized | Missing or invalid JWT token |
401 Unauthorized | Token has expired |
401 Unauthorized | Invalid audience (token not for this AgentOS) |
403 Forbidden | Insufficient scopes for the requested operation |
429 Too Many Requests | Service account verification is rate limited |
503 Service Unavailable | Service account verification is unavailable |
See Also
- Security Overview - AgentOS security overview
- JWT Middleware Guide - Configuration guide
- Scopes - Complete scope reference
- AuthorizationConfig - Authorization configuration