AuthMiddleware
Parameter reference for AuthMiddleware (aliased as JWTMiddleware), the AgentOS authentication and RBAC middleware.
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 TokenSourceConfigure at least one credential source: JWT verification keys/JWKS, a service-account verifier, or a security key. Enabling JWT RBAC (authorization=True, including automatic enablement through scope_mappings) requires a JWT source; a PAT verifier or security key alone is insufficient.
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 skips signature, expiry, and audience validation, producing unverified claims. Use only behind a trusted upstream validator or in isolated development. |
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 isolation for non-admin JWT callers, using user_id_claim (sub by default). Non-admin service accounts are always scoped to their own principal, regardless of this flag. Admins bypass this isolation. |
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
Install uv pip install 'agno[os]' openai pyjwt, export OPENAI_API_KEY, and set JWT_SIGNING_KEY to your HS256 issuer's secret. This example uses the same secret for verification. For a complete local token and request example, see middleware setup.
Save as jwt_server.py:
import os
from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.middleware import JWTMiddleware
verification_key = os.environ["JWT_SIGNING_KEY"]
agent_os = AgentOS(
id="jwt-reference",
agents=[Agent(id="assistant", model=OpenAIResponses(id="gpt-5.4"))],
)
app = agent_os.get_app()
app.add_middleware(
JWTMiddleware,
verification_keys=[verification_key],
algorithm="HS256",
validate=True,
)uv run uvicorn jwt_server:app --host 0.0.0.0 --port 7777The following are alternative middleware composition fragments. Replace the app.add_middleware(...) call above with one of them before starting the app; do not stack all the examples.
JWT with RBAC Authorization
app.add_middleware(
JWTMiddleware,
verification_keys=[verification_key],
algorithm="HS256",
authorization=True,
audience="jwt-reference",
verify_audience=True,
)JWT from Cookies
from agno.os.middleware.jwt import TokenSource
app.add_middleware(
JWTMiddleware,
verification_keys=[verification_key],
algorithm="HS256",
token_source=TokenSource.COOKIE,
cookie_name="access_token",
)Parameter Injection
app.add_middleware(
JWTMiddleware,
verification_keys=[verification_key],
algorithm="HS256",
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,
)Use a real issuer JWKS file. The following shows its shape only; the abbreviated modulus is not a usable key:
{
"keys": [
{
"kty": "RSA",
"kid": "my-key-id",
"use": "sig",
"alg": "RS256",
"n": "0vx7agoebGc...",
"e": "AQAB"
}
]
}Custom Scope Mappings
app.add_middleware(
JWTMiddleware,
verification_keys=[verification_key],
algorithm="HS256",
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 and OPTIONS 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 (when validation is enabled) |
401 Unauthorized | Invalid audience (when validation and audience verification are enabled) |
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