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):

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:

  1. The client sends Authorization: Bearer <token>. Any other scheme is rejected with 401 before a provider runs.
  2. AuthService.authenticate walks each enabled provider in order: execution-token provider first (always registered), then OIDC (if enabled), then API key (if enabled).
  3. 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 a 401.
  4. The route’s Depends(require_permission(...)) then checks the identity’s roles against the required permission. A mismatch is 403, not 401.

Principals

A principal is who or what is acting. Each provider issues a different flavour:

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

When it goes wrong

Two failure modes cover most of what you’ll see: