Skip to main content

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
  • localstack CLI
  • make

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 with LOCALSTACK_ (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

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)

Source distribution for localstack-keycloak 0.1.0
File Size Uploaded
localstack_keycloak-0.1.0.tar.gz 11.1 kB Details

Built distribution (wheel)

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

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

Release history Release notifications | RSS feed

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