Skip to main content

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.

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 — the first release candidate (0.1.0rc1) is on PyPI; there is no stable release yet. Note that a bare pip install keycloak-sdk currently resolves this RC, because pip falls back to pre-releases when only pre-releases exist.

Requirements

  • Python 3.10+
  • Ships the PEP 561 py.typed marker, so consumers can type-check with mypy too

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 alg is never trusted, so alg: none and 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 iss match, aud containment, mandatory exp, 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

License

Apache-2.0

Release files for keycloak-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keycloak-sdk 0.1.0
File Size Uploaded
keycloak_sdk-0.1.0.tar.gz 67.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for keycloak-sdk 0.1.0
File Interpreter ABI Platform
keycloak_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 115.5 kB

Release files / keycloak_sdk-0.1.0.tar.gz

Download URL keycloak_sdk-0.1.0.tar.gz
Size 67.1 kB
Tags Source
SHA-256 checksum
How to use checksums
c401c5edc2e98d1c830b46aa4f23f0c5d78f2e7109636e96f4a8e5fc1477f94b
BLAKE2b-256 checksum
How to use checksums
767cfbc21711ed92fcc54ec8ad3a338a7186053f98bc5771d3b77bb7985ee5bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / keycloak_sdk-0.1.0-py3-none-any.whl

Download URL keycloak_sdk-0.1.0-py3-none-any.whl
Size 48.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
419844b9ee43b15f6283899a51e2a0d672bcc670d25702554c5cc2d94ce788fb
BLAKE2b-256 checksum
How to use checksums
48212f624448fd1e741d0d9bd518f7f3e7747e53c2e01258aa68806c53dee694
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.1

2 release files

1.0.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page