Skip to main content

caselaw-auth-server

Server-side OIDC for Python products, interchangeable with the caselaw-auth npm package's /server entry point.

A session cookie sealed by either implementation unseals in the other, byte for byte. Both are written against packages/contract/contract.json, and both load packages/contract/conformance/cases.json at test time — which is what keeps them from drifting.

pip install caselaw-auth-server

Why

caselaw-auth/server is TypeScript, and half this estate is not: caselaw-access is FastAPI and citations-api is a Python HTTP server. Without a Python implementation, those two would have stayed on browser-side sessions purely because of the language their backend happens to be written in — with the refresh token in localStorage, where page script can read it.

Usage

from caselaw_auth_server import create_server_auth, create_pkce_pair, random_token

auth = create_server_auth(
    issuer=os.environ["AUTH_ISSUER"],              # .../realms/caselaw
    client_id=os.environ["AUTH_CLIENT_ID"],
    redirect_uri=os.environ["AUTH_REDIRECT_URI"],
    session_secret=os.environ["AUTH_SESSION_SECRET"],
    client_secret=os.environ.get("AUTH_CLIENT_SECRET"),   # confidential clients
)

Start a sign-in:

verifier, challenge = create_pkce_pair()
state = random_token()
# state and verifier must survive the round trip and stay unreadable by page
# script — a short httpOnly cookie, not anything the browser can see.
url = auth.authorization_url(state=state, code_challenge=challenge)

Complete it:

tokens = auth.exchange_code(code=code, code_verifier=verifier)
claims = auth.verify_token(tokens["access_token"])
session = auth.session_from_claims(claims, id_token=tokens.get("id_token"))
cookie = auth.seal_session(session)

Read it on any request — an HMAC check, no network call:

session = auth.unseal_session(request.cookies.get("caselaw_session"))
if not session or "admin" not in session["roles"]:
    raise Forbidden()

End it. id_token_hint is what makes this a real single sign-out:

auth.end_session_url(id_token=session.get("idToken"), return_to=site)

Mapping to the TypeScript package

Method names are idiomatic per language. Session keys are camelCase in both, because they are wire format rather than API surface: renaming them per language would break the property the whole contract exists to guarantee.

TypeScript Python
createServerAuth(config) create_server_auth(...)
authorizationUrl(options) authorization_url(...)
exchangeCode(options) exchange_code(...)
verifyToken(token, options) verify_token(token, ...)
rolesFromClaims(claims) roles_from_claims(claims)
sessionFromClaims(claims, options) session_from_claims(claims, ...)
sealSession(session, name) seal_session(session, name)
unsealSession(value) unseal_session(value)
cookieOptions(maxAge, options) cookie_options(max_age, ...)
endSessionUrl(options) end_session_url(...)
createPkcePair() create_pkce_pair()

Errors are typed here rather than string-matched: InvalidToken, AuthBackendUnavailable and SessionTooLarge, all under AuthError. The split between the first two is deliberate — collapsing them sends users to re-authenticate during an outage, which cannot help and doubles the load on the thing already failing.

Behaviour worth knowing

  • session_from_claims does not keep the access token. Where one is genuinely needed, put it in a cookie of its own; a token in a cookie leaks with the cookie.
  • The session carries its own TTL, not the token's few minutes.
  • seal_session raises above 4096 bytes rather than returning a cookie the browser will silently discard.
  • verify_token does not check aud by default. Keycloak puts account there for a public client's access token and names the client in azp.
  • JWKS is cached and retried once; a token that is itself invalid is never retried.

Tests

pip install -e ".[dev]"
pytest

The suite loads the shared conformance cases by relative path. Running it from a checkout of this repository is therefore required — the cases are not vendored into the package.

Related

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

caselaw_auth_server-0.1.0.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

caselaw_auth_server-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file caselaw_auth_server-0.1.0.tar.gz.

File metadata

  • Download URL: caselaw_auth_server-0.1.0.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for caselaw_auth_server-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c632be82d940f43b65dd47ff78111f7cdf5fba670bcbcf5ba0fbf1854c79e9d6
MD5 d5b0f8b4c14e41f0b43d3a1a8f09075b
BLAKE2b-256 4fb5358075fbf6001e35b9f6c159cd1f99a61d437bd4c272f65c2b6786a2a94d

See more details on using hashes here.

Provenance

The following attestation bundles were made for caselaw_auth_server-0.1.0.tar.gz:

Publisher: publish-python.yml on MaastrichtU-BISS/caselaw-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file caselaw_auth_server-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for caselaw_auth_server-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 25626d9d3f89f5c39af9ded798196ec34175068ea8af035187612a350bdc8b38
MD5 5c8fb90393ccb25e47a4f055eac111d9
BLAKE2b-256 df76af05f5b3262f04280351d744ab7c39e6cc6c57f760108d9fea411c5e1d52

See more details on using hashes here.

Provenance

The following attestation bundles were made for caselaw_auth_server-0.1.0-py3-none-any.whl:

Publisher: publish-python.yml on MaastrichtU-BISS/caselaw-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

2 files

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page