External Authentication¶
External Session Header¶
The floecat service accepts an external session header carrying a JWT. Quarkus OIDC validates it
and Floecat uses it to authenticate gRPC calls.
Auth modes:
- floecat.auth.mode=oidc: require session or authorization header.
- floecat.auth.mode=dev: require dev context (for local-only use).
Default is oidc; dev mode must be explicitly configured.
Account management is authorized via a global IdP role (see below). Floecat does not auto-create an admin account on startup.
Local Keycloak (dev)¶
For local testing you can run Keycloak with a pre-seeded realm that issues account_id and roles
claims expected by Floecat.
Start Keycloak:
KEYCLOAK_PORT=12221 docker compose --profile keycloak up
The realm import defines:
- realm: floecat
- client: floecat-client
- user: floecat-admin / password floecat-admin
- roles: administrator, platform-admin
- hardcoded claim: account_id=5eaa9cd5-7d08-3750-9457-cfe800b0b9d2 (seed account t-0001)
Role intent:
- platform-admin grants platform account management (account.write, account.delete) and is
intended for platform operators.
- administrator grants full tenant‑scoped access (catalogs/namespaces/tables/connectors) but does
not grant account creation/update. It does include account.delete.
- delete-account is an internal service role, not an IdP-facing operator role. It grants only
account.delete, and floecat performs the implied catalog/namespace/table/connector cleanup
internally.
See docs/fixed-roles.md.
Note: the realm config uses a service-account client (client_credentials flow). Password grant is
disabled.
Important: if you change the seed account ID, update
docker/keycloak/realm-floecat.json so the account_id claim matches.
Example service config (dev, running service on the host):
floecat.auth.mode=oidc
floecat.interceptor.authorization.header=authorization
quarkus.oidc.auth-server-url=http://127.0.0.1:12221/realms/floecat
quarkus.oidc.token.audience=floecat-client
If the service runs in Docker, set the issuer to the Keycloak service name on the Docker network:
quarkus.oidc.auth-server-url=http://keycloak:8080/realms/floecat
quarkus.oidc.auth-server-url=http://host.docker.internal:8080/realms/floecat # or KEYCLOAK_PORT override
Example token request:
curl -s \
-d "client_id=floecat-client" \
-d "client_secret=floecat-secret" \
-d "grant_type=client_credentials" \
http://127.0.0.1:12221/realms/floecat/protocol/openid-connect/token
OIDC Quickstart (Local + Shell CLI)¶
1) Enable local OIDC in docker/env.localstack-oidc:
FLOECAT_AUTH_MODE=oidc
FLOECAT_AUTH_PLATFORM_ADMIN_ROLE=platform-admin
FLOECAT_INTERCEPTOR_AUTHORIZATION_HEADER=authorization
FLOECAT_RECONCILER_OIDC_ISSUER=http://keycloak:8080/realms/floecat
FLOECAT_RECONCILER_OIDC_CLIENT_ID=floecat-reconciler-worker
FLOECAT_RECONCILER_OIDC_CLIENT_SECRET=floecat-reconciler-worker-secret
FLOECAT_SEED_OIDC_ISSUER=http://keycloak:8080/realms/floecat
FLOECAT_SEED_OIDC_CLIENT_ID=floecat-client
FLOECAT_SEED_OIDC_CLIENT_SECRET=floecat-secret
QUARKUS_OIDC_TENANT_ENABLED=true
QUARKUS_OIDC_AUTH_SERVER_URL=http://keycloak:8080/realms/floecat
QUARKUS_OIDC_TOKEN_AUDIENCE=floecat-client,trino-client,floecat-reconciler-worker
2) Start Keycloak + service:
make oidc-up
3) Fetch a token on the host (issuer must be http://host.docker.internal:8080/... unless you
override KEYCLOAK_PORT):
TOKEN=$(curl -s \
-d "client_id=floecat-client" \
-d "client_secret=floecat-secret" \
-d "grant_type=client_credentials" \
http://host.docker.internal:8080/realms/floecat/protocol/openid-connect/token \
| jq -r .access_token)
4) Run the Shell CLI in Docker (interactive):
FLOECAT_ACCOUNT=5eaa9cd5-7d08-3750-9457-cfe800b0b9d2 \
make cli-docker
make cli-docker obtains tokens using FLOECAT_OIDC_* settings in
docker/env.localstack-oidc and refreshes them automatically before expiry.
Inside the shell:
account 5eaa9cd5-7d08-3750-9457-cfe800b0b9d2
account list
Configuration (service application.properties):
- quarkus.oidc.tenant-enabled=true to opt into OIDC validation.
- floecat.auth.platform-admin.role=platform-admin to authorize platform account management.
- floecat.interceptor.session.header=x-floe-session to enable the header.
- Reconciler machine auth in OIDC mode:
- floecat.reconciler.oidc.issuer=http://keycloak:8080/realms/floecat
- floecat.reconciler.oidc.client-id=floecat-reconciler-worker
- floecat.reconciler.oidc.client-secret=floecat-reconciler-worker-secret
- floecat.reconciler.oidc.token-refresh-skew-seconds=30
- floecat.reconciler.oidc.connect-timeout=10s
- Worker-to-control-plane precedence is propagated request auth first, then the reconciler
machine token. Shared static reconcile tokens are no longer the primary or fallback path.
Seed fixture sync in OIDC mode (optional):
- floecat.seed.oidc.issuer=http://keycloak:8080/realms/floecat (when running in Docker)
- floecat.seed.oidc.client-id=floecat-client
- floecat.seed.oidc.client-secret=floecat-secret
- floecat.interceptor.validate.account=false to skip account lookup when the caller supplies a
trusted account id.
- quarkus.oidc.token.audience=... to set the aud claim value expected.
One of:
- quarkus.oidc.auth-server-url=... to validate with an issuer URL.
or
- quarkus.oidc.public-key=... to validate locally with a public key (tests/dev).
Environment equivalents: - QUARKUS_OIDC_TENANT_ENABLED - FLOECAT_AUTH_MODE - FLOECAT_AUTH_PLATFORM_ADMIN_ROLE - FLOECAT_INTERCEPTOR_SESSION_HEADER - FLOECAT_INTERCEPTOR_VALIDATE_ACCOUNT - FLOECAT_RECONCILER_OIDC_ISSUER - FLOECAT_RECONCILER_OIDC_CLIENT_ID - FLOECAT_RECONCILER_OIDC_CLIENT_SECRET - FLOECAT_RECONCILER_OIDC_TOKEN_REFRESH_SKEW_SECONDS - FLOECAT_RECONCILER_OIDC_CONNECT_TIMEOUT - FLOECAT_SEED_OIDC_ISSUER - FLOECAT_SEED_OIDC_CLIENT_ID - FLOECAT_SEED_OIDC_CLIENT_SECRET - QUARKUS_OIDC_TOKEN_AUDIENCE - QUARKUS_OIDC_AUTH_SERVER_URL - QUARKUS_OIDC_PUBLIC_KEY
Further documentation on integration to external OpenID Connect IDPs can be found here: Quarkus OIDC configuration reference
Dev vs Production Configuration¶
Development (local)¶
- Use
docker/env.inmemwithdocker/docker-compose.yml(viaenv_file) for local defaults. - For OIDC + Keycloak, use
docker/env.localstack-oidcby settingFLOECAT_ENV_FILE=./env.localstack-oidc(or runmake oidc-up). floecat.auth.mode=oidc(ordevfor fully local use).- Use Keycloak dev realm or another local IdP.
quarkus.oidc.auth-server-url=http://127.0.0.1:12221/realms/floecatquarkus.oidc.token.audience=floecat-client(orfloecat-client,trino-client,floecat-reconciler-workerif using Trino plus remote/local reconcile workers in OIDC mode).- Use the IdP role
platform-adminfor platform account management. - Use the IdP role
reconcile-workerfor the dedicated reconciler service principal. floecat.interceptor.authorization.header=authorization(orfloecat.interceptor.session.header)floecat.reconciler.oidc.issuer=http://127.0.0.1:12221/realms/floecatfor host-run workers, orhttp://keycloak:8080/realms/floecatfor Docker-network workers.floecat.reconciler.oidc.client-id=floecat-reconciler-workerfloecat.reconciler.oidc.client-secret=...- Optional:
floecat.reconciler.oidc.token-refresh-skew-seconds=30andfloecat.reconciler.oidc.connect-timeout=10s - Consider
floecat.interceptor.validate.account=falseif account ids are trusted in dev.
Production¶
- Use
docker/env.aws(or your own env file) and pass the values to the container. floecat.auth.mode=oidcquarkus.oidc.tenant-enabled=true- Configure exactly one of:
quarkus.oidc.auth-server-url=https://<issuer>/realms/<realm>quarkus.oidc.public-key=...(offline JWT validation)quarkus.oidc.token.audience=<audience>- Use the IdP role
platform-adminfor platform account management. - Use a dedicated reconciler service principal with the
reconcile-workerrole for worker gRPC. floecat.interceptor.authorization.header=authorization(orfloecat.interceptor.session.header)floecat.reconciler.oidc.issuer=https://<issuer>/realms/<realm>floecat.reconciler.oidc.client-id=<reconcile-worker-client-id>floecat.reconciler.oidc.client-secret=<reconcile-worker-client-secret>- Optional:
floecat.reconciler.oidc.token-refresh-skew-secondsandfloecat.reconciler.oidc.connect-timeout floecat.interceptor.validate.account=true(recommended in prod)- Ensure transport security (TLS) at the edge and IdP issuer URLs use HTTPS.
Direct OIDC Authorization Header¶
Floecat can also validate a standard authorization: Bearer <jwt> header using the same Quarkus
OIDC provider configuration. This is useful when clients authenticate directly with an IdP instead
of via an upstream engine session token.
Configuration (service application.properties):
- quarkus.oidc.tenant-enabled=true to opt into OIDC validation.
- floecat.auth.platform-admin.role=platform-admin to authorize platform account management.
- floecat.interceptor.authorization.header=authorization to enable the header.
- Reconciler machine auth in OIDC mode:
- floecat.reconciler.oidc.issuer=http://keycloak:8080/realms/floecat
- floecat.reconciler.oidc.client-id=floecat-reconciler-worker
- floecat.reconciler.oidc.client-secret=floecat-reconciler-worker-secret
- floecat.reconciler.oidc.token-refresh-skew-seconds=30
- floecat.reconciler.oidc.connect-timeout=10s
Seed fixture sync in OIDC mode (optional):
- floecat.seed.oidc.issuer=http://keycloak:8080/realms/floecat (when running in Docker)
- floecat.seed.oidc.client-id=floecat-client
- floecat.seed.oidc.client-secret=floecat-secret
- floecat.interceptor.validate.account=false to skip account lookup when the caller supplies a
trusted account id.
- quarkus.oidc.token.audience=... to set the aud claim value expected.
One of:
- quarkus.oidc.auth-server-url=... to validate with an issuer URL.
or
- quarkus.oidc.public-key=... to validate locally with a public key (tests/dev).
Environment equivalents: - QUARKUS_OIDC_TENANT_ENABLED - FLOECAT_AUTH_MODE - FLOECAT_AUTH_PLATFORM_ADMIN_ROLE - FLOECAT_INTERCEPTOR_AUTHORIZATION_HEADER - FLOECAT_INTERCEPTOR_VALIDATE_ACCOUNT - FLOECAT_RECONCILER_OIDC_ISSUER - FLOECAT_RECONCILER_OIDC_CLIENT_ID - FLOECAT_RECONCILER_OIDC_CLIENT_SECRET - FLOECAT_RECONCILER_OIDC_TOKEN_REFRESH_SKEW_SECONDS - FLOECAT_RECONCILER_OIDC_CONNECT_TIMEOUT - FLOECAT_SEED_OIDC_ISSUER - FLOECAT_SEED_OIDC_CLIENT_ID - FLOECAT_SEED_OIDC_CLIENT_SECRET - QUARKUS_OIDC_TOKEN_AUDIENCE - QUARKUS_OIDC_AUTH_SERVER_URL - QUARKUS_OIDC_PUBLIC_KEY