ASGI Connector
The ASGI connector 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 MCP Auth Transport.
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://billing-api", revocations=InMemoryRevocationStore(), required_scopes=["billing:read"], routes={ "/payouts": {"required_scopes": ["billing: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 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_agent / require_delegation / max_hop_count | Agent 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). |
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 connector verifies inbound mandates; it does not create agent sessions or delegation edges. Use the Python SDK to create Caracal context before making outbound calls.

