Cryptographic intent verification for FastAPI.
Drop this middleware into your FastAPI app. Verified agents get 100x the rate limit of anonymous traffic — enforced cryptographically, not by guesswork.
What it does · Quickstart · Policy config · How it works · Contributing
Every incoming request goes through three stages:
Incoming request
│
▼
┌─────────────────────┐
│ 1. Verify │ Extract X-Supelock-Actor + X-Supelock-Intent headers
│ │ Fetch public key from Registry
│ │ Verify Ed25519 signature
│ │ Check expiry, replay, method+path binding
│ │ → trust_level = "high" or "low"
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 2. Policy │ Load supelock.yaml
│ │ Check trust gate, path rules, intent rules
│ │ Apply rate limit per actor
│ │ → allowed or blocked (403 / 429)
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 3. Your app │ Request reaches your route handler
│ │ request.state.supelock_trust = "high"
│ │ request.state.supelock_actor = "ci-bot-1"
│ │ request.state.supelock_payload = { intent, ... }
└─────────────────────┘
Requests without Supelock headers are not rejected — they get trust_level=low and the anonymous policy applies.
Requirements: Python 3.10+, a running Supelock-Registry instance
git clone https://github.com/Sagnikkroy/Supelock-Middleware
cd Supelock-Middleware
pip install fastapi uvicorn pynacl pyyaml httpxAdd the middleware to your FastAPI app:
from fastapi import FastAPI
from supelock_middleware.middleware import SupelockMiddleware
app = FastAPI()
app.add_middleware(SupelockMiddleware)
@app.get("/api/data")
async def get_data(request: Request):
trust = request.state.supelock_trust # "high" or "low"
actor = request.state.supelock_actor # "ci-bot-1" or None
return {"trust": trust, "actor": actor}Drop a supelock.yaml in your project root and start the server:
uvicorn app:app --port 8000Create supelock.yaml in your project root:
default_policy: anonymous
policies:
verified_agent:
rate_limit: "1000/minute"
allowed_intents:
- "read_data"
- "create_order"
allowed_paths:
- "*"
trust_required: high
anonymous:
rate_limit: "10/minute"
allowed_intents:
- "*"
allowed_paths:
- "*"
trust_required: low
actors:
"ci-bot-1": verified_agent
"data-pipeline": verified_agentThat's it. ci-bot-1 with a valid Supelock token gets 1000 req/min. Everyone else gets 10.
| Field | Description | Example |
|---|---|---|
rate_limit |
Requests allowed per window | "1000/minute", "50/second", "10000/hour" |
allowed_intents |
Declared actions permitted | ["read_data", "submit_form"] or ["*"] |
allowed_paths |
URL path patterns (glob) | ["/api/read/*", "/api/search/*"] or ["*"] |
trust_required |
Minimum trust level | high (must have valid signature) or low |
Every response includes Supelock diagnostic headers:
X-Supelock-Trust: high
X-Supelock-Policy: verified_agent
X-Supelock-RateLimit-Remaining: 997
X-Supelock-RateLimit-Reset: 1743120060
The middleware looks for two HTTP headers on every request:
X-Supelock-Actor— the agent's identity (e.g."ci-bot-1")X-Supelock-Intent— a base64-encoded Ed25519 signed payload
The signed payload contains:
{
"actor_id": "ci-bot-1",
"method": "POST",
"path": "/api/orders",
"intent": { "action": "create_order", "max_amount": 5000 },
"nonce": "abc123",
"iat": 1743120000,
"exp": 1743120300
}The middleware fetches the actor's public key from the Registry, verifies the signature, checks expiry, prevents replay, and validates that method + path match the actual request.
After verification, the policy engine runs. It resolves which policy applies to the actor, then checks in order: trust gate → path → intent → rate limit. First failure short-circuits and returns the appropriate error.
@app.post("/api/orders")
async def create_order(request: Request, body: OrderBody):
if request.state.supelock_trust == "high":
# Full access — verified agent
return await process_order(body)
else:
# Anonymous — apply extra validation or reject
raise HTTPException(403, "Verified agent required")| Variable | Default | Description |
|---|---|---|
SUPELOCK_REGISTRY_URL |
http://localhost:8001 |
URL of the Registry service |
SUPELOCK_POLICY_PATH |
supelock.yaml |
Path to your policy file |
Supelock-Middleware/
├── supelock_middleware/
│ ├── middleware.py # Main middleware — verify + policy
│ ├── verifier.py # Ed25519 signature verification
│ ├── policy.py # Policy engine (rate limits, intent, path)
│ ├── replay.py # Nonce-based replay protection
│ ├── registry.py # Legacy sync lookup (kept for compat)
│ ├── registry_client.py # Async HTTP client for Registry service
│ └── exceptions.py # Verification error types
├── supelock.yaml # Example policy config
└── tests/
└── test_policy.py # 21 tests, all passing
pip install pytest pyyaml
pytest tests/ -vExpected: 21 passed.
| Repo | Role | Status |
|---|---|---|
| Supelock-SDK | Agent identity + request signing | ✅ Built |
| Supelock-Registry | Public key storage | ✅ Built |
| Supelock-Middleware | Verification + policy enforcement | ✅ Built (this repo) |
| Supelock-Dashboard | Live request monitoring UI | 🚧 In progress |
Issues and PRs welcome.
Good first issues:
- Redis-backed rate limiter for distributed deployments
-
POST /supelock/reloadendpoint to hot-reload policy without restart - Django / Starlette / Express (Node) middleware ports
- Prometheus metrics — request counts by trust level and policy
- Webhook support — notify a URL when an actor is rate limited
- Policy validation CLI —
supelock check supelock.yaml
git clone https://github.com/Sagnikkroy/Supelock-Middleware
cd Supelock-Middleware
pip install fastapi uvicorn pynacl pyyaml httpx pytest
pytest tests/ -vMIT