Skip to main content

DPoP signer/verifier for Swarmauri

Project description

Swarmauri Logo

PyPI - Downloads Hits PyPI - Python Version PyPI - License PyPI - swarmauri_signing_dpop

Swarmauri Signing DPoP

DPoP proof signer/verifier implementing RFC 9449 for proof-of-possession over HTTP requests.

Features:

  • Creates and validates dpop+jwt proofs with embedded public JWK thumbprints.
  • Supports ES256, RS256, and EdDSA algorithms through the SigningBase interface.
  • Optional access-token hash binding (ath), nonce enforcement, and replay-protection hooks.

Installation

The package is published on PyPI together with the dependencies required to sign and verify DPoP proofs.

pip

pip install swarmauri_signing_dpop

uv

uv add swarmauri_signing_dpop

Poetry

poetry add swarmauri_signing_dpop

Usage

DpopSigner implements the asynchronous SigningBase / ISigning interface. Signing requires the HTTP method and URL (opts['htm'] and opts['htu']), and verification requires the same data passed via require.

Signing and verifying a request

import asyncio

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519

from swarmauri_signing_dpop import DpopSigner


async def main() -> None:
    signer = DpopSigner()

    private_key = ed25519.Ed25519PrivateKey.generate()
    priv_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )
    key = {"kind": "pem", "priv": priv_pem, "alg": "EdDSA"}

    signatures = await signer.sign_bytes(
        key,
        b"",
        opts={"htm": "GET", "htu": "https://api.example/x"},
    )

    is_valid = await signer.verify_bytes(
        b"",
        signatures,
        require={"htm": "GET", "htu": "https://api.example/x"},
    )
    assert is_valid
    print("DPoP proof valid:", is_valid)


asyncio.run(main())

Signature format

sign_bytes and sign_envelope return a sequence with a single detached signature entry:

{
    "alg": "EdDSA",            # JWS algorithm used
    "format": "dpop+jwt",      # proof media type
    "sig": "<compact JWT>",    # DPoP proof token containing the claims
    "jkt": "<thumbprint>",     # SHA-256 JWK thumbprint for cnf.jkt binding
}

Use the jkt helper when comparing against cnf.jkt values embedded in access tokens.

Key references

Keys are provided using the KeyRef mapping expected by other Swarmauri signing packages:

  • { "kind": "pem", "priv": <PEM bytes|str> } — RSA/EC keys and Ed25519 PKCS8 PEM.
  • { "kind": "jwk", "priv": <private JWK dict> } — accepts EC, RSA, or OKP keys with private fields.

For Ed25519 material, both formats are supported; the signer derives and embeds the public JWK automatically.

Options reference

  • opts['htm'] / opts['htu']: HTTP method and URL that will be bound in the proof (required for signing).
  • opts['nonce']: Optional server-issued DPoP-Nonce to include in the proof.
  • opts['access_token']: Optional access token to derive the ath confirmation hash.
  • require['htm'] / require['htu']: Expected method and URL (required for verification).
  • require['max_skew_s']: IAT skew tolerance (defaults to 300 seconds).
  • require['algs']: Allowed signing algorithms. Defaults to all supported values.
  • require['nonce']: Expected nonce when enforcing a server challenge.
  • require['access_token']: Expected bearer token when validating ath.
  • require['replay']: Mapping with seen(jti) -> bool and mark(jti, ttl_s) callables for replay prevention.

sign_envelope and verify_envelope reuse the same logic after canonicalizing the envelope to bytes (raw or json). Payload bytes are otherwise unused because the DPoP proof binds request metadata instead of message content.

Entry Point

The signer registers under the swarmauri.signings entry point as DpopSigner.

Want to help?

If you want to contribute to swarmauri-sdk, read up on our guidelines for contributing that will help you get started.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swarmauri_signing_dpop-0.1.2.dev9.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swarmauri_signing_dpop-0.1.2.dev9-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file swarmauri_signing_dpop-0.1.2.dev9.tar.gz.

File metadata

  • Download URL: swarmauri_signing_dpop-0.1.2.dev9.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","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

Hashes for swarmauri_signing_dpop-0.1.2.dev9.tar.gz
Algorithm Hash digest
SHA256 8840cad9f967543850a9c0331ae35ab9380498fdf563c192b453e97abea1c1d9
MD5 07e0cfbd65a692aac76e13f2dd444dba
BLAKE2b-256 bbafd7397319e7baadac0222e66d423f8b4d19d46f797fc6503e06f329936880

See more details on using hashes here.

File details

Details for the file swarmauri_signing_dpop-0.1.2.dev9-py3-none-any.whl.

File metadata

  • Download URL: swarmauri_signing_dpop-0.1.2.dev9-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","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

Hashes for swarmauri_signing_dpop-0.1.2.dev9-py3-none-any.whl
Algorithm Hash digest
SHA256 d137c71eefa38196054439425eb9ce461809fac79861b7886c5d9ca3bfea1a05
MD5 154d7e204b2c483b380494383f74e3b5
BLAKE2b-256 45211373e99f83cbc55c63ee1ea686e955acf535d59b173ef4c9aa72f5bc1971

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page