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.
Account profiles and suspension
Section titled “Account profiles and suspension”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.
Self-signup
Section titled “Self-signup”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.
Eligibility is checked on every login
Section titled “Eligibility is checked on every login”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.
The provider can own roles, or not
Section titled “The provider can own roles, 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.
What neither mode is
Section titled “What neither mode is”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.