Authentication overview
How Flux authenticates requests — API keys, OIDC, bootstrap tokens, execution tokens — and the principal model that ties them together.
Flux 0.56.0 ships two user-facing auth providers — API keys and OIDC — plus two internal token types (bootstrap tokens for worker registration, execution tokens for callbacks during a run). Each provider can be enabled independently. This page is the map; the rest of the Security section is the detail.
What is on, what is off
Both providers default to off. They are turned on independently:
[flux.security.auth.oidc]
enabled = true
issuer = "https://idp.example.com"
audience = "flux-api"
[flux.security.auth.api_keys]
enabled = true
security.auth.enabled is a real, settable field — FLUX_SECURITY__AUTH__ENABLED=true (or enabled = true under [flux.security.auth]) turns authentication on directly. At startup the server reconciles the master switch with the providers (flux/security/config.py):
- Enabling either provider implies
auth.enabled = true— the master switch is forced on, with a warning if it was explicitly set tofalse. - Setting
auth.enabled = truewith no provider configured is rejected at startup with an error: enable[flux.security.auth.oidc]or[flux.security.auth.api_keys]. Auth on with nothing to authenticate against is a misconfiguration, not a usable state.
When auth is off, the server logs a CRITICAL line at startup:
Authentication is DISABLED. All requests are treated as the ANONYMOUS
admin principal. This is not safe for production.
That is by design for local development. Every request is bound to a synthetic ANONYMOUS identity with the admin role — fine against a SQLite file on your laptop; unsafe anywhere else. The line is suppressed in debug mode; wire it to an alert if it shows up in production logs.
How a request is authenticated
The flow lives in flux/security/dependencies.py and flux/security/auth_service.py:
- The client sends
Authorization: Bearer <token>. Any other scheme is rejected with401before a provider runs. AuthService.authenticatewalks each enabled provider in order: execution-token provider first (always registered), then OIDC (if enabled), then API key (if enabled).- The first provider that recognises the token returns a
FluxIdentity. Provider errors are logged and the chain continues; if no provider claims the token, the request gets a401. - The route’s
Depends(require_permission(...))then checks the identity’s roles against the required permission. A mismatch is403, not401.
Principals
A principal is who or what is acting. Each provider issues a different flavour:
- User — minted by the OIDC provider on first sight of a valid token; subject is the OIDC
subclaim. - Service account — created when you provision an API key (
flux principals create … --type service_account). The API-key provider rejects keys whose principal is not a service account. - Worker — auto-provisioned when a worker calls
POST /workers/registerwith a bootstrap token. The server hands back a session API key bound to the new worker principal. - Execution — short-lived, scoped to one running workflow. Used by workers calling back into the server mid-run (resume signals, checkpoint uploads, nested workflow dispatch).
See Principals and identity for the registry shape, the built-in roles (admin, operator, viewer, worker), and how roles are assigned.
Permissions
Authentication produces an identity. Authorization decides what that identity may do. Permissions are colon-delimited strings — for example workflow:billing:invoice:run — and roles hold lists of them, with * wildcards. See RBAC and permissions.
Where to go next
- Standing up OIDC against an external IdP → Configuring OIDC.
- Issuing and rotating API keys → Managing API keys.
- Worker enrolment → Bootstrap tokens.
- Internal callbacks during a run → Execution tokens.
When it goes wrong
Two failure modes cover most of what you’ll see:
- Auth is off in production. The
CRITICAL - Authentication is DISABLEDline at startup is the only signal Flux gives you. Wire it to an alert. - A request 401s with a token the client believes is valid. Check provider order (execution → OIDC → API key) and, for OIDC, the
audienceandissueron the token versus the values in[flux.security.auth.oidc]. JWKS is cached forjwks_cache_ttlseconds (default 3600), so a rotated signing key can produce stale-key failures until expiry.