# Hessra Python SDK
Python bindings for the Hessra authentication and authorization system.
## Overview
This Python package provides bindings to the Rust-based Hessra SDK, enabling Python applications to:
- Verify Biscuit authorization tokens (locally and remotely)
- Manage service chain token attestation
- Handle mTLS-authenticated communication with Hessra services
- Configure and manage authorization settings
**Note**: This library is focused on token verification and service chain operations. Token creation is handled by the Hessra authorization service.
## Installation
### From PyPI
```bash
# With uv
uv add hessra-py
# With pip
pip install hessra-py
```
### From Source
```bash
cd hessra-py
# Sync development dependencies (includes maturin)
uv sync --dev
# Build and install in development mode
uv run maturin develop
# Or build wheel and install
uv run maturin build --release
uv add target/wheels/hessra_py-*.whl
```
## Requirements
- Python 3.8+ (recommended: Python 3.12)
- [uv](https://docs.astral.sh/uv/) for Python package management
- Rust toolchain (for building from source)
## Quick Start
The Python SDK connects to your Hessra authorization service using the same test certificates as the Rust SDK examples.
```python
import hessra_py
# Load certificates (same as used in Rust SDK examples)
mtls_cert = open("../certs/client.crt").read()
mtls_key = open("../certs/client.key").read()
server_ca = open("../certs/ca-2030.pem").read()
# Create configuration
config = (hessra_py.HessraConfig.builder()
.base_url("test.hessra.net")
.port(443)
.protocol("http1")
.mtls_cert(mtls_cert)
.mtls_key(mtls_key)
.server_ca(server_ca)
.build())
# Create client and setup with public key
client = hessra_py.HessraClient(config)
client_with_key = client.setup_new()
# Verify a token locally (requires real Biscuit token)
client_with_key.verify_token_local(
token="<biscuit_token_base64>",
subject="uri:urn:test:argo-cli0",
resource="resource1",
operation="read"
)
# Create configuration from environment variables
config = hessra_py.HessraConfig.from_env()
# Or build configuration manually
config = (hessra_py.HessraConfig.builder()
.base_url("your-auth-service.com")
.port(443)
.protocol("http1")
.mtls_cert(your_client_cert)
.mtls_key(your_client_key)
.server_ca(your_server_ca)
.public_key(your_public_key)
.build())
# Create client
client = hessra_py.HessraClient(config)
# Setup client (fetches public key if needed)
client = client.setup_new()
# Verify a token locally
client.verify_token_local(
token="your_base64_token",
subject="user_id",
resource="api/endpoint",
operation="read"
)
# Verify token remotely via API
result = client.verify_token_remote(
token="your_base64_token",
subject="user_id",
resource="api/endpoint",
operation="read"
)
print(f"Verification result: {result}")
```
## Service Chain Operations
For complex authorization flows involving multiple services:
```python
# Attest a token with your service
attested_token = client.attest_service_chain_token(
token="original_token",
service="my-service"
)
# Verify a service chain token
service_chain_json = '''[
{
"component": "auth-service",
"public_key": "ed25519/public_key_1"
},
{
"component": "payment-service",
"public_key": "ed25519/public_key_2"
}
]'''
client.verify_service_chain_token_local(
token=attested_token,
subject="user_id",
resource="api/endpoint",
operation="read",
service_chain_json=service_chain_json,
component=None # Verify entire chain
)
```
## Configuration
### Environment Variables
The library supports loading configuration from environment variables:
```bash
export HESSRA_BASE_URL="your-service.com"
export HESSRA_PORT="443"
export HESSRA_PROTOCOL="http1"
export HESSRA_MTLS_CERT="$(cat client.crt)"
export HESSRA_MTLS_KEY="$(cat client.key)"
export HESSRA_SERVER_CA="$(cat ca.crt)"
export HESSRA_PUBLIC_KEY="$(cat public.key)"
export HESSRA_PERSONAL_KEYPAIR="$(cat personal.key)"
```
Then load with:
```python
config = hessra_py.HessraConfig.from_env()
```
### Builder Pattern
All configuration and client objects support a fluent builder pattern:
```python
config = (hessra_py.HessraConfig.builder()
.base_url("service.com")
.port(443)
.protocol("http1") # or "http3"
.mtls_cert(cert_string)
.mtls_key(key_string)
.server_ca(ca_string)
.public_key(public_key_string)
.personal_keypair(keypair_string)
.build())
client = (hessra_py.HessraClient.builder()
.base_url("service.com")
.port(443)
# ... other configuration
.build())
```
## Error Handling
All operations can raise `HessraPyError`:
```python
try:
client.verify_token_local(token, subject, resource, operation)
print("Token is valid")
except hessra_py.HessraPyError as e:
print(f"Verification failed: {e}")
```
## API Reference
### HessraConfig
Configuration object for Hessra services.
**Methods:**
- `from_env()` - Load from environment variables
- `builder()` - Create configuration builder
- Properties: `base_url`, `port`, `protocol`, `public_key`
### HessraClient
Main client for interacting with Hessra services.
**Methods:**
- `__init__(config)` - Create client with configuration
- `setup_new()` - Setup client and return new instance with public key
- `verify_token_local(token, subject, resource, operation)` - Verify token locally
- `verify_token_remote(token, subject, resource, operation)` - Verify token via API
- `get_public_key()` - Fetch public key from service
- `attest_service_chain_token(token, service)` - Add service attestation to token
- `verify_service_chain_token_local(...)` - Verify service chain token locally
- `verify_service_chain_token_remote(...)` - Verify service chain token via API
## Examples
See the `examples/` directory for complete usage examples:
- `basic_usage.py` - Basic token verification and configuration
- `test_verification.py` - Test suite demonstrating all features
## Development
Building and testing the Python bindings:
```bash
# Clone and navigate to the project
cd hessra-py
# Initialize uv project and sync dependencies
uv sync --dev
# Build in development mode
uv run maturin develop
# Run example tests
uv run python examples/basic_usage.py
uv run python examples/test_verification.py
# Run tests with pytest (when available)
uv run pytest
# Build release wheel
uv run maturin build --release
# Check the built wheel
ls -la target/wheels/
```
### Development Workflow
The Python bindings use `uv` for fast dependency management and `maturin` for building the Rust extension:
1. **Initial setup**: `uv sync --dev` installs all development dependencies
2. **Development builds**: `uv run maturin develop` builds and installs for testing
3. **Running examples**: `uv run python examples/...` executes Python scripts
4. **Release builds**: `uv run maturin build --release` creates optimized wheels
## Publishing and Releases
This package is published to PyPI independently from the main Hessra SDK. See [RELEASE.md](RELEASE.md) for the complete release process.
### For Maintainers
To release a new version:
1. Update version in `Cargo.toml`
2. Commit changes and create a tag: `git tag hessra-py-v0.1.1`
3. Push the tag: `git push origin hessra-py-v0.1.1`
4. GitHub Actions will automatically build and publish to PyPI
## License
Apache License 2.0 - See LICENSE file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "hessra-py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "hessra, authorization, authentication, security, biscuit, mtls, token, verification, rust, cryptography",
"author": null,
"author_email": "Jake Valentic <jake@hessra.net>",
"download_url": "https://files.pythonhosted.org/packages/2d/9e/7baf769f9765b445929a1a7230b79681d898b961843120693bae30f74099/hessra_py-0.2.1.tar.gz",
"platform": null,
"description": "# Hessra Python SDK\n\nPython bindings for the Hessra authentication and authorization system.\n\n## Overview\n\nThis Python package provides bindings to the Rust-based Hessra SDK, enabling Python applications to:\n\n- Verify Biscuit authorization tokens (locally and remotely)\n- Manage service chain token attestation\n- Handle mTLS-authenticated communication with Hessra services\n- Configure and manage authorization settings\n\n**Note**: This library is focused on token verification and service chain operations. Token creation is handled by the Hessra authorization service.\n\n## Installation\n\n### From PyPI\n\n```bash\n# With uv\nuv add hessra-py\n\n# With pip\npip install hessra-py\n```\n\n### From Source\n\n```bash\ncd hessra-py\n\n# Sync development dependencies (includes maturin)\nuv sync --dev\n\n# Build and install in development mode\nuv run maturin develop\n\n# Or build wheel and install\nuv run maturin build --release\nuv add target/wheels/hessra_py-*.whl\n```\n\n## Requirements\n\n- Python 3.8+ (recommended: Python 3.12)\n- [uv](https://docs.astral.sh/uv/) for Python package management\n- Rust toolchain (for building from source)\n\n## Quick Start\n\nThe Python SDK connects to your Hessra authorization service using the same test certificates as the Rust SDK examples.\n\n```python\nimport hessra_py\n\n# Load certificates (same as used in Rust SDK examples)\nmtls_cert = open(\"../certs/client.crt\").read()\nmtls_key = open(\"../certs/client.key\").read()\nserver_ca = open(\"../certs/ca-2030.pem\").read()\n\n# Create configuration\nconfig = (hessra_py.HessraConfig.builder()\n .base_url(\"test.hessra.net\")\n .port(443)\n .protocol(\"http1\")\n .mtls_cert(mtls_cert)\n .mtls_key(mtls_key)\n .server_ca(server_ca)\n .build())\n\n# Create client and setup with public key\nclient = hessra_py.HessraClient(config)\nclient_with_key = client.setup_new()\n\n# Verify a token locally (requires real Biscuit token)\nclient_with_key.verify_token_local(\n token=\"<biscuit_token_base64>\",\n subject=\"uri:urn:test:argo-cli0\",\n resource=\"resource1\",\n operation=\"read\"\n)\n\n# Create configuration from environment variables\nconfig = hessra_py.HessraConfig.from_env()\n\n# Or build configuration manually\nconfig = (hessra_py.HessraConfig.builder()\n .base_url(\"your-auth-service.com\")\n .port(443)\n .protocol(\"http1\")\n .mtls_cert(your_client_cert)\n .mtls_key(your_client_key)\n .server_ca(your_server_ca)\n .public_key(your_public_key)\n .build())\n\n# Create client\nclient = hessra_py.HessraClient(config)\n\n# Setup client (fetches public key if needed)\nclient = client.setup_new()\n\n# Verify a token locally\nclient.verify_token_local(\n token=\"your_base64_token\",\n subject=\"user_id\",\n resource=\"api/endpoint\",\n operation=\"read\"\n)\n\n# Verify token remotely via API\nresult = client.verify_token_remote(\n token=\"your_base64_token\",\n subject=\"user_id\",\n resource=\"api/endpoint\",\n operation=\"read\"\n)\nprint(f\"Verification result: {result}\")\n```\n\n## Service Chain Operations\n\nFor complex authorization flows involving multiple services:\n\n```python\n# Attest a token with your service\nattested_token = client.attest_service_chain_token(\n token=\"original_token\",\n service=\"my-service\"\n)\n\n# Verify a service chain token\nservice_chain_json = '''[\n {\n \"component\": \"auth-service\",\n \"public_key\": \"ed25519/public_key_1\"\n },\n {\n \"component\": \"payment-service\",\n \"public_key\": \"ed25519/public_key_2\"\n }\n]'''\n\nclient.verify_service_chain_token_local(\n token=attested_token,\n subject=\"user_id\",\n resource=\"api/endpoint\",\n operation=\"read\",\n service_chain_json=service_chain_json,\n component=None # Verify entire chain\n)\n```\n\n## Configuration\n\n### Environment Variables\n\nThe library supports loading configuration from environment variables:\n\n```bash\nexport HESSRA_BASE_URL=\"your-service.com\"\nexport HESSRA_PORT=\"443\"\nexport HESSRA_PROTOCOL=\"http1\"\nexport HESSRA_MTLS_CERT=\"$(cat client.crt)\"\nexport HESSRA_MTLS_KEY=\"$(cat client.key)\"\nexport HESSRA_SERVER_CA=\"$(cat ca.crt)\"\nexport HESSRA_PUBLIC_KEY=\"$(cat public.key)\"\nexport HESSRA_PERSONAL_KEYPAIR=\"$(cat personal.key)\"\n```\n\nThen load with:\n\n```python\nconfig = hessra_py.HessraConfig.from_env()\n```\n\n### Builder Pattern\n\nAll configuration and client objects support a fluent builder pattern:\n\n```python\nconfig = (hessra_py.HessraConfig.builder()\n .base_url(\"service.com\")\n .port(443)\n .protocol(\"http1\") # or \"http3\"\n .mtls_cert(cert_string)\n .mtls_key(key_string)\n .server_ca(ca_string)\n .public_key(public_key_string)\n .personal_keypair(keypair_string)\n .build())\n\nclient = (hessra_py.HessraClient.builder()\n .base_url(\"service.com\")\n .port(443)\n # ... other configuration\n .build())\n```\n\n## Error Handling\n\nAll operations can raise `HessraPyError`:\n\n```python\ntry:\n client.verify_token_local(token, subject, resource, operation)\n print(\"Token is valid\")\nexcept hessra_py.HessraPyError as e:\n print(f\"Verification failed: {e}\")\n```\n\n## API Reference\n\n### HessraConfig\n\nConfiguration object for Hessra services.\n\n**Methods:**\n\n- `from_env()` - Load from environment variables\n- `builder()` - Create configuration builder\n- Properties: `base_url`, `port`, `protocol`, `public_key`\n\n### HessraClient\n\nMain client for interacting with Hessra services.\n\n**Methods:**\n\n- `__init__(config)` - Create client with configuration\n- `setup_new()` - Setup client and return new instance with public key\n- `verify_token_local(token, subject, resource, operation)` - Verify token locally\n- `verify_token_remote(token, subject, resource, operation)` - Verify token via API\n- `get_public_key()` - Fetch public key from service\n- `attest_service_chain_token(token, service)` - Add service attestation to token\n- `verify_service_chain_token_local(...)` - Verify service chain token locally\n- `verify_service_chain_token_remote(...)` - Verify service chain token via API\n\n## Examples\n\nSee the `examples/` directory for complete usage examples:\n\n- `basic_usage.py` - Basic token verification and configuration\n- `test_verification.py` - Test suite demonstrating all features\n\n## Development\n\nBuilding and testing the Python bindings:\n\n```bash\n# Clone and navigate to the project\ncd hessra-py\n\n# Initialize uv project and sync dependencies\nuv sync --dev\n\n# Build in development mode\nuv run maturin develop\n\n# Run example tests\nuv run python examples/basic_usage.py\nuv run python examples/test_verification.py\n\n# Run tests with pytest (when available)\nuv run pytest\n\n# Build release wheel\nuv run maturin build --release\n\n# Check the built wheel\nls -la target/wheels/\n```\n\n### Development Workflow\n\nThe Python bindings use `uv` for fast dependency management and `maturin` for building the Rust extension:\n\n1. **Initial setup**: `uv sync --dev` installs all development dependencies\n2. **Development builds**: `uv run maturin develop` builds and installs for testing\n3. **Running examples**: `uv run python examples/...` executes Python scripts\n4. **Release builds**: `uv run maturin build --release` creates optimized wheels\n\n## Publishing and Releases\n\nThis package is published to PyPI independently from the main Hessra SDK. See [RELEASE.md](RELEASE.md) for the complete release process.\n\n### For Maintainers\n\nTo release a new version:\n\n1. Update version in `Cargo.toml`\n2. Commit changes and create a tag: `git tag hessra-py-v0.1.1`\n3. Push the tag: `git push origin hessra-py-v0.1.1`\n4. GitHub Actions will automatically build and publish to PyPI\n\n## License\n\nApache License 2.0 - See LICENSE file for details.\n\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Python bindings for the Hessra authorization system with Biscuit token verification and mTLS support",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/hessra/hessra-sdk.rs/issues",
"Documentation": "https://docs.rs/hessra-sdk",
"Homepage": "https://github.com/hessra/hessra-sdk.rs",
"Repository": "https://github.com/hessra/hessra-sdk.rs",
"Source Code": "https://github.com/hessra/hessra-sdk.rs/tree/main/hessra-py"
},
"split_keywords": [
"hessra",
" authorization",
" authentication",
" security",
" biscuit",
" mtls",
" token",
" verification",
" rust",
" cryptography"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "05b16b5c3aba2ba78464ec9fe7aca12865e0617d3c855cca2b38782de42984bb",
"md5": "3260d4cc5acf85ac3c7ed9b036a09495",
"sha256": "a8b06bf09594fd7916f70059d2303dedc456d20b22f8ccddd47f46ac32bbe07c"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "3260d4cc5acf85ac3c7ed9b036a09495",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3336076,
"upload_time": "2025-08-28T18:30:24",
"upload_time_iso_8601": "2025-08-28T18:30:24.920533Z",
"url": "https://files.pythonhosted.org/packages/05/b1/6b5c3aba2ba78464ec9fe7aca12865e0617d3c855cca2b38782de42984bb/hessra_py-0.2.1-cp38-abi3-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "293fbf57e35f114e170d75b78941759acfa2b4ca56f264d9a8bae24a783497f8",
"md5": "ac1e37504c0f2c4476f904d4e4a5ce68",
"sha256": "2b7579e71fa18cf6148afe5cf087c707016a181f43fe0430c69c37ba2a12fbee"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "ac1e37504c0f2c4476f904d4e4a5ce68",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3135703,
"upload_time": "2025-08-28T18:30:26",
"upload_time_iso_8601": "2025-08-28T18:30:26.887030Z",
"url": "https://files.pythonhosted.org/packages/29/3f/bf57e35f114e170d75b78941759acfa2b4ca56f264d9a8bae24a783497f8/hessra_py-0.2.1-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5b0794d2954a14a4203dbf35208b0db9b664a17930ece3dc8cfa3ee0eedbafac",
"md5": "d9882cbe5ebf7f5f7f5bfa534c14f9b1",
"sha256": "cf7af5c808a4a1aab028015744e19fc6867601f974e0e42411ef99a2ce7cd10e"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "d9882cbe5ebf7f5f7f5bfa534c14f9b1",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3652264,
"upload_time": "2025-08-28T18:30:29",
"upload_time_iso_8601": "2025-08-28T18:30:29.325116Z",
"url": "https://files.pythonhosted.org/packages/5b/07/94d2954a14a4203dbf35208b0db9b664a17930ece3dc8cfa3ee0eedbafac/hessra_py-0.2.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "62399b7c6779dd307cecc55dd9c3e5dab716106cbe62f0e084689737a3727701",
"md5": "dbf4ec368248a514a2f2f4c9e098b7f8",
"sha256": "745078529a406b85b9b6c8d7c10ba7cce39827af41d538736406846b31392d8f"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-manylinux_2_28_aarch64.whl",
"has_sig": false,
"md5_digest": "dbf4ec368248a514a2f2f4c9e098b7f8",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 3492956,
"upload_time": "2025-08-28T18:30:31",
"upload_time_iso_8601": "2025-08-28T18:30:31.537732Z",
"url": "https://files.pythonhosted.org/packages/62/39/9b7c6779dd307cecc55dd9c3e5dab716106cbe62f0e084689737a3727701/hessra_py-0.2.1-cp38-abi3-manylinux_2_28_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b180af4d6d07d7316e4bdaeec76c07a16bd91309c7dc10efe1530d97b284b50a",
"md5": "3a75555827d753bb64d17b854c68ec1f",
"sha256": "4090838b2b914364c47d3785330d9e9e375075d322c995385c097adf16369e94"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-win32.whl",
"has_sig": false,
"md5_digest": "3a75555827d753bb64d17b854c68ec1f",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 2509550,
"upload_time": "2025-08-28T18:30:35",
"upload_time_iso_8601": "2025-08-28T18:30:35.393435Z",
"url": "https://files.pythonhosted.org/packages/b1/80/af4d6d07d7316e4bdaeec76c07a16bd91309c7dc10efe1530d97b284b50a/hessra_py-0.2.1-cp38-abi3-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "93cf822c74256f50250ef3998a24b3d805b83375dc10db8f5fc1edeb2d19efc1",
"md5": "4695004015795f46962c96681780ff4b",
"sha256": "0a0574bca20bc88763ea72513f7aab580a6103603cfcf461bdf02e6db22f4e07"
},
"downloads": -1,
"filename": "hessra_py-0.2.1-cp38-abi3-win_amd64.whl",
"has_sig": false,
"md5_digest": "4695004015795f46962c96681780ff4b",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 2914205,
"upload_time": "2025-08-28T18:30:37",
"upload_time_iso_8601": "2025-08-28T18:30:37.945652Z",
"url": "https://files.pythonhosted.org/packages/93/cf/822c74256f50250ef3998a24b3d805b83375dc10db8f5fc1edeb2d19efc1/hessra_py-0.2.1-cp38-abi3-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2d9e7baf769f9765b445929a1a7230b79681d898b961843120693bae30f74099",
"md5": "57d5846eb7ae0e997786d57872e0c845",
"sha256": "9acddbd4bd0da162de78c6d520ffb12c655ddf46bff927eae90ca0dcf475899a"
},
"downloads": -1,
"filename": "hessra_py-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "57d5846eb7ae0e997786d57872e0c845",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 150868,
"upload_time": "2025-08-28T18:30:41",
"upload_time_iso_8601": "2025-08-28T18:30:41.126762Z",
"url": "https://files.pythonhosted.org/packages/2d/9e/7baf769f9765b445929a1a7230b79681d898b961843120693bae30f74099/hessra_py-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-28 18:30:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hessra",
"github_project": "hessra-sdk.rs",
"github_not_found": true,
"lcname": "hessra-py"
}