hyperhive/swarm-authelia-bridge
Repository files (latest commit first)
Filename Latest commit message Latest commit date
atlas 1885022d02 fix(#3422): give bridge-created identities an email too
#3414 fixed the missing-email defect in swarmctl only, so every identity
created by the bridge landed in users.yml with no `email`. A relying
party that asks for the claim does not degrade, it fails -- grafana's
OIDC login is the measured case (#3393).

Two writers of one file disagreeing about a field one of them treats as
required is not a difference worth keeping, and with the file shared the
result also depended on which tool wrote last.

Mutation-checked: removing the fill turns the new test red and nothing
else.
2026-08-18 10:31:48 +02:00
..
src fix(#3422): give bridge-created identities an email too 2026-08-18 10:31:48 +02:00
Cargo.toml fix(#3422): the bridge reads and writes users.yml directly 2026-08-18 10:31:48 +02:00
README.md add swarm-authelia-bridge: the only thing allowed to write swarm-authelia's users database 2026-08-16 22:38:40 +02:00

swarm-authelia-bridge

The only thing allowed to write swarm-authelia's users database.

Why this exists

swarm-controller's CreateIdentity job needs to add an agent as an authelia subject, but swarm-controller runs unprivileged and does not own users.yml — a different uid does (authelia-swarm, the user services.authelia.instances.swarm runs as). Root/CAP_CHOWN/a shared group were all examined and rejected during this crate's design thread — see swarmctl/README.md's identical analysis of this same file, written before this crate existed.

The fix: run this process as User = "authelia-swarm"; instead — inside the swarm-authelia container, alongside authelia itself — so it simply owns the file it writes. No elevated privilege anywhere.

Shape

  • One endpoint, POST /requests, body = swarm-authelia-bridge-sock's BridgeRequest verbatim — one variant today (EnsureAgentIdentity, idempotently ensure an agent exists as an authelia subject).
  • Bearer-authenticated via authelia's own OIDC token introspection (RFC 7662), against swarm-controller's existing machine-client identity (already minted for the queue connection) — no new credential.
  • No restart of authelia after a write — relies on authentication_backend.file.watch, confirmed working against the pinned 4.39.20 build during this design work.
  • Network-facing rather than unix-socket-only: swarm-authelia's container shares the host netns, so the same listener serves both a co-located swarm-controller (loopback) and a split-host one (bind wider + firewall) with no separate transport.

Known limitation

swarmctl still writes an independent users.json/users.yml for human accounts, assuming co-location with swarm-controller's host. Two canonical stores for the same physical file is a real seam, not solved here — routing swarmctl through this bridge too is a plausible follow-up, out of scope for the agent-identity slice this crate shipped with.