Metadata-Version: 2.4
Name: veltro-suite-auth
Version: 0.2.1
Summary: Canonical Veltro suite auth contract: Auth.js session decode + suite-service token mint/verify.
Project-URL: Homepage, https://github.com/veltrosecurity/vectorflow/tree/main/packages/suite-auth-py
Project-URL: Repository, https://github.com/veltrosecurity/vectorflow
Author: Veltro Security
License: AGPL-3.0-or-later
Keywords: auth,authjs,jwe,suite-service-token,veltro
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: cryptography>=43.0.0
Requires-Dist: python-jose[cryptography]>=3.5.0
Description-Content-Type: text/markdown

# veltro-suite-auth

The **canonical Veltro suite auth contract** — one published Python package for
the two cross-service security primitives shared across the Veltro suite
(VectorFlow, CHAD, WARDEN). Before this package each app carried its own
byte-identical copy of the decoder/verifier; CHAD and WARDEN now depend on this
package and carry none.

## What it provides

- **`veltro_suite_auth.session`** — decode VectorFlow's Auth.js v5 session
  cookie (JWE, `alg=dir` / `enc=A256CBC-HS512`, HKDF-SHA256 key salted by the
  cookie name) for delegated suite login.
  - `decode_session(cookies, secret) -> SessionClaims | None`
  - `SessionClaims`, `SessionError` / `SessionInvalid` / `SessionExpired`
  - `SESSION_COOKIE_NAMES`, `derive_encryption_key`
- **`veltro_suite_auth.service_token`** — mint + verify the short-lived (60s),
  scoped, HS256 suite-service token used for machine-to-machine calls between
  suite apps (issuer `veltro-suite`, audience `suite-service`).
  - `mint_service_token(secret, *, scope, svc, actor_email=None, actor_suite_role=None) -> str`
  - `verify_service_token(token, secret, required_scope) -> ServiceTokenClaims`
  - `ServiceTokenClaims`, `ServiceTokenError` / `ServiceTokenInvalid` / `ServiceTokenExpired`
  - `SUITE_SERVICE_ISSUER`, `SUITE_SERVICE_AUDIENCE`, `SUITE_SERVICE_MINTERS`,
    `SUITE_SERVICE_TOKEN_TTL_SECONDS`
- **`veltro_suite_auth.testing`** — golden cross-language vectors, shipped in
  the wheel: `session_fixture()`, `service_token_vectors()`.

Old `settings:*` and `external:*` families keep optional actor claims.
Product-scoped `chad:*` and `warden:*` tokens require both `actor_email` and
`actor_suite_role`, and verification rejects them otherwise.

## Contract source & rename map

The code was moved **verbatim** from CHAD's `backend/app/core/vf_session.py`
and `backend/app/core/suite_service_token.py`, plus WARDEN's minting logic from
`backend/app/services/suite_token.py`. Only symbol names and CHAD/WARDEN-specific
docstring prose changed:

| old (CHAD / WARDEN) | new (`veltro_suite_auth`) |
|---|---|
| `decode_vf_session` | `decode_session` |
| `VfSessionClaims` | `SessionClaims` |
| `VfSessionError` / `VfSessionInvalid` / `VfSessionExpired` | `SessionError` / `SessionInvalid` / `SessionExpired` |
| `SESSION_COOKIE_NAMES`, `derive_encryption_key` | *unchanged* |
| `verify_suite_service_token` | `verify_service_token` |
| `SuiteServiceClaims` | `ServiceTokenClaims` |
| `SuiteServiceTokenError` / `...Invalid` / `...Expired` | `ServiceTokenError` / `ServiceTokenInvalid` / `ServiceTokenExpired` |
| `SUITE_SERVICE_ISSUER` / `SUITE_SERVICE_AUDIENCE` / `SUITE_SERVICE_MINTERS` | *unchanged* |
| WARDEN `mint_suite_service_token(scope)` (settings-coupled) | `mint_service_token(secret, *, scope, svc, ...)` (explicit params) |

## Cross-language conformance

The suite has a TypeScript minter (VectorFlow's
`src/server/services/suite/service-token.ts`) and this Python decoder/verifier.
Two per-PR gates in the VectorFlow repo keep them from drifting:

- **`suite-auth-contract` CI job** — installs this package and runs its tests,
  including `tests/conformance/test_fresh_session_roundtrip.py`, which shells
  `node scripts/mint-test-session.mjs` to mint a **fresh** Auth.js cookie and
  decodes it here. Catches VF-minter ⟂ Python-decoder drift on the session
  cookie.
- **`contract-vectors.test.ts`** — pins the committed
  `vectors/service-token-vectors.json` against the live TS minters
  (`mintSuiteServiceToken` / `mintSuiteExternalToken`). Catches TS-minter
  drift on the service token; the Python side of the same vectors is asserted
  by `tests/test_vectors.py`.

## Regenerating the vectors

- **`session-fixture.json`** — a fixed Auth.js cookie. Regenerate with
  VectorFlow's script (from the repo root):

  ```sh
  node scripts/mint-test-session.mjs > packages/suite-auth-py/src/veltro_suite_auth/vectors/session-fixture.json
  ```

- **`service-token-vectors.json`** — ten suite-service vectors covering the
  legacy scopes, every actor-required MCP family, `svc=veltro`, and rejection
  of an actorless MCP token. Regenerate with (from the repo root):

  ```sh
  EMIT_CONTRACT_VECTORS=1 pnpm vitest run src/server/services/suite/__tests__/contract-vectors.test.ts
  ```

## Local development

```sh
# from packages/suite-auth-py/
python3.11 -m venv .venv && . .venv/bin/activate
pip install -e . pytest
pytest -v            # conformance test needs `node` + a repo checkout, else it skips
```

## Publish (after merge to main)

The `Publish suite auth to PyPI` workflow builds and publishes with PyPI
Trusted Publishing. Its PyPI publisher must match:

- owner: `veltrosecurity`
- repository: `vectorflow`
- workflow: `publish-suite-auth.yml`
- environment: `pypi`

Dispatch the workflow from `main`. Never republish an existing version — bump
both `pyproject.toml` and `veltro_suite_auth.__version__` for every release.
