Metadata-Version: 2.4
Name: auth51-verifier
Version: 1.0.0
Summary: Resource-server enforcement library for auth51 Agentic JWT intent tokens — offline verification of signature, issuer, audience, scopes, Proof-of-Possession, and value binding.
License: Apache-2.0
License-File: LICENSE
Keywords: auth51,agentic-authorization,resource-server,jwt,ai-agents,fastapi
Author: ago
Author-email: ago@hypernome.com
Requires-Python: >=3.10
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Classifier: Framework :: FastAPI
Provides-Extra: dev
Requires-Dist: auth51-governance (>=0.1.4,<0.2.0)
Requires-Dist: cryptography (>=46.0.3,<47.0.0)
Requires-Dist: fastapi (>=0.128.0,<0.129.0)
Requires-Dist: httpx (>=0.28.1,<0.29.0)
Requires-Dist: pydantic (>=2.12.5,<3.0.0)
Requires-Dist: pydantic-settings (>=2.12.0,<3.0.0)
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
Requires-Dist: pytest (>=9.0.2,<10.0.0) ; extra == "dev"
Requires-Dist: pytest-asyncio (>=1.3.0,<2.0.0) ; extra == "dev"
Requires-Dist: pytest-cov (>=7.0.0,<8.0.0) ; extra == "dev"
Requires-Dist: uvicorn (>=0.40.0,<0.41.0)
Project-URL: Homepage, https://auth51.com
Project-URL: Repository, https://github.com/unforge-io/auth51-verifier
Description-Content-Type: text/markdown

# auth51-verifier

Resource-server (RS) enforcement library for [auth51](https://auth51.com) Agentic JWT
intent tokens. Mount it on your API and it authorizes each request **offline** —
"protect the resource, not the host."

It verifies, in one pass and without calling back to the Authority:

- **signature** against the Authority's published JWKS (fetched + cached),
- **issuer / expiry / audience / scopes**,
- **Proof-of-Possession** (DPoP `cnf.jkt`, with legacy RSA `cnf.jwk` fallback) — a
  stolen bearer token is useless without the sender's key,
- **value binding** — the token's frozen `vb` claim is re-checked against the real
  request (static invariants, the `action_hash`, and T2 reference bounds resolved at
  the resource through registered providers), using the same
  [`auth51-governance`](https://pypi.org/project/auth51-governance/) evaluator the
  Authority used at mint.

## Install

```bash
pip install auth51-verifier
```

`auth51-governance` (the value-binding evaluator) is pulled in automatically.

## Use

```python
from fastapi import Depends, FastAPI
from auth51_verifier import install_signature_middleware, require_auth

app = FastAPI()
install_signature_middleware(app)

@app.get("/data", dependencies=[Depends(require_auth("read:data", audience="api.example.com"))])
def read_data():
    return {"ok": True}
```

Configure it from the environment (no code wiring):

```bash
AUTHORITY_URL=https://authority.auth51.com
JWKS_PATH=/v1/oauth/.well-known/jwks.json
EXPECTED_ISS=https://authority.auth51.com
REQUIRE_POP=true
ENFORCE_VALUE_BINDING=true
```

### Value-binding reference providers (T2)

A reference bound such as `refund.amount <= charge.amount` freezes an **unresolved**
reference in the token; the resource resolves it against its own system of record at
request time. Register a provider so the verifier can look it up:

```python
from auth51_verifier.extraction import register_provider

# args are pulled from the real request; return the record the bound reads its field from
register_provider("charge_lookup", lambda args: load_charge(args["charge_id"]))
```

If no provider is registered for a reference bound, the request fails closed — the
verifier never assumes a bound it cannot check.

## License

Apache-2.0

