Algorithm-routing token service for Swarmauri
Project description
Swarmauri Token Composite
Algorithm-routing token service delegating to child providers based on JWT headers, claims, or algorithms.
Features
- Compose multiple asynchronous
ITokenServiceimplementations behind a singleCompositeTokenServicefacade. - 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
kidso 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
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_tokens_composite-0.3.0.dev48.tar.gz.
File metadata
- Download URL: swarmauri_tokens_composite-0.3.0.dev48.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62679702b5b92a439b2f32f3f4d8240061e6a538818f70b09732a37a9617f14a
|
|
| MD5 |
7abd390752ed46636f6623bf6969e074
|
|
| BLAKE2b-256 |
623f441fef8e5df3a53d44cd95ffdbf343a7c70f7cfbb21f03022ea7f9f1fdc7
|
File details
Details for the file swarmauri_tokens_composite-0.3.0.dev48-py3-none-any.whl.
File metadata
- Download URL: swarmauri_tokens_composite-0.3.0.dev48-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95852b9fa642335cb3e46366a5a90b97aaf085e2822107568a0df5f0f516bc98
|
|
| MD5 |
4b98ab70b919d3ae0f2bf8cf85d7f004
|
|
| BLAKE2b-256 |
50619f954d0665a0890405f3054bb0caeee801b58a409c631a7a78dddf04d19e
|