Watch
0
0
Fork
You've already forked hyperhive
0

swarm-grafana: keep Grafana's OIDC secret, admin password and metrics bearer on the host's /run, not in the container's root

The three delivery units still read from bao under Grafana's own leaf, but
now write to /run/swarm-grafana-secrets on the host (tmpfs), which the
container bind-mounts read-only at the same path. Before, they wrote to
/var/lib/nixos-containers/swarm-grafana/var/lib/{grafana-oidc,grafana-admin,
grafana-metrics}/ on persistent disk, where a superseded value stayed after
rotation and went into backups of the container root. Host tmpfiles now
removes the three old files.

Rotation is unchanged: refresh_consumer restarts Grafana (or starts it if it
failed) when a file changes, since Grafana reads each $__file{} once as it
starts. After a reboot the files are fetched again; until the store answers
Grafana stays down, where before it came up on the last copy from disk.

Part of #4998 (slice 2b).
This commit is contained in:
atlas 2026-10-15 22:09:03 +02:00 • committed by mara
commit cbab23273a
4 changed files with 95 additions and 37 deletions

View file

@ -242,11 +242,11 @@ let
in
lib.hasInfix "bao kv put -cas=0 secret/swarm/services/swarm-grafana/admin/password value=-" unit.script
&& lib.hasInfix "openssl rand -hex 32" unit.script
&& lib.hasInfix "atomic_write_secret 0400 196:0 /var/lib/nixos-containers/swarm-grafana/var/lib/grafana-admin/password" unit.script
&& lib.hasInfix "atomic_write_secret 0400 196:0 /run/swarm-grafana-secrets/admin-password" unit.script
&& lib.elem "container@swarm-grafana.service" unit.before
&& unit.environment.BAO_CLIENT_CERT == "/etc/pki/bao-grafana-oidc.pem"
&& grafana.settings.security.admin_password == "$__file{/var/lib/grafana-admin/password}"
&& lib.hasInfix "admin reset-admin-password --password-from-stdin < /var/lib/grafana-admin/password" service.preStart
&& grafana.settings.security.admin_password == "$__file{/run/swarm-grafana-secrets/admin-password}"
&& lib.hasInfix "admin reset-admin-password --password-from-stdin < /run/swarm-grafana-secrets/admin-password" service.preStart
&& lib.hasInfix "-config ${resetConfig}" service.script;
}
{
@ -290,6 +290,43 @@ let
lib.hasInfix "secret/swarm/services/swarm-grafana/oidc/client" s
&& !(lib.hasInfix "secret/swarm/hives/" s);
}
{
# A copy on persistent disk outlives the secret's rotation and lands in
# backups of the container's root.
name = "grafana's OIDC secret, admin password and metrics bearer are written to the host's /run only, and the old copies removed";
ok =
let
m = grafanaRemoteAuthelia;
services = m.systemd.services;
mount = m.containers.swarm-grafana.bindMounts."/run/swarm-grafana-secrets";
rules = m.systemd.tmpfiles.rules;
guest = m.containers.swarm-grafana.config.services.grafana;
persistent = s: lib.hasInfix "/var/lib/nixos-containers" s || lib.hasInfix "/var/lib/grafana-" s;
oidc = services.swarm-bao-grafana-oidc.script;
admin = services.swarm-bao-grafana-admin.script;
bearer = services.swarm-bao-grafana-metrics-bearer.script;
in
lib.hasInfix "atomic_write_secret 0400 196:0 /run/swarm-grafana-secrets/swarm-grafana.secret" oidc
&& lib.hasInfix "atomic_write_secret 0400 196:0 /run/swarm-grafana-secrets/metrics-bearer" bearer
&& !(persistent oidc)
&& !(persistent admin)
&& !(persistent bearer)
&& !(persistent services.swarm-bao-grafana-controller-token.script)
&& lib.hasInfix "< /run/swarm-grafana-secrets/admin-password" services.swarm-bao-grafana-controller-token.script
&& mount.hostPath == "/run/swarm-grafana-secrets"
&& mount.isReadOnly
&&
guest.settings."auth.generic_oauth".client_secret
== "$__file{/run/swarm-grafana-secrets/swarm-grafana.secret}"
&& lib.any (
d: d.secureJsonData.httpHeaderValue1 or null == "$__file{/run/swarm-grafana-secrets/metrics-bearer}"
) guest.provision.datasources.settings.datasources
&& lib.elem "d /run/swarm-grafana-secrets 0755 root root -" rules
&& lib.elem "r /var/lib/nixos-containers/swarm-grafana/var/lib/grafana-oidc/swarm-grafana.secret" rules
&& lib.elem "r /var/lib/nixos-containers/swarm-grafana/var/lib/grafana-admin/password" rules
&& lib.elem "r /var/lib/nixos-containers/swarm-grafana/var/lib/grafana-metrics/bearer" rules
&& !(lib.any (lib.hasPrefix "f /run/swarm-grafana-secrets") rules);
}
{
# Both halves of the co-location assumption, which was one host's
# `deploy.*` answering a question about the whole swarm: the identities