Keycloak SDK for Python — auth (OIDC/OAuth2) + Admin REST API, wrapping python-keycloak
Project description
Keycloak SDK for Python
Authentication (OIDC / OAuth2) and the Admin REST API for Keycloak behind one consistent facade, with hardened JWT validation and a full async mirror.
English · 한국어
Part of a nine-language polyglot SDK (Java · Python · Node · Go · C# · PHP · Rust · Ruby · Kotlin) — one API surface, isomorphic across all of them: github.com/xzawed/KeyCloakSDK.
Pre-release — not yet published to PyPI.
Requirements
- Python 3.10+
- Ships the PEP 561
py.typedmarker, so consumers can type-check withmypytoo
Install
pip install keycloak-sdk
The distribution name is keycloak-sdk; the import package is keycloak_sdk.
Quickstart
from keycloak_sdk import KeycloakClient, KeycloakConfig
config = KeycloakConfig(
server_url="https://kc.example.com",
realm="myrealm",
client_id="admin-cli",
client_secret="changeme", # load the real value from an env var / secrets manager
)
# The `with` block cleans up the admin and auth sessions on exit.
with KeycloakClient.create(config) as kc:
# 1) Issue a client-credentials token. repr(TokenSet) masks every token value.
token = kc.auth.client_credentials_token()
# 2) Validate it — algorithm pinning, exact iss, aud containment, mandatory exp, clock skew.
validated = kc.auth.validate(token.access_token)
print(f"subject={validated.subject} aud={validated.audience}")
# 3) Admin API — admin is created lazily on first access. create() returns the new user id.
user_id = kc.admin.users.create({"username": "alice", "enabled": True})
users = kc.admin.users.search(first=0, max=20)
validate() expects the token's aud to contain client_id by default, but a stock realm does not put the client id into a client-credentials token. Either set expected_audience="my-api" on the config to check the audience your tokens actually carry, or add an audience mapper to the client in Keycloak (Client scopes → dedicated scope → Add mapper → Audience).
Async
keycloak_sdk.aio is a complete async mirror — same method names, value types, and exceptions — so it never blocks the event loop (FastAPI and friends):
from keycloak_sdk import KeycloakConfig
from keycloak_sdk.aio import AsyncKeycloakClient
async def handler(config: KeycloakConfig) -> None:
async with AsyncKeycloakClient.create(config) as kc:
token = await kc.auth.client_credentials_token()
validated = await kc.auth.validate(token.access_token)
users = await kc.admin.users.search(first=0, max=20)
Only authorization_url stays synchronous — it assembles a URL and needs no network.
Security defaults
The SDK replaces the unsafe library defaults rather than inheriting them:
- Algorithm pinning — the header-supplied
algis never trusted, soalg: noneand HS/RS confusion are rejected structurally: joserfc decodes against the configured allowlist, and an empty allowlist is refused at construction rather than falling back to joserfc's permissive default set. - Strict claim checks — exact
issmatch,audcontainment, mandatoryexp,nbf, and a bounded clock skew. - DoS-safe JWKS — a refetch is triggered only by an unresolved key ID and never by a bad signature, and is rate-limited to a minimum interval (
jwks_min_refetch_seconds, 30s by default) — so no volume of forged tokens makes the SDK issue more than one JWKS request per interval. - Secret handling —
repr()of the config and token types masks secrets and tokens as***(no prefix leak), and TLS verification is on by default.
Masking covers this SDK's own repr(); it cannot cover what your logging framework or a traceback does with a value you hand it. Python has no erasable string type, so the client secret lives in an ordinary str for its lifetime — masking is defence in depth, not an erasure guarantee.
Versioning and support
This SDK is pre-1.0. Under SemVer a 0.x minor bump may carry breaking changes, so read the release notes before upgrading. Only the newest released version of each language SDK receives security fixes — there are no LTS lines, and older 0.x releases are not backported to. Full policy: SECURITY.md.
Documentation
- Getting started — install, quickstart, async, and the compatibility matrix
- Deploying a Keycloak server — the server this SDK talks to
- Security policy
- Full examples:
quickstart.py·async_quickstart.py
License
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 keycloak_sdk-0.1.0rc1.tar.gz.
File metadata
- Download URL: keycloak_sdk-0.1.0rc1.tar.gz
- Upload date:
- Size: 65.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3f0641529f80d1dc2d9b4edb1e463a805768e16c5e0eb045c12e1470922007d
|
|
| MD5 |
355bf3652bd8187264f24c63698d5d74
|
|
| BLAKE2b-256 |
54f4c515d2f31f7564f1d54789583001c5c1e3e0b4922355cc118209d8717485
|
Provenance
The following attestation bundles were made for keycloak_sdk-0.1.0rc1.tar.gz:
Publisher:
python-release.yml on xzawed/KeyCloakSDK
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keycloak_sdk-0.1.0rc1.tar.gz -
Subject digest:
f3f0641529f80d1dc2d9b4edb1e463a805768e16c5e0eb045c12e1470922007d - Sigstore transparency entry: 2317519299
- Sigstore integration time:
-
Permalink:
xzawed/KeyCloakSDK@f52e2174d56b8d5caac80ac7c910afcf86d716b3 -
Branch / Tag:
refs/tags/py-v0.1.0rc1 - Owner: https://github.com/xzawed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-release.yml@f52e2174d56b8d5caac80ac7c910afcf86d716b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file keycloak_sdk-0.1.0rc1-py3-none-any.whl.
File metadata
- Download URL: keycloak_sdk-0.1.0rc1-py3-none-any.whl
- Upload date:
- Size: 46.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
163a0cd707249e48d9ae402cbb44c3ae57d4c210524602ce1683bf14b10b774c
|
|
| MD5 |
7f6fcf10618c91e485515d900d981bd3
|
|
| BLAKE2b-256 |
292734aff91ebbc55663ce66a0696f434248bb29db385e0fead0257f2a552ccc
|
Provenance
The following attestation bundles were made for keycloak_sdk-0.1.0rc1-py3-none-any.whl:
Publisher:
python-release.yml on xzawed/KeyCloakSDK
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keycloak_sdk-0.1.0rc1-py3-none-any.whl -
Subject digest:
163a0cd707249e48d9ae402cbb44c3ae57d4c210524602ce1683bf14b10b774c - Sigstore transparency entry: 2317519519
- Sigstore integration time:
-
Permalink:
xzawed/KeyCloakSDK@f52e2174d56b8d5caac80ac7c910afcf86d716b3 -
Branch / Tag:
refs/tags/py-v0.1.0rc1 - Owner: https://github.com/xzawed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-release.yml@f52e2174d56b8d5caac80ac7c910afcf86d716b3 -
Trigger Event:
push
-
Statement type: