Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Swarmauri Logo

PyPI - Downloads Hits PyPI - Python Version PyPI - License PyPI - swarmauri_tokens_remoteoidc Discord

swarmauri_tokens_remoteoidc

Remote OIDC token verification service for Swarmauri.

This package provides a verification-only token service that retrieves JSON Web Key Sets (JWKS) from a remote OpenID Connect (OIDC) issuer and validates JWTs in accordance with RFC 7517 and RFC 7519. It implements ITokenService and exposes an entry point named RemoteOIDCTokenService.

Features

  • Remote OIDC discovery with JWKS caching and conditional revalidation (ETag / Last-Modified).
  • Audience and issuer validation with configurable clock-skew leeway.
  • Optional extras for additional canonicalisation formats via the cbor extra.
  • Manual refresh hook for cache priming plus a jwks() helper for introspection.
  • Verification-only surface: mint() deliberately raises NotImplementedError.

Installation

pip

pip install swarmauri_tokens_remoteoidc

Poetry

poetry add swarmauri_tokens_remoteoidc

uv

uv add swarmauri_tokens_remoteoidc

Install the optional CBOR canonicalisation helpers with the cbor extra if needed:

pip install swarmauri_tokens_remoteoidc[cbor]
poetry add --extras cbor swarmauri_tokens_remoteoidc
uv add swarmauri_tokens_remoteoidc[cbor]

Usage

  1. Provide the expected OIDC issuer URL. Optionally override jwks_url to skip discovery when you already know the JWKS endpoint.
  2. Call refresh() to prime caches when your process boots or after a rotation signal.
  3. Await verify() with the JWT to validate signatures, issuer, and optional audience or nonce constraints.

Example

The snippet below boots a minimal HTTP server that hosts a JWKS containing a symmetric key. It then mints a short-lived HS256 token and verifies it using RemoteOIDCTokenService.

import asyncio
import json
import threading
import time
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

import jwt
from jwt.utils import base64url_encode

from swarmauri_tokens_remoteoidc import RemoteOIDCTokenService

SECRET = b"super-secret-key"
KEY_ID = "demo-key"


def make_handler(jwks: dict):
    class Handler(BaseHTTPRequestHandler):
        def do_GET(self):
            if self.path != "/jwks.json":
                self.send_response(404)
                self.end_headers()
                return

            body = json.dumps(jwks).encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "application/json")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)

        def log_message(self, format, *args):  # pragma: no cover - quiet server
            return

    return Handler


async def main() -> None:
    jwks = {
        "keys": [
            {
                "kty": "oct",
                "kid": KEY_ID,
                "k": base64url_encode(SECRET).decode("ascii"),
                "alg": "HS256",
            }
        ]
    }

    server = ThreadingHTTPServer(("127.0.0.1", 0), make_handler(jwks))
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()

    try:
        issuer = "https://issuer.example.com"
        jwks_url = f"http://127.0.0.1:{server.server_address[1]}/jwks.json"

        service = RemoteOIDCTokenService(
            issuer=issuer,
            jwks_url=jwks_url,
            expected_alg_whitelist=("HS256",),
        )

        now = int(time.time())
        token = jwt.encode(
            {
                "iss": issuer,
                "aud": "my-audience",
                "sub": "user-123",
                "iat": now,
                "exp": now + 60,
            },
            SECRET,
            algorithm="HS256",
            headers={"kid": KEY_ID},
        )

        service.refresh(force=True)
        claims = await service.verify(token, audience="my-audience")
        print(f"Verified subject: {claims['sub']}")
    finally:
        server.shutdown()
        thread.join()


if __name__ == "__main__":
    asyncio.run(main())

The service performs JWKS discovery or fetch, validates the token signature and issuer, and returns the decoded claims when verification succeeds. Cache entries refresh automatically based on cache_ttl_s or manually via refresh(force=True).

Want to help?

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

Metadata

Release files for swarmauri_tokens_remoteoidc 0.11.0.dev1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for swarmauri_tokens_remoteoidc 0.11.0.dev1
File Size Uploaded
swarmauri_tokens_remoteoidc-0.11.0.dev1.tar.gz 11.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for swarmauri_tokens_remoteoidc 0.11.0.dev1
File Interpreter ABI Platform
swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl Python 3 none any Details

Total release size: 23.3 kB

Release files / swarmauri_tokens_remoteoidc-0.11.0.dev1.tar.gz

Download URL swarmauri_tokens_remoteoidc-0.11.0.dev1.tar.gz
Size 11.0 kB
Tags Source
SHA-256 checksum
How to use checksums
418a6a2e2a8eec748089bcfbabcc2029a4e5ac63b3fb90edc3c129bb73261568
BLAKE2b-256 checksum
How to use checksums
fb706d700f26177bd0e139840a1641bc620b242326af051306cb7da5bcb10e1f
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl

Download URL swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl
Size 12.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
950b99f62aeca37c39ed444bc4194ac9f623943287250846760153b4d0b55d83
BLAKE2b-256 checksum
How to use checksums
e21f8b84c32a407a9c6756bb1032c7b4c74fdb6482f11c7c3257e3880d092f34
Upload date
Uploaded using Trusted Publishing?
What is 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}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page