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.dev51.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.dev51.tar.gz.

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.3.0.dev51.tar.gz
  • Upload date:
  • Size: 10.9 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_remoteoidc-0.3.0.dev51.tar.gz
Algorithm Hash digest
SHA256 45466ce80f4f8feefa48831a029a82669131406ff77224a6d56515e2ec7b1ce3
MD5 22b5b656e58089b4e47ce48b89e6c28e
BLAKE2b-256 31f2ccff5f31987f718d45f98a60bdd002c16096cffa9076364ac86e2ef05a34

See more details on using hashes here.

File details

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

File metadata

  • Download URL: swarmauri_tokens_remoteoidc-0.3.0.dev51-py3-none-any.whl
  • Upload date:
  • Size: 12.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_remoteoidc-0.3.0.dev51-py3-none-any.whl
Algorithm Hash digest
SHA256 9db38f6704dc8d0d5d14a2ca37c6723f494e2f3474038b99015e67101329dabb
MD5 7dda632fffbeee04cc7e0c8ca636292f
BLAKE2b-256 d1ab74b84411f9e7fd6ef8dab6331c03e45a1115a0da22bf6a7f3cbb089f7e15

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