Self-Hosted (BYO Token)

Run AgentOS without the AgentOS control plane by issuing and verifying your own JWTs.

AgentOS verifies any JWT signed with a key you provide. The AgentOS control plane is one issuer; you can also issue your own tokens, or accept tokens from third-party identity providers.

Issuance Models

ModelTokens minted byVerification keyWhen to use
Control planeos.agno.comPublic key from the control planeDefault. Works with the AgentOS UI out of the box.
Self-hostedYour backend or identity providerThe key you sign withAir-gapped, on-prem, or full control over claims.

Issuing Your Own Tokens

Sign tokens in your backend with the matching verification key. Asymmetric algorithms (RS256, ES256) use a public key. Symmetric algorithms (HS256) use a shared secret. See Algorithm Options for the full list.

Tokens must include the claims from Token Structure. The scopes claim controls what the caller can do.

Configure AgentOS with the verification key:

from agno.os import AgentOS
from agno.os.config import AuthorizationConfig

agent_os = AgentOS(
    id="my-agent-os",
    agents=[agent],
    authorization=True,
    authorization_config=AuthorizationConfig(
        verification_keys=["your-public-key-or-shared-secret"],
        algorithm="RS256",  # or "HS256" for shared secret
    ),
)

Send the token in the Authorization header:

curl -H "Authorization: Bearer $TOKEN" http://localhost:7777/agents

See the Basic Authorization (Symmetric) and Basic Authorization (Asymmetric) examples for generating signed tokens end to end.

AgentOS can match the JWT's kid header against multiple keys in a local JWKS file. Keys are loaded when the validator is constructed; AgentOS does not poll a remote JWKS URL. On rotation, refresh the local file and restart the application or reconstruct its validator. See Configuration Options.

Third-Party Identity Providers

AgentOS can verify identity-provider JWTs with a supported signing algorithm and the provider's verification keys. Configure the key, algorithm, audience policy, and permission claim for your issuer:

  1. Download the provider's JWKS document to a local file.
  2. Set jwks_file to that path and algorithm to the token's signing algorithm.
  3. Set scopes_claim to the name of a claim containing an array of permission strings. Built-in resources require native Agno names such as agents:read and agents:my-agent:run. Custom REST mappings do not replace those handler checks or the native mappings used by built-in MCP tools.

AgentOS treats a space-delimited OAuth scope string as one scope. For Auth0, enable RBAC and Add Permissions in the Access Token, then select scopes_claim="permissions" and configure permissions using Agno's scope names.

If the provider gives you a raw public key (PEM) instead of a JWKS endpoint, use verification_keys=[pem] and skip jwks_file. Setting both is also valid: AgentOS tries JWKS keys first (matched by kid), then static verification keys.

Example: WorkOS

Download the JWKS file from your WorkOS environment:

curl https://api.workos.com/sso/jwks/$WORKOS_CLIENT_ID > workos-jwks.json

Point AgentOS at it. WorkOS tokens carry permissions under the permissions claim, so set scopes_claim="permissions" on the JWT middleware:

from agno.os import AgentOS
from agno.os.middleware.jwt import JWTMiddleware

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

app = agent_os.get_app()

app.add_middleware(
    JWTMiddleware,
    jwks_file="workos-jwks.json",
    algorithm="RS256",
    scopes_claim="permissions",
    authorization=True,
)

WorkOS organization sessions carry the organization's role and permissions. Configure those permissions using native Agno scope names, such as agents:read. Reserve custom scope mappings for your own routes.

Why this example uses JWTMiddleware instead of AuthorizationConfig. AuthorizationConfig covers verification keys, algorithm, audience, and isolation, but not claim names or token sources. Use it when the provider's JWT uses the standard scopes and sub claims. For providers that use a different claim name (WorkOS and Auth0 permissions, Okta scp), or when you need cookie tokens or custom scope mappings, use JWTMiddleware directly.

See WorkOS BYOT for a runnable example.

Accepting Multiple Issuers

verification_keys is a list. AgentOS tries each key in order until one verifies the token. Pass a second key to accept tokens from both the AgentOS control plane and your own backend at the same time.

authorization_config=AuthorizationConfig(
    verification_keys=[
        AGENTOS_CONTROL_PLANE_PUBLIC_KEY,  # tokens issued by os.agno.com
        YOUR_BACKEND_PUBLIC_KEY,        # tokens minted by your service
    ],
    algorithm="RS256",
)

This keeps the AgentOS UI working through the control plane while your backend mints its own tokens for service-to-service or production traffic. All keys in the list must use the algorithm set in algorithm.

For a mix of JWKS-based and raw-key issuers (e.g., a third-party IDP plus the AgentOS control plane), set both jwks_file and verification_keys. AgentOS tries JWKS keys first (matched by kid), then static verification keys as a fallback.

Order matters for performance, not correctness. AgentOS tries each key in order and stops at the first match. Put the most common issuer first to skip an extra decode attempt per request.

Reading Tokens from Cookies

By default, AgentOS reads the JWT from the Authorization: Bearer header. For browser apps that hit AgentOS directly, use the JWT middleware to read from a cookie, or both.

Use this as the single manual JWT middleware configuration, replacing the earlier manual setup. Stacking it behind a header-only JWT layer would still reject cookie-only requests.

from agno.os.middleware.jwt import JWTMiddleware, TokenSource

app = agent_os.get_app()

app.add_middleware(
    JWTMiddleware,
    verification_keys=["your-public-key"],
    algorithm="RS256",
    token_source=TokenSource.BOTH,   # HEADER | COOKIE | BOTH
    cookie_name="access_token",
    authorization=True,
)

See JWT Middleware for the full set of token-source options.

Next Steps

TaskGuide
See claim structure and example tokensTokens
See the full scope referenceScopes
Configure JWT middleware in depthJWT Middleware