Skip to Content
IntegrationsKeycloak

Keycloak

KalamDB natively validates Keycloak RS256 tokens via OIDC discovery — no bridge service required.

Integration Model

KalamDB bearer token validation routes by algorithm:

  • HS256 with iss = "kalamdb" → internal shared-secret validation.
  • RS256 / ES256 / etc. from a trusted issuer → external OIDC discovery + JWKS validation.

Keycloak issues RS256 tokens by default, so KalamDB validates them directly when the issuer is trusted.

Supported algorithms: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384. ES512 is not supported.

Quick Start with Docker Compose

The KalamDB repository includes a Keycloak service in docker/utils/docker-compose.yml:

keycloak: image: quay.io/keycloak/keycloak:26.0 command: ["start-dev", "--import-realm"] environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin ports: - "8081:8080" volumes: - ./keycloak/realm-import:/opt/keycloak/data/import:ro - ./keycloak/data:/opt/keycloak/data

Start it:

docker compose up keycloak -d

Admin console: http://127.0.0.1:8081
Default credentials: admin / admin

Configure KalamDB

Step 1: Add Keycloak as a trusted issuer

The issuer URL format for Keycloak is https://<host>/realms/<realm>:

[authentication] jwt_trusted_issuers = "http://127.0.0.1:8081/realms/myrealm" auto_create_users_from_provider = true

Or via environment variables:

export KALAMDB_JWT_TRUSTED_ISSUERS="http://127.0.0.1:8081/realms/myrealm" export KALAMDB_AUTH_AUTO_CREATE_USERS_FROM_PROVIDER=true

To keep internal login working alongside Keycloak:

export KALAMDB_JWT_TRUSTED_ISSUERS="kalamdb,http://127.0.0.1:8081/realms/myrealm"

Step 2: Create a Keycloak client

In the Keycloak Admin Console:

  1. Select your realm (or create one).
  2. Go to ClientsCreate client.
  3. Set Client ID (e.g., kalamdb-app).
  4. Set Client authentication to On if using confidential clients; Off for public clients.
  5. Under Valid redirect URIs, add your app URL.
  6. Note the Client ID — this is used for audience validation.

Step 3: Create a user in Keycloak

  1. Go to UsersAdd user.
  2. Set username (e.g., alice).
  3. Under Credentials, set a password.
  4. Enable the user.

Step 4: Get a token and use it

# Get token via direct-access grant (for testing) KC_TOKEN=$(curl -s -X POST \ http://127.0.0.1:8081/realms/myrealm/protocol/openid-connect/token \ -d "client_id=kalamdb-app&grant_type=password&username=alice&password=secret" \ | jq -r .access_token) # Use it with KalamDB curl -X POST http://127.0.0.1:8080/v1/api/sql \ -H "Authorization: Bearer $KC_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"sql":"SELECT CURRENT_USER();"}'

How Validation Works

  1. KalamDB receives the Keycloak RS256 token.
  2. Extracts iss (e.g., http://127.0.0.1:8081/realms/myrealm) and confirms it is trusted.
  3. Fetches {iss}/.well-known/openid-configuration to discover the jwks_uri.
  4. Fetches the JWKS endpoint and caches keys by kid.
  5. Validates signature, issuer, and expiry.
  6. Maps preferred_username (Keycloak default) to KalamDB username.

JWKS Caching

  • Keys are cached per-issuer in memory.
  • Unknown kid → automatic JWKS refresh.
  • No TTL-based eviction — keys remain until a cache miss triggers refresh.
  • Keycloak key rotation is handled transparently.

Issuer URL Precision

The issuer URL must exactly match the iss claim in Keycloak tokens:

CorrectIncorrect
http://127.0.0.1:8081/realms/myrealmhttp://127.0.0.1:8081/realms/myrealm/ (trailing slash)
https://keycloak.example.com/realms/prodhttps://keycloak.example.com/ (missing realm)

Check the token iss claim: echo $KC_TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq .iss

Verification Checklist

  1. Confirm Keycloak realm issuer URL matches the token iss claim exactly.
  2. Add issuer to jwt_trusted_issuers.
  3. Restart KalamDB.
  4. Get a Keycloak token using direct-access grant or browser flow.
  5. Send it as Authorization: Bearer <token> to a KalamDB endpoint.
  6. Verify SELECT CURRENT_USER() returns the expected username.

Troubleshooting

SymptomCauseFix
401 UnauthorizedIssuer not trustedAdd exact issuer URL to jwt_trusted_issuers
DiscoveryFailedKalamDB cannot reach KeycloakCheck network/DNS, ensure /.well-known/openid-configuration is accessible
Wrong usernameKeycloak sends preferred_username, not usernameBoth are accepted by KalamDB via serde alias
User not foundauto_create_users_from_provider is falseEnable it, or pre-create the user with CREATE USER ... WITH OAUTH
Last updated on