A minimal Keycloak-compatible OIDC/OAuth2 mock server
Project description
Keycloak Mockup
Keycloak Mockup is a lightweight Keycloak-compatible OIDC/OAuth2 mock server for local development, integration testing, and CI pipelines.
It provides a fake identity provider with configurable users, roles, JWT claims, JWKS, login page, token endpoint, userinfo endpoint, logout endpoint, and a built-in browser demo client for testing authentication flows.
By default, no runtime options are required:
- the built-in
config.yamlis used automatically - the demo client is served at
/ - the server listens on port
5151
⚠️ Keycloak Mockup is intended for development and testing only. Do not use it in production.
Main use cases
- Run a local Keycloak-like identity provider without installing Keycloak.
- Test backend services that expect OIDC/OAuth2 and JWT tokens.
- Test browser clients using the Keycloak JavaScript adapter.
- Provide deterministic users and roles in CI/integration tests.
- Inspect issued tokens and userinfo data through the built-in demo client.
Quick start with Docker Compose
Create docker-compose.yml:
services:
keycloak-mockup:
image: ghcr.io/calcite/keycloak-mockup:latest
ports:
- "5151:5151"
Start the service:
docker compose up
Open:
- Demo client: http://localhost:5151/
- OIDC discovery: http://localhost:5151/realms/myrealm/.well-known/openid-configuration
The demo client lets you click Login, authenticate against Keycloak Mockup, and inspect the data returned to the browser client: parsed token claims, raw tokens, adapter state, and userinfo response.
Default users are defined in the packaged config.yaml, for example:
admin/admin123operator/operator123viewer/viewer123
Docker Compose with a custom config
To customize users, roles, realm, client ID, token TTLs, or advertised base URL, mount your own config file:
cp src/keycloak_mockup/config.example.yaml ./config.yaml
services:
keycloak-mockup:
image: ghcr.io/calcite/keycloak-mockup:latest
ports:
- "5151:5151"
volumes:
- ./config.yaml:/config.yaml:ro
command: ["keycloak-mockup", "--config", "/config.yaml"]
Docker Compose with /demo-client/ path
The demo client is mounted at / by default. To move it to /demo-client/:
services:
keycloak-mockup:
image: ghcr.io/calcite/keycloak-mockup:latest
ports:
- "5151:5151"
environment:
DEMO_CLIENT_PATH: "/demo-client/"
Then open:
Install with pip
Install from PyPI:
pip install keycloak-mockup
Run with the packaged default config:
keycloak-mockup
Open:
Install from a local checkout:
pip install .
keycloak-mockup
Run as a Python module:
python -m keycloak_mockup
Use a custom config when needed:
keycloak-mockup --config ./config.yaml
Configuration
Runtime behavior is controlled by a YAML or JSON config file. If --config is omitted, the packaged config.yaml is used.
Minimal example:
realm: myrealm
client_id: myclient
host: "0.0.0.0"
port: 5151
base_url: "http://localhost:5151"
insecure_cookies: true
users:
- username: admin
password: admin123
email: admin@example.com
name: Admin User
enabled: true
autologin: true
realm_roles:
- ADMIN
client_roles:
myclient:
- admin
See the full reference in docs/configuration.md.
Built-in demo client
The app includes a static browser demo client based on the Keycloak JavaScript adapter.
Default URL:
http://localhost:5151/
Optional path override:
DEMO_CLIENT_PATH=/demo-client/ keycloak-mockup
The page supports:
- Login redirect through Keycloak Mockup
- Logout
- Token refresh
- Userinfo reload
- Displaying parsed token claims
- Displaying raw access/refresh/ID tokens when available
- Displaying adapter state and selected client configuration
The demo client displays sensitive token data in the browser. Use it only for local development and testing.
Main endpoints
- OIDC discovery:
/realms/{realm}/.well-known/openid-configuration - Realm info:
/realms/{realm} - Authorization:
/realms/{realm}/protocol/openid-connect/auth - Token:
/realms/{realm}/protocol/openid-connect/token - Userinfo:
/realms/{realm}/protocol/openid-connect/userinfo - Logout:
/realms/{realm}/protocol/openid-connect/logout - JWKS:
/realms/{realm}/protocol/openid-connect/certs
Supported flows
- Authorization Code flow
- Refresh token flow with rotation
- Client Credentials flow
- Browser login with session cookie
- Silent SSO support for Keycloak JS testing
Example access token payload
{
"iss": "http://localhost:5151/realms/myrealm",
"sub": "a1b2c3d4-...",
"aud": "myclient",
"email": "admin@example.com",
"name": "Admin User",
"preferred_username": "admin",
"realm_access": { "roles": ["ADMIN"] },
"resource_access": {
"myclient": { "roles": ["admin"] }
}
}
Client examples
Development with pip
The project uses standard Python packaging and plain pip; PDM is not required.
Create a virtual environment and install the package with development dependencies:
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
Run tests:
pytest -q
Build the Python package and Docker image locally:
python -m pip install build
python -m build
docker build -t keycloak-mockup .
Release
A release is created by pushing a version tag such as v0.1.0:
git tag v0.1.0
git push origin v0.1.0
The GitHub Actions release workflow will:
- build the Python source distribution and wheel
- upload the Python package to PyPI
- build a Docker image from the generated wheel
- push the Docker image to this repository's GitHub Container Registry package (
ghcr.io/<owner>/<repo>) - create a GitHub Release with the Python artifacts attached
Required GitHub/PyPI setup:
- Configure PyPI Trusted Publishing for this project on
pypi.org. - In PyPI, add this GitHub repository as a trusted publisher for workflow
.github/workflows/release.yml. - No
PYPI_API_TOKENsecret is required; the workflow publishes with GitHub OIDC viapypa/gh-action-pypi-publish. - Ensure workflow permissions allow package publishing. In GitHub repository settings, enable Actions → General → Workflow permissions → Read and write permissions if needed.
- The workflow uses
GITHUB_TOKENfor GitHub Releases and GHCR publishing; no extra GHCR token should be needed for the same repository.
License
MIT License — see 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_mockup-0.1.0.post1.dev0.tar.gz.
File metadata
- Download URL: keycloak_mockup-0.1.0.post1.dev0.tar.gz
- Upload date:
- Size: 419.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d5616702d762afced884099a5aa40547255c5895f1949bbda5a6e42f5e26022
|
|
| MD5 |
d740c486bfb5ff032203fd7a1a12b77b
|
|
| BLAKE2b-256 |
b803bbc066108e264d652cbf16ee1756c8d04d410b803c1bc3891af4fd31dad7
|
Provenance
The following attestation bundles were made for keycloak_mockup-0.1.0.post1.dev0.tar.gz:
Publisher:
release.yml on calcite/keycloak-mockup
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keycloak_mockup-0.1.0.post1.dev0.tar.gz -
Subject digest:
0d5616702d762afced884099a5aa40547255c5895f1949bbda5a6e42f5e26022 - Sigstore transparency entry: 1859656724
- Sigstore integration time:
-
Permalink:
calcite/keycloak-mockup@3091c759801eb732ccde28f50be28e6febe152f0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/calcite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3091c759801eb732ccde28f50be28e6febe152f0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file keycloak_mockup-0.1.0.post1.dev0-py3-none-any.whl.
File metadata
- Download URL: keycloak_mockup-0.1.0.post1.dev0-py3-none-any.whl
- Upload date:
- Size: 39.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da78a72d153f4ae92e273d19073ba42dc53a6139c6a0139665972127360d8fc7
|
|
| MD5 |
7fe3e01246a43b950ea6d81aef7e5a1c
|
|
| BLAKE2b-256 |
f38091d2eb075b9fb4599b6cdb38a5daff6f3497112564863c66294fc657dc0a
|
Provenance
The following attestation bundles were made for keycloak_mockup-0.1.0.post1.dev0-py3-none-any.whl:
Publisher:
release.yml on calcite/keycloak-mockup
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keycloak_mockup-0.1.0.post1.dev0-py3-none-any.whl -
Subject digest:
da78a72d153f4ae92e273d19073ba42dc53a6139c6a0139665972127360d8fc7 - Sigstore transparency entry: 1859656743
- Sigstore integration time:
-
Permalink:
calcite/keycloak-mockup@3091c759801eb732ccde28f50be28e6febe152f0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/calcite
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3091c759801eb732ccde28f50be28e6febe152f0 -
Trigger Event:
push
-
Statement type: