Skip to main content

Remote OIDC token verification service

Project description

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.

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_remoteoidc-0.11.0.dev1.tar.gz (11.0 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_remoteoidc-0.11.0.dev1.tar.gz.

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.11.0.dev1.tar.gz
  • Upload date:
  • Size: 11.0 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

Hashes for swarmauri_tokens_remoteoidc-0.11.0.dev1.tar.gz
Algorithm Hash digest
SHA256 418a6a2e2a8eec748089bcfbabcc2029a4e5ac63b3fb90edc3c129bb73261568
MD5 6fd29930b1c4ded4808aa98872531b76
BLAKE2b-256 fb706d700f26177bd0e139840a1641bc620b242326af051306cb7da5bcb10e1f

See more details on using hashes here.

File details

Details for the file swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl.

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl
  • Upload date:
  • Size: 12.3 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

Hashes for swarmauri_tokens_remoteoidc-0.11.0.dev1-py3-none-any.whl
Algorithm Hash digest
SHA256 950b99f62aeca37c39ed444bc4194ac9f623943287250846760153b4d0b55d83
MD5 7dd72028344d3159cc384c9fee691a7c
BLAKE2b-256 e21f8b84c32a407a9c6756bb1032c7b4c74fdb6482f11c7c3257e3880d092f34

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