Metadata-Version: 2.4
Name: sonnet-auth
Version: 0.3.1
Summary: JWT/JWKS authentication and Cedar authorization for sonnet-server applications
Author-email: Wolfgang Miller <wolfgang.miller@petrarca-labs.com>
License-Expression: Apache-2.0
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <4.0,>=3.14
Description-Content-Type: text/markdown
Requires-Dist: sonnet-server>=0.4.0
Requires-Dist: sonnet-core>=0.1.0
Requires-Dist: joserfc>=1.7.3
Requires-Dist: httpx2>=2.7.0
Provides-Extra: cedar
Requires-Dist: cedarpy>=4.0.0; extra == "cedar"
Provides-Extra: dev
Requires-Dist: sonnet-auth[cedar]; extra == "dev"
Requires-Dist: ruff>=0.3.0; extra == "dev"
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: testcontainers[keycloak]>=4.0; extra == "dev"

# sonnet-auth

JWT/JWKS authentication and Cedar authorization for sonnet-server
applications. Two independent layers: authentication answers *who is calling*,
authorization answers *may they do this*. You can adopt either without the
other.

Version 0.3.0.

## What it provides

- **JWT/JWKS validation** -- `JwtCredentialValidator` fills sonnet-server's
  credential-validator slot. RS256/ES256, TTL-based key refresh, graceful
  degradation when the identity provider is unreachable.
- **Ambient identity** -- middleware that publishes the caller for the whole
  request path, so services never take an auth argument.
- **Claim mapping** -- configurable dot-path extraction from JWT claims onto
  the auth context and Cedar principal attributes, with an automatic mode for
  non-plumbing claims.
- **Cedar policy evaluation** (`cedar` extra) -- `PolicyEngine` over cedarpy,
  with `check_authz()` and `filter_authz()` as one-line gates for handlers and
  list operations.
- **Pluggable resolvers** -- slots for domain-specific Cedar resource
  attributes and principal enrichment.
- **Token issuance** -- `TokenIssuer` for services that mint their own tokens
  rather than only validating someone else's.
- **Extensions** -- `AuthnExtension` and `AuthzExtension` do the wiring:
  settings resolution, validator installation, policy loading, DI registration.

There is no user store, no login endpoint and no role model. Those are facts
about your application.

## Install

```bash
uv add sonnet-auth              # authentication only
uv add "sonnet-auth[cedar]"     # authentication + Cedar authorization
```

| Extra | Adds | Use when |
|---|---|---|
| `cedar` | `cedarpy` | Evaluating policies, registering `AuthzExtension`, or mounting `whoami_router`. |

`cedar` is the only non-development extra; it carries a compiled Rust engine, so
a verify-only service should not pay for it. The Cedar names are resolved
lazily, so `import sonnet_auth` never imports `cedarpy`.

Requires Python 3.14+ and `sonnet-server>=0.4.0`. The JWKS fetch uses
`httpx2`, not `httpx`.

## Usage

Register the extensions in your app factory; order matters, because
authorization reads the settings authentication resolved.

```python
from sonnet_auth import AuthnExtension, AuthzExtension

registry = create_extension_registry(
    DatabaseExtension(),
    AuthnExtension(env_prefix="EXAMPLE_", seed_fn=load_auth_seed),
    AuthzExtension(loader=load_policies, on_engine_ready=register_resolver),
    RestExtension(),
)
```

Configuration then comes from `EXAMPLE_AUTHN_*` and `EXAMPLE_AUTHZ_*`
environment variables, optionally seeded from the database. Gating a handler is
one call:

```python
from sonnet_auth import check_authz

check_authz("search", "Source", source_name)
```

The usage guides cover authentication, authorization, writing Cedar policies,
issuing tokens and MCP wiring.

## Documentation

- **Usage** -- [`docs/usage/index.md`](docs/usage/index.md)
- **Design** -- [`docs/design/index.md`](docs/design/index.md)
- **Workspace** -- [`../../docs/README.md`](../../docs/README.md)

## License

Apache 2.0 -- see [LICENSE.md](../../LICENSE.md).
