Metadata-Version: 2.5
Name: jwt-policy-guard
Version: 0.1.0
Summary: Policy-first JWT verification and issuing for Python applications.
Project-URL: Homepage, https://github.com/uppy19d0/jwt-policy-guard-python
Project-URL: Documentation, https://github.com/uppy19d0/jwt-policy-guard-python#readme
Project-URL: Repository, https://github.com/uppy19d0/jwt-policy-guard-python
Project-URL: Issues, https://github.com/uppy19d0/jwt-policy-guard-python/issues
Project-URL: Changelog, https://github.com/uppy19d0/jwt-policy-guard-python/blob/main/CHANGELOG.md
Author: Luis Aneuris Tavarez De Jesus
License-Expression: MIT
License-File: LICENSE
Keywords: authentication,authorization,jwks,jwt,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: pyjwt[crypto]<3,>=2.13
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy<2,>=1.14; extra == 'dev'
Requires-Dist: pytest-cov>=6; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Requires-Dist: twine>=6; extra == 'dev'
Description-Content-Type: text/markdown

# jwt-policy-guard

[![CI](https://github.com/uppy19d0/jwt-policy-guard-python/actions/workflows/ci.yml/badge.svg)](https://github.com/uppy19d0/jwt-policy-guard-python/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/jwt-policy-guard.svg)](https://pypi.org/project/jwt-policy-guard/)
[![Python](https://img.shields.io/pypi/pyversions/jwt-policy-guard.svg)](https://pypi.org/project/jwt-policy-guard/)

Policy-first JWT verification and issuing for Python 3.9+. The package builds on
PyJWT's maintained cryptographic implementation and adds an immutable application
policy so security decisions do not come from attacker-controlled token headers.

Created by [Luis Aneuris Tavarez De Jesus](https://www.ltavarez.me/).

## Why this exists

JWT signature verification is only one part of token security. Applications must
also constrain algorithms, bind keys to a trusted issuer, validate audiences,
require time claims, distinguish token types, and enforce their own scopes and
roles. `jwt-policy-guard` makes those decisions explicit and reusable.

## Installation

```bash
pip install jwt-policy-guard
```

## Verify tokens

```python
from datetime import timedelta
from jwt_policy_guard import JwtPolicy, JwtVerifier, JwksKeyProvider

policy = JwtPolicy(
    algorithms=("RS256",),
    issuer="https://identity.example.com/",
    audiences=("payments-api",),
    required_scopes=frozenset({"payments:read"}),
    max_token_age=timedelta(minutes=15),
)

verifier = JwtVerifier(
    policy,
    JwksKeyProvider("https://identity.example.com/.well-known/jwks.json"),
)
verified = verifier.verify(encoded_token)

print(verified.subject)
verified.require_roles({"operator"})
```

## Issue application-owned tokens

```python
from datetime import timedelta
from jwt_policy_guard import JwtIssuer

issuer = JwtIssuer(
    issuer="https://identity.example.com/",
    audiences=("payments-api",),
    key=private_key,
    algorithm="RS256",
    key_id="2026-09-primary",
)

token = issuer.issue(
    "customer-42",
    expires_in=timedelta(minutes=10),
    scopes={"payments:read"},
    roles={"customer"},
    claims={"tenant": "acme"},
)
```

## Security guarantees

- No unsecured `none` algorithm.
- Symmetric and asymmetric algorithms cannot be mixed in one policy.
- The allow-list never comes from the token header.
- Trusted issuer, intended audience, registered time claims, and explicit `typ`.
- Optional maximum token age, subject pattern, required scopes, and roles.
- HTTPS-only JWKS by default with PyJWT key caching and rotation support.
- Read-only verified claims and a typed exception hierarchy.

This library follows the deployment guidance in
[RFC 8725](https://www.rfc-editor.org/rfc/rfc8725.html). It does not replace TLS,
secure key storage, key rotation, token revocation, or application authorization.
Never log raw tokens.

## Development

```bash
python -m pip install -e '.[dev]'
ruff check .
mypy src
pytest
python -m build
twine check dist/*
```

## License

MIT
