OIDC & Issuer Trust
This page covers OIDC/JWT issuer trust configuration for KalamDB.
Use this when you want KalamDB to accept tokens from external identity providers (Keycloak, Auth0, Google, Azure AD, etc.).
Token Routing Model
KalamDB inspects every bearer token before signature verification to decide how to validate it:
Token alg | Token iss | Validation Path |
|---|---|---|
| HS256 | kalamdb | Internal: verified using auth.jwt_secret |
| RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384 | Any trusted issuer | External: verified via OIDC discovery + provider JWKS |
ES512 is not supported.
This means external tokens from standard OIDC providers are validated natively — no bridge service required.
server.toml Settings
[authentication]
jwt_secret = "replace-with-strong-random-secret-32-plus-chars"
jwt_trusted_issuers = "https://issuer.example.com"
auto_create_users_from_provider = falseNotes:
[auth]and[authentication]are both accepted (serde alias).jwt_trusted_issuersaccepts a comma-separated list for multiple issuers.- Keep
jwt_secretstrong even when using external issuers — it is still used for internal HS256 tokens fromPOST /v1/api/auth/login. - Set
auto_create_users_from_provider = trueto auto-provision users when a valid external token arrives for an unknown user.
Environment Variable Overrides
export KALAMDB_JWT_SECRET="replace-with-strong-random-secret-32-plus-chars"
export KALAMDB_JWT_TRUSTED_ISSUERS="https://issuer.example.com,https://issuer-2.example.com"
export KALAMDB_AUTH_AUTO_CREATE_USERS_FROM_PROVIDER=trueBoolean env vars accept "true", "1", or "yes" (case-insensitive).
Environment variables override server.toml values.
Full OIDC Configuration Matrix
server.toml key | Environment variable | Default | Notes |
|---|---|---|---|
auth.jwt_secret | KALAMDB_JWT_SECRET | "CHANGE_ME_IN_PRODUCTION" | Rejected on non-localhost if weak |
auth.jwt_trusted_issuers | KALAMDB_JWT_TRUSTED_ISSUERS | "" (empty) | Comma-separated list |
auth.jwt_expiry_hours | KALAMDB_JWT_EXPIRY_HOURS | 24 | Internal token lifetime |
auth.auto_create_users_from_provider | KALAMDB_AUTH_AUTO_CREATE_USERS_FROM_PROVIDER | false | Auto-create on first external token |
OIDC Discovery Flow
When KalamDB encounters an external token (non-HS256):
- Extracts
algandkidfrom the JWT header (unverified). - Extracts
issfrom the JWT payload (unverified). - Confirms
issis injwt_trusted_issuers. - Fetches
{issuer_url}/.well-known/openid-configuration. - Extracts
jwks_urifrom the discovery response. - Fetches the JWKS endpoint and caches keys by
kid. - Matches the token
kidto a cached signing key. - Validates signature, issuer, expiry, and audience (if configured).
JWKS Caching Behavior
- Keys are cached per-issuer in memory, indexed by
kid. - Cache-miss refresh: if a token’s
kidis not found, KalamDB automatically re-fetches the JWKS endpoint. - No TTL-based eviction: cache refreshes only on miss — keys remain cached until an unknown
kidtriggers a refresh. - Keys without a
kidfield are silently discarded from the cache. - Key rotation at the provider is handled automatically (new
kid→ cache miss → refresh).
JWT Claims Structure
KalamDB reads these claims from external tokens:
| Claim | Type | Required | Notes |
|---|---|---|---|
sub | string | Yes | User subject identifier |
iss | string | Yes | Must match a trusted issuer |
exp | number | Yes | Expiry (Unix timestamp, seconds) |
iat | number | Yes | Issued-at (Unix timestamp, seconds) |
username / preferred_username | string | No | Mapped to KalamDB username (serde alias for Keycloak/Auth0 compatibility) |
email | string | No | User email |
role | string | No | KalamDB role: user, service, dba, system |
token_type | string | No | "access" or "refresh" |
Provider-Agnostic Checklist
- Confirm exact issuer URL (trailing slashes matter).
- Verify the provider publishes
/.well-known/openid-configuration. - Add the issuer URL to
jwt_trusted_issuers. - Restart KalamDB.
- Send a provider-issued bearer token to a protected endpoint.
- Validate authentication and user mapping behavior.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
401 Unauthorized on external token | Issuer not in jwt_trusted_issuers | Add exact issuer URL |
MissingKid error | Token missing kid header | Provider must include kid in JWT header |
KeyNotFound after JWKS refresh | Key rotated and kid no longer present | Check provider JWKS, ensure key is published |
DiscoveryFailed | Cannot reach /.well-known/openid-configuration | Check network, DNS, and issuer URL format |
JwtValidationFailed: ExpiredSignature | Token expired | Get fresh token from provider |
| User not found after auth | auto_create_users_from_provider is false | Enable it or pre-create user with CREATE USER ... WITH OAUTH |
Provider Guides
Related
Last updated on