Watch
0
0
Fork
You've already forked hyperhive
0

Compare commits

..
Author SHA1 Message Date
atlas
bafda6e3d5 docs/sso: name Grafana as the exception, and say it is unconditional
sso.md's "What this doesn't do" list opened with "It doesn't disable
local login" without qualification, which was wrong for Grafana before
the previous commit and is wrong in a different way after it: Grafana now
disables the form for every deployment, not just where authelia happens to
be on the same host.

Names the exception, gives the reason a reader can act on (a default
`admin`/`admin` account on a gateway-published vhost), and states the
consequence plainly — SSO is the only door, so a dead provider locks
everyone out, which is why the OIDC role defaults to Admin.
2026-09-11 18:23:51 +02:00
atlas
72635832b7 swarm-grafana: grafana requires SSO, so the login form goes unconditionally
`auth.disable_login_form` was gated on `ssoLocal` — `grafana.enable &&
authelia.enable`, i.e. "both of them run on THIS host". With authelia
elsewhere in the swarm that is false, so a deployment that is very much
using SSO still rendered grafana with its local login form enabled, on a
vhost the gateway publishes, for a product that ships an `admin`/`admin`
account.

The reason that matters was already in the module, three lines up
("Grafana ships an `admin`/`admin` account, and this vhost is on the
public gateway") — it was just attached to a conditional. Whether a
password box sits on a public login page is not a per-host question.

Per mara on the docs PR for this: "grafana requires sso - no local
login". The OIDC block below stays gated on locality; making that follow
the same swarm-wide question is a larger change with its own tracking.

The module-eval suite already had the fixture this needed: `grafanaOldPath`
enables grafana and not authelia, which is exactly the shape the login
form stayed enabled in, so the regression case needs no new hive. 90 -> 91
properties.

Closes #4218.
2026-09-11 18:23:51 +02:00
3 changed files with 33 additions and 9 deletions

View file

@ -242,11 +242,18 @@ page-only check. This was verified that way when the split was introduced.
## What this doesn't do
- **It doesn't disable local login.** Each service keeps its password
database and gains a second door. An identity provider that can take a
service offline when it hiccups is worse than one with two ways in.
Making authelia the only path is a separate, reversible switch per
service (tuwunel's `login_with_password`, forgejo's own setting).
- **It doesn't disable local login — except on Grafana.** Forgejo and
tuwunel keep their password databases and gain a second door: an identity
provider that can take a service offline when it hiccups is worse than one
with two ways in, and making authelia the only path there is a separate,
reversible switch (tuwunel's `login_with_password`, forgejo's own setting).
⚠️ **Grafana is the exception, and not a reversible one.** Its module sets
`auth.disable_login_form` unconditionally, because Grafana ships an
`admin`/`admin` account and its vhost is on the public gateway — so a
password box there is a way in whatever the deployment. SSO is the only
door, and a dead provider locks everyone out, the built-in admin
included. That's why `swarm.grafana.oidc.role` defaults to `Admin`; see
[`services.md`](services.md#metrics-victoriametrics--grafana).
- **It doesn't provision users.** Agents are created and destroyed
continuously, so the subject set belongs to a program rather than to a
config file; today that program is `swarmctl`.

View file

@ -701,10 +701,17 @@ in
# whole host fails to build. The unit below generates it.
security.secret_key = "$__file{${secretKeyPath}}";
# No local password path at all when SSO is configured. This
# is not tidiness: Grafana ships an `admin`/`admin` account,
# and this vhost is on the public gateway.
auth.disable_login_form = ssoLocal;
# No local password path, ever. This is not tidiness: Grafana
# ships an `admin`/`admin` account and this vhost is on the
# public gateway, so SSO is the only way in — not merely the
# preferred one.
#
# Deliberately NOT `ssoLocal`: whether a password box sits on a
# public login page cannot depend on which host happens to run
# authelia. The OIDC block below is still gated on locality;
# making that follow the same swarm-wide question is a larger
# change tracked on its own.
auth.disable_login_form = true;
}
// lib.optionalAttrs ssoLocal {
"auth.generic_oauth" = {

View file

@ -655,6 +655,16 @@ let
rule: lib.hasInfix "/run/test-grafana-sock" rule
) grafanaOldPath.systemd.tmpfiles.rules;
}
{
# This fixture enables grafana and NOT authelia, which is the shape the
# login form used to stay enabled in: the toggle read "both services are
# on this host" rather than "grafana requires SSO". Grafana ships an
# `admin`/`admin` account and its vhost is on the public gateway, so a
# password box there is a way in whatever the topology.
name = "grafana disables its local login form even where authelia is not on this host";
ok =
grafanaOldPath.containers.swarm-grafana.config.services.grafana.settings.auth.disable_login_form;
}
{
# Reads the daemon's rendered unit, not the options: the queue address
# arrives as an env var whose whole attrset is guarded on `natsUrl`, and