Skip to main content

Algorithm-routing token service for Swarmauri

Project description

Swarmauri Logo

PyPI - Downloads Hits PyPI - Python Version PyPI - License PyPI - swarmauri_tokens_composite


Swarmauri Token Composite

Algorithm-routing token service delegating to child providers based on JWT headers, claims, or algorithms.

Features

  • Compose multiple asynchronous ITokenService implementations behind a single CompositeTokenService facade.
  • Dispatch mint requests by explicit service hints (headers["svc"]), token type headers (headers["typ"]), confirmation claims (claims["cnf"]), or requested algorithms.
  • Detect verification routes from SSH certificate prefixes, JWT-style tokens (including DPoP and mTLS-bound variants), or fall back through each service until one succeeds.
  • Merge child capability metadata and JWKS responses, de-duplicating keys by kid so downstream clients can rely on a single aggregated feed.

Installation

Install the package with your preferred Python packaging tool:

pip install swarmauri_tokens_composite
poetry add swarmauri_tokens_composite

If you use uv, install it (skip the first line if uv is already available) and then add the package:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv pip install swarmauri_tokens_composite

Usage

CompositeTokenService accepts a list of services implementing ITokenService. It inspects headers, claims, and requested algorithms to choose the most appropriate delegate for mint, verify, and jwks calls. The child services remain responsible for the actual cryptographic work, while the composite aggregates their capabilities and keys.

# README Example: CompositeTokenService basic routing
import asyncio
from typing import Any, Dict, Iterable

from swarmauri_tokens_composite import CompositeTokenService


class MemoryTokenService:
    """In-memory stand-in for an async ITokenService implementation."""

    def __init__(self, type_name: str, formats: Iterable[str], algs: Iterable[str]):
        self.type = type_name
        self._formats = tuple(formats)
        self._algs = tuple(algs)

    def supports(self) -> Dict[str, Iterable[str]]:
        return {"formats": self._formats, "algs": self._algs}

    async def mint(
        self, claims: Dict[str, Any], *, alg: str, headers=None, **_: Any
    ) -> str:
        return f"{self.type}:{alg}:{claims['sub']}"

    async def verify(self, token: str, **kwargs) -> Dict[str, Any]:
        svc, alg, sub = token.split(":", 2)
        if svc != self.type:
            raise ValueError("routed to wrong service")
        return {"sub": sub, "alg": alg, "service": svc}

    async def jwks(self) -> Dict[str, Any]:
        return {"keys": [{"kid": f"{self.type}-kid"}]}


def build_composite() -> CompositeTokenService:
    jwt_service = MemoryTokenService("JWTTokenService", ["JWT"], ["HS256"])
    ssh_service = MemoryTokenService("SshCertTokenService", ["SSH-CERT"], ["ssh-ed25519"])
    return CompositeTokenService([jwt_service, ssh_service])


def describe_example(result: Dict[str, Any]) -> None:
    print("JWT token:", result["jwt_token"])
    print("SSH token:", result["ssh_token"])
    print("JWT service handled mint/verify:", result["jwt_claims"]["service"])
    print("SSH service handled mint/verify:", result["ssh_claims"]["service"])
    print("JWKS keys:", {entry["kid"] for entry in result["jwks"]["keys"]})


async def main() -> Dict[str, Any]:
    composite = build_composite()

    jwt_token = await composite.mint({"sub": "alice"}, alg="HS256")
    ssh_token = await composite.mint({"sub": "bob"}, alg="ssh-ed25519")

    jwt_claims = await composite.verify(jwt_token)
    ssh_claims = await composite.verify(ssh_token)
    jwks = await composite.jwks()

    return {
        "jwt_token": jwt_token,
        "ssh_token": ssh_token,
        "jwt_claims": jwt_claims,
        "ssh_claims": ssh_claims,
        "jwks": jwks,
    }


example_result = asyncio.run(main())
describe_example(example_result)

The example above shows how the composite selects different child services by algorithm while producing a merged JWKS response. In production you would supply concrete implementations that speak to HSMs, remote signing services, or other secure key stores.

Entry point

The provider is registered under the swarmauri.tokens entry-point as CompositeTokenService.

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_tokens_composite-0.3.0.dev51.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

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

File details

Details for the file swarmauri_tokens_composite-0.3.0.dev51.tar.gz.

File metadata

  • Download URL: swarmauri_tokens_composite-0.3.0.dev51.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","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_tokens_composite-0.3.0.dev51.tar.gz
Algorithm Hash digest
SHA256 18e95413a941ba37ea6087ceab1db3c921e1301818d8f2f84daa4dc49f0fd7ba
MD5 06d9f3b1c9c33aa3fe8964e03224fa1f
BLAKE2b-256 07fc5d0c420993f02e0f19059829bfaf3a3eedf10dc6bd4513ba2a62bd8ecbb8

See more details on using hashes here.

File details

Details for the file swarmauri_tokens_composite-0.3.0.dev51-py3-none-any.whl.

File metadata

  • Download URL: swarmauri_tokens_composite-0.3.0.dev51-py3-none-any.whl
  • Upload date:
  • Size: 11.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","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_tokens_composite-0.3.0.dev51-py3-none-any.whl
Algorithm Hash digest
SHA256 883004c223cf7db840d81bf5eb993b7c2a1cd32f65ed51406de8e3a9a0ca3341
MD5 fe0eb8a2b656ecf8e42d32e4dc862c9a
BLAKE2b-256 6f8b36b99cf8a12617a7a399ae7c1bebc7ab5ed20544690a0b340446c7a11f0b

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