Remote OIDC token verification service
Project description
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
cborextra. - Manual refresh hook for cache priming plus a
jwks()helper for introspection. - Verification-only surface:
mint()deliberately raisesNotImplementedError.
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
- Provide the expected OIDC issuer URL. Optionally override
jwks_urlto skip discovery when you already know the JWKS endpoint. - Call
refresh()to prime caches when your process boots or after a rotation signal. - 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
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_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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83307d5fb6a0effb3d13687447e4517d19d426faddf1ed5bdcc6fb938ef8cc49
|
|
| MD5 |
0cbff612d90d33e9cfa5076d01b4178d
|
|
| BLAKE2b-256 |
0e47daab2ddd45e731fe4b27040415e07695886e12af0f2a6f5d6bd224c2e91e
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd9ab6a3ed1c6d6337597a25e01316ab07dc55ad8546e270c56fab7cb3d5854f
|
|
| MD5 |
0949d5097c48bc9c286b280aeadfb11b
|
|
| BLAKE2b-256 |
9263e31a0dc84422433978e816436aaa20924f5ee21f92c3d0d8afd6b4654f68
|