JWT / OIDC Auth on the Coordinator
Configure the coordinator to validate end-user bearer tokens against an OIDC provider.
For end-user auth (analysts hitting the UI, BI tools connecting via JDBC), wire the coordinator to your OIDC provider. Krishiv validates the bearer token against a JWKS endpoint and enforces the configured audience.
Prerequisites
- An OIDC provider (Auth0, Keycloak, Okta, Azure AD, or any compliant implementation).
- An OIDC application with a known
audclaim (Krishiv requires it in production). - The provider's JWKS URL (typically
https://issuer/.well-known/jwks.json).
Step 1 — Coordinator env
export KRISHIV_PRODUCTION=1
export KRISHIV_OIDC_JWKS_URI=https://auth.example.com/.well-known/jwks.json
export KRISHIV_OIDC_AUDIENCE=krishiv-prod
export KRISHIV_COORDINATOR_BEARER_TOKEN=... # still required for service-to-service
export KRISHIV_UI_TOKEN=... # separate from OIDC; optional
Production mode (KRISHIV_PRODUCTION=1) requires that KRISHIV_OIDC_AUDIENCE be set, otherwise the coordinator refuses to start.
Step 2 — Role mapping
Krishiv recognises three standard roles for management endpoints:
| Role | Can |
|---|---|
admin | Everything: submit, cancel, savepoint, restore, manage executors. |
writer | Submit queries and write data. Cannot manage jobs or executors. |
reader | Read-only: query, list jobs, read state. Cannot write or modify. |
The role is read from the JWT claim. Configure the claim name at the OIDC provider — typically https://krishiv/roles or groups. The coordinator's validate_grpc_auth_for_role enforces it.
Step 3 — Client side
Python:
import os, krishiv as ks
# The SDK reads the bearer token from the standard OIDC token endpoint
os.environ["KRISHIV_OIDC_TOKEN"] = open("/run/secrets/oidc-token").read()
session = ks.Session.connect("https://coord.example.com:50051")
CLI:
KRISHIV_OIDC_TOKEN=... krishiv sql --query "SELECT 1"
Browser (UI): the UI prompts for a bearer token on first load. Store it in localStorage; it's sent as Authorization: Bearer ... on every request.
Step 4 — Key rotation
The coordinator caches the JWKS for KRISHIV_OIDC_JWKS_REFRESH_SECS (default 600). On rotation the provider publishes the new key alongside the old; the next refresh picks it up. Existing tokens continue to work until they expire.