Users, roles and API tokens

Local and single sign-on users, the built-in roles and what each can do, session tokens, and long-lived API tokens for CI and scripts.

Every request to the control plane acts as a user of one tenant. What the user may do is the union of its roles’ permissions. A request carries the user’s identity as a short session token, from a sign-in, or as a long-lived API token the user created, which can only narrow what the user may do.

Local users and single sign-on users

A local user signs in with an email and a password. The first one is the bootstrap admin, created at boot from bootstrap.email and bootstrap.password_hash (or bootstrap.password) in tenant default; on Lite it is the admin dexaflow lite sets up. An admin creates more:

dexaflow auth create-user --email ana@example.com --password-stdin \
  --role operator < password.txt

or through the API, POST /api/v2/users with {"email": "...", "password": "...", "roles": ["operator"]}. The email is lowercased and must be unique in the tenant; the password must be at least 8 characters; each role must exist in the tenant. Creating users needs write:user, which only admin has. GET /api/v2/users lists them.

A single sign-on user has no password. With OIDC (Google Workspace, Entra ID, Okta and others, Cognito), the user row is created at the first sign-in when auth.oidc.jit_provisioning is on, with the roles that auth.oidc.role_mappings gives the user’s groups, or auth.oidc.default_role when none match. With a trusted issuer, the platform in front of Dexaflow creates the user and sets its roles through the operator service API. While OIDC is on, password sign-in is refused except for the emails in auth.oidc.break_glass_emails.

An admin deactivates or reactivates a user of their tenant with PATCH /api/v2/users/{user_id} and the body {"is_active": false} (or true). The admin needs write:user and cannot deactivate their own account. A deactivated user is refused at its next request, and so are its session, its token renewals and its API tokens; a new sign-in is refused too. The change is recorded in the audit log as user.deactivate or user.activate; the deactivation entry also counts the API tokens it revoked. Deactivating ends the user’s credentials for good: its API tokens are revoked, and every session it had stays refused. Reactivating restores the user with the roles it had, and the user signs in again and creates new API tokens. Changing a local user’s roles or password through the API is not available yet (#2229).

Built-in roles

Every tenant has these roles. They are system roles: they cannot be deleted, and an upgrade does not assign them to anyone.

RoleCan
viewerRead DAGs, runs, task instances, XComs, pools, connections, variables and the configuration.
editorWhat viewer can, plus author DAGs and write connections and variables.
operatorWhat editor can, plus trigger runs, set run and task states, clear tasks, and write pools.
deployerRead DAGs and their versions, register versions and set the current version. Nothing else: meant for CI.
adminEverything in its tenant, including users, every user’s API tokens and the audit log.

Permissions are pairs such as read:dag or write:pool; a route that a role lacks the permission for answers 403. A user with several roles gets every permission of each.

Sessions

Signing in, in the UI or with dexaflow auth login, gives a session token that lives auth.jwt.token_ttl_seconds (one hour by default). The UI renews it while it is open, up to auth.jwt.max_lifetime_seconds (one day by default) after the first sign-in; then the user signs in again.

dexaflow auth login saves the session for the server it signed in to, and the other commands use it. With single sign-on it opens the browser, or prints a code to confirm on another device with --device. To sign in with a password from a script, pass the credentials in the environment rather than on the command line:

export DEXAFLOW_USERNAME=ana@example.com
export DEXAFLOW_PASSWORD=...
dexaflow auth login --server https://dexaflow.example.com

A password is not sent over plain http to a server that is not on the same machine unless you pass --allow-insecure-password.

API tokens

An API token is a long-lived credential a user creates for CI or a script. It starts with dxf_, is shown once, and the server keeps only its SHA-256 hash. It acts as its owner, with the owner’s roles read again on every request, and its scope narrows them:

  • deploy reads DAGs and their versions, registers versions and sets the current version. Everything else is refused, whatever the owner’s roles. This is the token for a CI pipeline.
  • read reads everything its owner can read.

Create one while signed in:

dexaflow auth create-token --scope deploy --name github-my-dags --ttl 90d

or with POST /api/v2/apiTokens and {"name": "github-my-dags", "scope": "deploy", "expires_in_seconds": 7776000}. The owner’s roles must allow what the scope does, or the create answers 403.

  • Lifetime. 90 days by default, from one hour to 365 days. An expired token answers 401.
  • Listing. dexaflow auth tokens list, GET /api/v2/apiTokens, or User > API tokens in the UI show the name, scope, owner, expiry and last use, never the token. A user sees its own tokens; an admin sees every token of the tenant.
  • Revoking. dexaflow auth tokens revoke <id>, DELETE /api/v2/apiTokens/{id}, or Revoke in the UI stops the token on its next request. An admin can revoke any token of the tenant.
  • Limits. A user holds at most 50 live tokens, with names unique among them. A token cannot create, list or revoke tokens, and it works only in the Authorization header, never as a browser session.
  • Audit. Creating, revoking and retiring a token are recorded in the audit log, with the token’s id and name.
  • Turned off. auth.api_tokens.disabled: true stops serving the token routes and screen and refuses every API token, for platforms that decide access at each sign-in.

The CI deploy guide walks through a service user with the deployer role and its deploy token. A CI job can also skip stored tokens and exchange its own identity token (CI OIDC).

Tokens from a trusted issuer

A platform in front of Dexaflow can send its own signed tokens as bearer tokens. Their scopes (dexaflow:read, dexaflow:run, dexaflow:deploy) narrow the user’s roles the same way. The configuration reference lists what each scope grants.