Metadata-Version: 2.4
Name: pico-server-auth
Version: 0.1.2
Summary: Embeddable auth server module for the pico ecosystem — JWT issuance, wallet login, JWKS endpoint
Author-email: David Perez Cabrera <dperezcabrera@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/dperezcabrera/pico-server-auth
Project-URL: Documentation, https://dperezcabrera.github.io/pico-server-auth/
Project-URL: Repository, https://github.com/dperezcabrera/pico-server-auth
Project-URL: Changelog, https://github.com/dperezcabrera/pico-server-auth/blob/main/CHANGELOG.md
Project-URL: Issue Tracker, https://github.com/dperezcabrera/pico-server-auth/issues
Keywords: auth,jwt,wallet,challenge-response,jwks,ml-dsa-65,ed25519,secp256k1,post-quantum,pico-ioc,pico-boot,dependency-injection
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pico-ioc[yaml]>=2.2.0
Requires-Dist: pico-boot>=0.1.0
Requires-Dist: pico-fastapi>=0.1.0
Requires-Dist: pico-client-auth>=0.2.0
Requires-Dist: python-jose[cryptography]>=3.3.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: ruff>=0.9.0; extra == "dev"
Requires-Dist: httpx; extra == "dev"
Dynamic: license-file

# pico-server-auth

[![PyPI](https://img.shields.io/pypi/v/pico-server-auth.svg)](https://pypi.org/project/pico-server-auth/)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/dperezcabrera/pico-server-auth)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
![CI](https://github.com/dperezcabrera/pico-server-auth/actions/workflows/ci.yml/badge.svg)
[![codecov](https://codecov.io/gh/dperezcabrera/pico-server-auth/branch/main/graph/badge.svg)](https://codecov.io/gh/dperezcabrera/pico-server-auth)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=dperezcabrera_pico-server-auth&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=dperezcabrera_pico-server-auth)
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=dperezcabrera_pico-server-auth&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=dperezcabrera_pico-server-auth)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=dperezcabrera_pico-server-auth&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=dperezcabrera_pico-server-auth)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/pico-server-auth?period=monthly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=Monthly+downloads)](https://pepy.tech/projects/pico-server-auth)
[![Docs](https://img.shields.io/badge/Docs-pico--server--auth-blue?style=flat&logo=readthedocs&logoColor=white)](https://dperezcabrera.github.io/pico-server-auth/)
[![Interactive Lab](https://img.shields.io/badge/Learn-online-green?style=flat&logo=python&logoColor=white)](https://dperezcabrera.github.io/pico-learn/)

Embeddable auth server module for the [pico-boot](https://github.com/dperezcabrera/pico-boot) ecosystem.

Issues JWT tokens, handles wallet challenge-response login, and exposes JWKS — all compatible with [pico-client-auth](https://github.com/dperezcabrera/pico-client-auth) validation.

## Two deployment modes

**Embedded** — add to any [pico-boot](https://github.com/dperezcabrera/pico-boot) app, auth runs in the same process. Auto-discovered — no need to list it in `modules=[]`:

```python
container = init(modules=["myapp"], config=config)
# pico-server-auth endpoints are available automatically
```

**Standalone** — deploy as a separate auth service:

```python
container = init(modules=[], config=config)
app = container.get(FastAPI)
# Other services point pico-client-auth to this service's /api/v1/auth/jwks
```

Scaffold a new project with [pico-initializer](https://dperezcabrera.github.io/pico-initializer/) — select **pico-server-auth** in the modules list.

## Endpoints

```
GET  /api/v1/auth/jwks            JWKS public keys (pico-client-auth fetches this)
POST /api/v1/auth/challenge       Request nonce for wallet login
POST /api/v1/auth/sign-in         Verify wallet signature, issue JWT
POST /api/v1/auth/login           Password login (admin bootstrap)
POST /api/v1/auth/fleet/sessions  Mint a fleet session token (X-Fleet-Secret gated)   [v0.1.2]
POST /api/v1/auth/revoke          Revoke a token by jti (operator-gated)               [v0.1.2]
GET  /api/v1/auth/revoked-jtis    jti denylist (polled by pico-client-auth)            [v0.1.2]
GET  /api/v1/auth/mints           Currently-valid long-lived tokens (audit view)       [v0.1.2]
```

## Wallet login flow

```
Client                    pico-server-auth
  │                            │
  │ POST /api/v1/auth/challenge       │
  │ { address: "0x..." }       │
  │───────────────────────────>│
  │ { challenge: "<nonce>" }   │
  │<───────────────────────────│
  │                            │
  │ sign(nonce) with wallet    │
  │                            │
  │ POST /api/v1/auth/sign-in          │
  │ { address, public_key,     │
  │   signature, challenge,    │
  │   algorithm: "ML-DSA-65" } │
  │───────────────────────────>│
  │ { access_token, address }  │
  │<───────────────────────────│
```

## Supported wallet algorithms

| Algorithm | Type | Library |
|-----------|------|---------|
| ML-DSA-65 | Post-quantum lattice (FIPS 204) | `cryptography` |
| Ed25519 | Edwards curve | `cryptography` |
| secp256k1 | Elliptic curve (ECDSA) | `cryptography` |

## Compatibility with pico-client-auth

Tokens issued by pico-server-auth are standard JWT (RS256). pico-client-auth validates them by fetching JWKS from the `/api/v1/auth/jwks` endpoint.

**Same process**: pico-client-auth discovers the JWKS endpoint automatically (same FastAPI app).

**Separate processes**: configure pico-client-auth to point to the server:

```yaml
auth_client:
  issuer: "http://auth-server:8100"
  audience: "pico"
  # JWKS fetched from http://auth-server:8100/api/v1/auth/jwks
```

## Challenge store

By default, challenges are stored in memory with TTL expiry. For multi-instance deployments, register a custom `ChallengeStore` component:

```python
@component
class RedisChallengeStore:
    async def create(self, address: str) -> str: ...
    async def validate(self, address: str, nonce: str) -> bool: ...
    async def cleanup(self) -> int: ...
```

The in-memory default is replaced automatically via `on_missing_selector`.

## Configuration

```yaml
server_auth:
  issuer: "http://localhost:8100"
  audience: "pico"
  algorithm: "RS256"
  access_token_expire_minutes: 15
  challenge_ttl_seconds: 60
  supported_wallet_algorithms:
    - "ML-DSA-65"
    - "Ed25519"
    - "secp256k1"

  # ── v0.1.2: agent/fleet, revocation & mint audit ──
  admin_role: "operator"            # role stamped on password-login tokens
  fleet_mint_secret: ""             # set to enable POST /fleet/sessions (X-Fleet-Secret)
  fleet_session_ttl_seconds: 86400  # default fleet session lifetime (24h)
  revocation_store_path: ""         # JSONL path for the jti denylist (empty = in-memory)
  mint_audit_path: ""               # JSONL path for the mint audit log (empty = in-memory)
  mint_audit_min_ttl_seconds: 300   # don't audit mints shorter-lived than this
```

## Stack

- [pico-ioc](https://github.com/dperezcabrera/pico-ioc) — dependency injection
- [pico-boot](https://github.com/dperezcabrera/pico-boot) — auto-discovery
- [pico-fastapi](https://github.com/dperezcabrera/pico-fastapi) — controllers
- [pico-client-auth](https://github.com/dperezcabrera/pico-client-auth) — token validation

## License

MIT
