Metadata-Version: 2.3
Name: oakquant-tokens
Version: 0.1.0
Summary: OakQuant shared token contract: canonical JWT claim schema, EdDSA signer, verifier, JWKS, and Ed25519 key management. The single source of truth for issuing (Canopy) and verifying (grove, ranger, ...) access tokens.
Author: Pumulo Sikaneta
Author-email: pumulo@gmail.com
Requires-Python: >=3.13,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: Authlib (>=1.6.5,<2.0.0)
Requires-Dist: cryptography (>=46.0.2,<47.0.0)
Description-Content-Type: text/markdown

# oakquant-tokens

The shared **token contract** for the OakQuant platform — the single source of
truth for the access-token format so the issuer (Canopy) and every verifier
(grove, ranger, …) cannot drift.

Deliberately tiny: depends only on `authlib` + `cryptography`. No service-level
coupling — unlike depending on the full `timber-common`, any service can adopt
this without inheriting a database/ORM/encryption stack.

```python
from oak_tokens import (
    TokenSigner, TokenVerifier, TokenContext, TokenError,
    JwksClient, build_jwks, public_jwk,
    generate_ed25519_keypair, compute_kid, public_pem_from_private,
)
```

## Roles

- **Issuer (Canopy):** holds the Ed25519 private key, mints JWTs with
  `TokenSigner`, publishes the public half via `build_jwks` / `public_jwk` at
  `/.well-known/jwks.json`.
- **Verifiers (grove, ranger):** verify with `TokenVerifier`, resolving the
  signing key from the issuer's JWKS via `JwksClient` (rotation-friendly) or a
  static public key. Returns a `TokenContext`.

## Claim schema

Header: `alg=EdDSA`, `kid`, `typ=JWT`. Payload:
`iss, sub, aud, exp, iat, jti, scope, client_id, tenant_id, actor_kind, roles[]`.

Algorithm allow-list excludes `none`; `iss`/`aud`/`exp` and required claims are
enforced. An optional `revocation_check` callback supports a jti/introspection
revocation fallback for sensitive operations.

