Metadata-Version: 2.4
Name: csrd-auth
Version: 0.3.57
Summary: Pluggable JWT authentication — authenticators, key providers, and FastAPI dependency factories
Project-URL: Repository, https://github.com/csrd-api/fastapi-common
Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/auth
Project-URL: Changelog, https://github.com/csrd-api/fastapi-common/blob/main/CHANGELOG.md
License: MIT
Requires-Python: >=3.12
Requires-Dist: csrd-context
Requires-Dist: csrd-models
Requires-Dist: fastapi<1,>=0.115
Requires-Dist: pydantic<3,>=2
Requires-Dist: pyjwt<3,>=2
Description-Content-Type: text/markdown

# csrd-auth

Pluggable JWT authentication for FastAPI — authenticators, key providers, and dependency factories.

**Tier 2 (bridge)** — depends on `csrd-models` and `csrd-context` only.

## Installation

```bash
pip install "csrd-auth @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/auth"
```

## Usage

```python
from csrd.auth import (
    JWTAuthenticator,
    StaticKeyProvider,
    create_bearer_dependency,
    create_jwt_bearer,
)
```

### Quick start — JWT bearer dependency

```python
# Standalone (provide your own token_finder)
from csrd.auth import create_jwt_bearer

auth_dep = create_jwt_bearer(
    key="your-secret",
    token_finder=lambda: extract_token_from_request(),
)
```

When used with `csrd.versioning`, wire in `find_token` explicitly:

```python
from csrd.auth import create_jwt_bearer
from csrd.versioning import find_token

auth_dep = create_jwt_bearer(key="your-secret", token_finder=find_token)
```

## Authenticators

| Class | Strategy |
|-------|----------|
| `JWTAuthenticator` | Decode & verify JWT locally via PyJWT |
| `StaticAuthenticator` | Accept a fixed token (dev/testing) |
| `RemoteAuthenticator` | Validate via upstream HTTP endpoint |
| `CallbackAuthenticator` | Delegate to any sync/async callable |
| `ChainedAuthenticator` | Try multiple authenticators in order |

## Key Providers

| Class | Strategy |
|-------|----------|
| `StaticKeyProvider` | Fixed string, bytes, or `SecretStr` |
| `EnvKeyProvider` | Read from `app.state` or settings loader |
| `JWKSKeyProvider` | Fetch from JWKS endpoint (cached with TTL) |
| `MultiKeyProvider` | Route by `kid` header or try all |
| `CallbackKeyProvider` | Delegate to any callable |

## Protocols

- `Authenticator` — `(Request, str) -> UserClaims`
- `KeyProvider` — `(token_headers, app) -> key`

Both are `@runtime_checkable` protocols.

## Dependency Tier

```
Tier 1      csrd.models  csrd.lifespan  csrd.context
Tier 2      csrd.auth  csrd.logging  csrd.delegate  csrd.repository  csrd.service
Tier 3      csrd.versioning
```

`csrd.auth` depends only on `csrd.models` (for `UserClaims`) and `csrd.context` (for `user_info_context`). It has **no dependency** on `csrd.versioning`.
