Keycloak on LocalStack
This repo contains a LocalStack Extension that runs Keycloak alongside LocalStack for identity and access management with local AWS applications.
This Extension:
- Spins up a Keycloak instance on LocalStack startup.
- Auto-registers Keycloak as an OIDC identity provider in LocalStack IAM.
- Ships with a default realm (
localstack) ready for OAuth2/OIDC flows. - Exchanges Keycloak JWTs for temporary AWS credentials via
AssumeRoleWithWebIdentity.
Prerequisites
- Docker
- LocalStack Pro
localstackCLImake
Installation
localstack extensions install "git+https://github.com/localstack/localstack-extensions.git#egg=localstack-keycloak&subdirectory=keycloak"
Install local development version
To install the extension into LocalStack in developer mode, you will need Python 3.11, and create a virtual environment in the extensions project.
make install
Then, to enable the extension for LocalStack, run
localstack extensions dev enable .
You can then start LocalStack with EXTENSION_DEV_MODE=1 to load all enabled extensions:
EXTENSION_DEV_MODE=1 localstack start
Usage
Start LocalStack:
localstack start
Keycloak will be available at:
| Endpoint | URL |
|---|---|
| Admin Console | http://localhost:8080/admin |
| Token Endpoint | http://keycloak.localhost.localstack.cloud:4566/realms/localstack/protocol/openid-connect/token |
| JWKS URL | http://keycloak.localhost.localstack.cloud:4566/realms/localstack/protocol/openid-connect/certs |
Keycloak ports are exposed directly on the host for easy access:
- Admin Console & HTTP (8080):
http://localhost:8080- Use this for the admin UI and direct API access - Management (9000):
http://localhost:9000- Health and metrics endpoints (Keycloak 26+)
The gateway URL (keycloak.localhost.localstack.cloud:4566) is available for token endpoints and OIDC flows.
- Default Admin Credentials:
admin/admin - Health check:
curl http://localhost:9000/health/ready
Get an Access Token
TOKEN=$(curl -s -X POST \
"http://keycloak.localhost.localstack.cloud:4566/realms/localstack/protocol/openid-connect/token" \
-d "grant_type=client_credentials" \
-d "client_id=localstack-client" \
-d "client_secret=localstack-client-secret" | jq -r '.access_token')
Exchange Token for AWS Credentials
# Create IAM role that trusts Keycloak
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::000000000000:oidc-provider/keycloak.localhost.localstack.cloud:4566/realms/localstack"
},
"Action": "sts:AssumeRoleWithWebIdentity"
}]
}
EOF
awslocal iam create-role \
--role-name KeycloakAuthRole \
--assume-role-policy-document file://trust-policy.json
# Exchange Keycloak token for AWS credentials
awslocal sts assume-role-with-web-identity \
--role-arn arn:aws:iam::000000000000:role/KeycloakAuthRole \
--role-session-name test-session \
--web-identity-token "$TOKEN"
Configuration
| Environment Variable | Default | Description |
|---|---|---|
KEYCLOAK_REALM |
localstack |
Name of the default realm |
KEYCLOAK_VERSION |
26.0 |
Keycloak Docker image version |
KEYCLOAK_REALM_FILE |
- | Path to custom realm JSON file |
KEYCLOAK_DEFAULT_USER |
- | Username for auto-created test user |
KEYCLOAK_DEFAULT_PASSWORD |
- | Password for auto-created test user |
KEYCLOAK_OIDC_AUDIENCE |
localstack-client |
Audience claim for OIDC provider |
KEYCLOAK_FLAGS |
- | Additional flags for Keycloak start command |
Note: When using
localstack start, prefix environment variables withLOCALSTACK_(e.g.,LOCALSTACK_KEYCLOAK_REALM).
Custom Realm Configuration
Use your own realm JSON file with pre-configured users, roles, and clients.
# The path must be an absolute HOST path for Docker mount
# Use LOCALSTACK_ prefix when running via CLI
LOCALSTACK_KEYCLOAK_REALM_FILE=/path/to/my-realm.json localstack start
See quickstart/sample-realm.json for a realm template and quickstart/README.md for a step-by-step guide.
Create Test Users
# Auto-create a test user on startup (use LOCALSTACK_ prefix with CLI)
LOCALSTACK_KEYCLOAK_DEFAULT_USER=testuser LOCALSTACK_KEYCLOAK_DEFAULT_PASSWORD=password123 localstack start
Default Client
The extension creates a default client localstack-client with:
- Client Secret:
localstack-client-secret - Flows: Authorization Code, Client Credentials, Direct Access Grants
- Service Account Roles:
admin,user
The service account for localstack-client is automatically assigned the admin realm role, enabling full access when using client credentials flow.
Sample Application
See the sample-app/ directory for a complete example demonstrating:
- API Gateway with Lambda Authorizer
- JWT validation with Keycloak
- Role-based access control
- DynamoDB user management
Troubleshooting
Keycloak takes a long time to start
Keycloak typically takes 30-60 seconds to fully start. The extension waits for the health check to pass before marking LocalStack as ready.
Health check endpoint returns 404
In Keycloak 26+, the health endpoint is on port 9000:
curl http://localhost:9000/health/ready
View Keycloak logs
docker logs ls-ext-keycloak
Development
# Install dependencies
make install
# Run tests (requires LocalStack with extension running)
make test
# Format code
make format
# Lint
make lint
License
Apache License 2.0
Metadata
Release files for localstack-keycloak 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| localstack_keycloak-0.1.0.tar.gz | 11.1 kB | Without provenance | Details for localstack_keycloak-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| localstack_keycloak-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for localstack_keycloak-0.1.0-py3-none-any.whl |
Total release size: 19.3 kB
Release files / localstack_keycloak-0.1.0.tar.gz
| Download URL | localstack_keycloak-0.1.0.tar.gz |
|---|---|
| Size | 11.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de4772ca75c4c523020f76c776fb38eec29e4f6ec298677e8071fb07a3f42014
|
|
BLAKE2b-256 checksum How to use checksums |
c063ad0a626f242b0c75b31ab3d21bde71c157ac6b46d8718b74d398e78157b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / localstack_keycloak-0.1.0-py3-none-any.whl
| Download URL | localstack_keycloak-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d68dc07abf73b501313ebb467dd955c0f84438be091c765c66ed14e23e8f1d14
|
|
BLAKE2b-256 checksum How to use checksums |
b4064754afcf12b449852cf96ef48c74bcea61082d95686e419ea98fd53e08c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Security for localstack-keycloak 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.