---
title: "ASGI Connector"
url: "https://docs.caracal.run/sdks/connectors/asgi/"
markdown_url: "https://docs.caracal.run/markdown/sdks/connectors/asgi.md"
description: "Pure ASGI middleware that verifies Caracal mandates for FastAPI, Starlette, and Quart resource servers."
page_type: "page"
concepts: []
requires: []
---

# ASGI Connector

Canonical URL: https://docs.caracal.run/sdks/connectors/asgi/
Markdown URL: https://docs.caracal.run/markdown/sdks/connectors/asgi.md
Description: Pure ASGI middleware that verifies Caracal mandates for FastAPI, Starlette, and Quart resource servers.
Page type: page
Concepts: none
Requires: none

---

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](/sdks/transport-mcp/).

## Install

```bash
pip install caracalai-asgi
```

## Add middleware

```python
from caracalai_asgi import CaracalASGIAuth
from caracalai_revocation import InMemoryRevocationStore
from 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

| 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](/sdks/connectors/redis/) 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

- Verified claims are stored as `scope["state"]["caracal"]`, surfaced as `request.state.caracal` in 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 standard `error`/`error_description` JSON 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

The connector verifies inbound mandates; it does not create agent sessions or delegation edges. Use the [Python SDK](/sdks/python/) to create Caracal context before making outbound calls.

## Related pages

- [Protect a FastAPI App](/guides/protect-fastapi/)
- [MCP Auth Transport](/sdks/transport-mcp/)
- [Sessions and Revocation](/concepts/sessions-revocation/)
