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


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.3.0.dev32.tar.gz (10.9 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.3.0.dev32.tar.gz.

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.3.0.dev32.tar.gz
  • Upload date:
  • Size: 10.9 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_tokens_remoteoidc-0.3.0.dev32.tar.gz
Algorithm Hash digest
SHA256 83307d5fb6a0effb3d13687447e4517d19d426faddf1ed5bdcc6fb938ef8cc49
MD5 0cbff612d90d33e9cfa5076d01b4178d
BLAKE2b-256 0e47daab2ddd45e731fe4b27040415e07695886e12af0f2a6f5d6bd224c2e91e

See more details on using hashes here.

File details

Details for the file swarmauri_tokens_remoteoidc-0.3.0.dev32-py3-none-any.whl.

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.3.0.dev32-py3-none-any.whl
  • Upload date:
  • Size: 12.2 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_tokens_remoteoidc-0.3.0.dev32-py3-none-any.whl
Algorithm Hash digest
SHA256 fd9ab6a3ed1c6d6337597a25e01316ab07dc55ad8546e270c56fab7cb3d5854f
MD5 0949d5097c48bc9c286b280aeadfb11b
BLAKE2b-256 9263e31a0dc84422433978e816436aaa20924f5ee21f92c3d0d8afd6b4654f68

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