Skip to content

Authentication modes

Fanout signs people in one of two ways, set by FANOUT_AUTH_MODE. The choice is not only about convenience — it decides who owns a user’s role.

There are no passwords. Active users receive short-lived codes by email, which is why SMTP exists as a setting at all.

SMTP is optional, and that has a consequence worth understanding rather than discovering. Creating a user without it succeeds, and reports that it could not deliver an invitation. The account is real; nobody can reach it until an operator with shell access mints a link with fanout login-link. That is the designed path, not a workaround — see troubleshooting.

In local mode, roles are managed inside Fanout.

User responses from GET /api/auth/me and GET /api/users use display_name and status. Status is active or suspended; roles remain viewer, operator, and admin.

Administrators provision users with POST /api/users, supplying email, display_name, and role. New users have status active. Profile edits use PATCH /api/users/{id} with only email and display_name. Change roles with PATCH /api/users/{id}/role and a body such as {"role":"viewer"}; suspend an account with PATCH /api/users/{id}/status and {"status":"suspended"}. Use {"status":"active"} on that same status route to restore sign-in. Unknown fields and invalid statuses return 400.

Email, role, and status changes revoke existing browser sessions. Suspension blocks both local and OIDC sign-in, as well as OAuth token use. Restoring status does not restore revoked sessions. The last active administrator cannot be demoted, suspended, or deleted. These account rules apply in both auth modes.

FANOUT_SELF_SIGNUP (default false) lets anyone who can receive an email code provision themselves an account. It exists for public installations that want per-user access without a shared credential or an identity provider.

Two conditions guard it, and both matter:

  • Only after email-code verification. An account is created when the code is verified, not when it is requested, so an address nobody controls cannot become a user.
  • Never before admin setup. Provisioning is refused while the instance has no users, so the first account is always the administrator you create deliberately — a race for the setup URL cannot hand someone else the instance.

Self-provisioned users are viewer. Be clear about what that grants before turning this on: a viewer can read all telemetry the instance holds, keep their own dashboards, and run the chat investigator — which calls your model provider and spends money. It can change its own dashboards, but cannot manage alert rules, rotate the ingest token, or administer users.

If that is more than you want to hand to anyone who can receive an email, leave self-signup off and create accounts deliberately. The full matrix is in roles, generated from the authorization table itself.

An identity provider handles sign-in. Two behaviours are worth knowing before you rely on it.

FANOUT_OIDC_ALLOWED_GROUPS and FANOUT_OIDC_ALLOWED_DOMAINS are evaluated at every login, including by an identity that is already linked. Removing someone from an allowed group at the provider blocks their next login. It does not wait for a provisioning cycle, and there is no window in which a removed user continues to be admitted.

If neither list is set there is no allow policy, and membership is managed locally instead.

Verified identities can be auto-provisioned as viewers

Section titled “Verified identities can be auto-provisioned as viewers”

FANOUT_OIDC_AUTO_PROVISION creates an eligible identity’s account on first login, after administrator setup. Its role comes from the configured admin or operator group mapping, falling back to FANOUT_OIDC_DEFAULT_ROLE (viewer). With the default FANOUT_OIDC_EMAIL_VERIFICATION=required, the identity must have a verified email. The issuer policy trusts the configured issuer instead and requires an allowlist. Auto-provisioning always requires an allowed group or domain. Chat, MCP tools and owned dashboards are available to viewers; operator actions still require the corresponding capabilities.

This is the OIDC counterpart to local self-signup above, and it obeys the same allow policy: if FANOUT_OIDC_ALLOWED_GROUPS or FANOUT_OIDC_ALLOWED_DOMAINS is set, an identity outside it is not admitted at all, provisioning or not.

If FANOUT_OIDC_ADMIN_GROUPS or FANOUT_OIDC_OPERATOR_GROUPS is set, the provider owns each linked user’s role. The mapped role is applied on every login; anyone in no mapped group falls back to FANOUT_OIDC_DEFAULT_ROLE. A role change increments the user’s auth version, revokes their browser sessions, and writes a role.changed audit event — in one transaction, so a demotion cannot half-apply and leave live sessions at the old level.

If neither group list is set, roles are managed locally and logins never change them.

Neither is a tenancy boundary. Namespaces scope telemetry queries, but anyone who can query the instance can query every namespace in it. An instance is one trust domain; separate trust domains want separate instances.