FastAPI dependency adapter for Lyhna execution authority
Project description
lyhna-gate
FastAPI dependency adapter for Lyhna's bind() authority boundary. Every protected
route goes through Lyhna's enforcement core before your handler runs. Approved
requests continue with the receipt available in the handler; refused and escalated
requests are blocked with a structured response envelope.
No receipt, no execution.
Install
pip install lyhna-gate
Authentication
Set your API key as an environment variable:
export LYHNA_API_KEY=lyhna_...
The adapter reads LYHNA_API_KEY from the environment via the underlying lyhna
SDK. There is no api_key parameter on the adapter itself.
If you need to target a non-default endpoint (staging, self-hosted), set
LYHNA_ENDPOINT before starting your application — the lyhna SDK resolves it
automatically. The adapter exposes no base_url parameter.
Usage
from fastapi import Depends, FastAPI, Request
from lyhna_gate import lyhna_gate
app = FastAPI()
async def payload_from_request(request: Request):
return await request.json()
@app.post("/deploy")
async def deploy(
receipt=Depends(lyhna_gate(
action_type="deploy_service",
intent="release_v3",
intent_version="1.0",
payload_from=payload_from_request,
))
):
# Only reached when Lyhna returns APPROVED
return {"ok": True, "receipt_id": receipt.receipt_id}
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
action_type |
str |
Yes | Canonical action identifier registered with Lyhna |
intent |
str |
Yes | Intent name for this bind call |
intent_version |
str |
Yes | Intent version string (e.g. "1.0") |
payload_from |
callable |
Yes | Sync or async function that extracts the action payload from the request |
attach_to_state |
str |
No | Attribute name on request.state where the receipt is stored. Defaults to "lyhna_receipt" |
The adapter does not accept api_key, base_url, authority_tier, tier, or
fail_open. Authority tier is determined server-side by your tenant's
authority_rules — callers cannot self-classify.
Bind contract
payload_from receives a FastAPI Request and must return a JSON-serializable
dict describing what will happen. The adapter calls lyhna.bind() with exactly
these four fields:
| Field | Source |
|---|---|
action_type |
factory config |
action_payload |
return value of payload_from(request) |
intent |
factory config |
intent_version |
factory config |
Response behavior
APPROVED — route handler runs; request.state.lyhna_receipt holds the full
Receipt object. The receipt is also returned directly from the dependency.
REFUSED (403):
{
"detail": {
"execution": "blocked",
"outcome": "REFUSED",
"reason": "...",
"receipt": { "..." }
}
}
ESCALATED (202):
{
"detail": {
"execution": "blocked_pending_authority",
"outcome": "ESCALATED",
"reason": "...",
"escalate_to": "human_governor",
"receipt": { "..." }
}
}
Binding error (503) — auth failure, timeout, or transport error:
{
"detail": {
"execution": "blocked_binding_unavailable",
"outcome": "REFUSED",
"reason": "Lyhna authentication failed",
"receipt": null
}
}
The adapter fails closed on every error. There is no fail-open path.
Accessing the receipt in the handler
Two equivalent access paths on APPROVED:
@app.post("/action")
async def handler(request: Request, receipt=Depends(gate)):
# Via dependency return value:
print(receipt.receipt_id)
# Via request.state (useful in middleware or downstream dependencies):
print(request.state.lyhna_receipt.receipt_id)
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lyhna_gate-0.1.0.tar.gz.
File metadata
- Download URL: lyhna_gate-0.1.0.tar.gz
- Upload date:
- Size: 7.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddca8bc0f8b3fdbb7b76f3e4a1badd9d614395c0dd9df2e2f562b722c607b5ed
|
|
| MD5 |
775fa70d74b0a5f79b9aaa07950c758f
|
|
| BLAKE2b-256 |
8dd0ec24ab6ff32efc1d2cd26df699c600d0698657a9ce9432febe1dbd9d8eb7
|
File details
Details for the file lyhna_gate-0.1.0-py3-none-any.whl.
File metadata
- Download URL: lyhna_gate-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4de5158438ca8dba531ea077a626eabd14ee41c3900a919e0b2588d57ccae30b
|
|
| MD5 |
bd342f980544d6e03bc5adae9ca0f13b
|
|
| BLAKE2b-256 |
7962b89bc67f120f3c0f4cedbd28666465d37a171897202c2a48a7ec601ab785
|