ASGI Adapter
The ASGI adapter protects any Python ASGI application - FastAPI, Starlette, Quart, Django ASGI - with fail-closed Caracal mandate verification. It is pure ASGI: it imports no web framework and delegates every check to Verify Package.
CaracalASGIAuth is the only public package entry point. Use it for inbound ASGI HTTP or WebSocket authentication, not outbound SDK calls.
Install
Section titled “Install”pip install caracalai-asgiAdd middleware
Section titled “Add middleware”from caracalai_asgi import CaracalASGIAuthfrom caracalai_revocation import InMemoryRevocationStorefrom fastapi import FastAPI
app = FastAPI()app.add_middleware( CaracalASGIAuth, audience="resource://pipernet", revocations=InMemoryRevocationStore(), required_scopes=["pipernet:read"], routes={ "/payouts": {"required_scopes": ["pipernet:payout"], "require_delegation": True}, }, exclude=["/healthz"],)
@app.get("/balances")async def balances(request): principal = request.state.caracal return {"sub": principal.sub, "scopes": principal.scope}issuer defaults to CARACAL_STS_URL and expected_zone_id to CARACAL_ZONE_ID, so a provider deployed with the standard Caracal workload variables only states its own audience and revocation store. Construction fails if no issuer or zone can be resolved.
Options
Section titled “Options”| Option | Use it for |
|---|---|
audience | The provider’s own resource identifier; mandates minted for other resources are rejected. |
revocations | Revocation store consulted on every request. Use Redis Revocation Store in production. |
required_scopes / required_targets | Default scope and target requirements for every route. |
require_session / require_delegation / max_hop_count | Session identity, delegated authority, and Delegation-depth requirements. |
routes | Per-route overrides by path prefix; the longest matching prefix wins. Any option above can be overridden. |
exclude | Path prefixes served without verification (health and readiness probes). |
required_use defaults to resource; require_session and require_delegation default to false. Exclusions and route prefixes match path-segment boundaries, and the longest route prefix wins.
Behavior
Section titled “Behavior”- Verified claims are stored as
scope["state"]["caracal"], surfaced asrequest.state.caracalin Starlette and FastAPI. - Failed verification answers with the shared status mapping (
http_status_for_auth_error): 401 for credential failures, 403 for insufficient authority, with the standarderror/error_descriptionJSON body. - WebSocket connections that fail verification are closed with policy code
1008; lifespan events pass through. - Call
await middleware.warmup()at startup to prefetch the zone JWKS before the first request.
Boundary
Section titled “Boundary”The adapter verifies inbound mandates; it does not create Sessions or Delegations. Use the Python SDK to create Caracal context before making outbound calls.

