DPoP proof-of-possession tooling for Swarmauri services
Project description
Swarmauri PoP DPoP
swarmauri_pop_dpop enables RFC 9449 Demonstrating Proof-of-Possession flows for
Swarmauri services. The signer and verifier reuse the shared Swarmauri PoP
contract so applications can mix DPoP, CWT, and X.509 strategies interchangeably.
Features
- Implements
DPoPSignerandDPoPVerifierwith consistent Swarmauri PoP semantics, includingcnfgeneration and verification hooks - Normalises HTTP method and URI handling to align with the DPoP specification, including support for query strings and ports
- Provides nonce and replay integration points so you can plug in application-specific storage to enforce single-use proofs
- Validates
athhashes for OAuth access tokens to ensure request binding when PoP is layered on bearer credentials
Installation
pip install swarmauri_pop_dpop
uv add swarmauri_pop_dpop
Usage
Signing an outgoing HTTP request
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
import base64
from swarmauri_pop_dpop import DPoPSigner
private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()
public_jwk = {
"kty": "OKP",
"crv": "Ed25519",
"x": base64.urlsafe_b64encode(
public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw,
)
).rstrip(b"=").decode("ascii"),
}
signer = DPoPSigner(
private_key=private_key,
public_jwk=public_jwk,
algorithm="EdDSA",
)
dpop_header = signer.sign_request("GET", "https://api.example.com/resource")
print("DPoP header:", dpop_header)
print("cnf:", signer.cnf_binding())
Verifying an incoming HTTP request
import asyncio
from typing import Mapping
from swarmauri_core.pop import CnfBinding, HttpParts, VerifyPolicy
from swarmauri_pop_dpop import DPoPVerifier
class MemoryReplay:
def __init__(self) -> None:
self._seen: set[str] = set()
def seen(self, scope: str, key: str) -> bool:
return f"{scope}:{key}" in self._seen
def mark(self, scope: str, key: str, ttl_s: int) -> None:
self._seen.add(f"{scope}:{key}")
async def verify_request(headers: Mapping[str, str], cnf: CnfBinding, access_token: str) -> None:
verifier = DPoPVerifier()
req = HttpParts(method="GET", url="https://api.example.com/resource", headers=headers)
await verifier.verify_http(
req,
cnf,
policy=VerifyPolicy(require_ath=True),
replay=MemoryReplay(),
extras={"access_token": access_token},
)
asyncio.run(verify_request({"DPoP": dpop_header}, signer.cnf_binding(), "opaque-access-token"))
The verifier enforces thumbprints for the provided JWK, checks nonce and replay
constraints, and validates ath hashes when bearer tokens are provided.
Compatibility
- Python 3.10, 3.11, and 3.12
- Asynchronous contexts that can dispatch
HttpPartsinstances fromswarmauri_core - Intended for OAuth 2.0 servers, API gateways, and microservices that need to accept Demonstration of Proof-of-Possession headers
Related Packages
swarmauri_pop_cwtfor COSE-based confirmationswarmauri_pop_x509to validate mutual TLS thumbprints using the samecnfcontractswarmauri_corewhich defines the PoP primitives consumed by all Swarmauri proof strategies
Contributing
Please contribute improvements through the Swarmauri SDK repository. Ensure tests, formatting, and linting match the root instructions and describe your changes clearly in pull requests so reviewers understand the intended impact.
Support
Need help integrating DPoP in Swarmauri? File an issue on GitHub with implementation details and reproduction steps. For security disclosures, use the contact information listed in the repository security policy.
License
Apache License 2.0. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file swarmauri_pop_dpop-0.11.0.dev1.tar.gz.
File metadata
- Download URL: swarmauri_pop_dpop-0.11.0.dev1.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8858e3c2f24ebf14e2cb84ceb3058178a2e004705146265acc835807a9019da2
|
|
| MD5 |
a356d7b94c750b18beff6d7913f47d91
|
|
| BLAKE2b-256 |
4386cfd5eca211f03fdce9ec20778ac06ae3d1d4ea99939aa6827306536ae346
|
File details
Details for the file swarmauri_pop_dpop-0.11.0.dev1-py3-none-any.whl.
File metadata
- Download URL: swarmauri_pop_dpop-0.11.0.dev1-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
714ec380ad52ec2748eba78b91474ba1774fa36428474bc3180360d30170c870
|
|
| MD5 |
b2c5f717ece15b7e7c9fa742ca2d9591
|
|
| BLAKE2b-256 |
e0caaa2eabb0f6381ca524e0507302c7780a6e58baf9ad82e44277af3a48baf4
|