ldap goes state-only, HM leaves the system config, and four hosts drop the local account #120

Merged
lament merged 7 commits from ldap-state-only-hm-split into main 2026-08-01 01:32:07 -05:00
Owner
  • openldap.nix: the openldap-seed unit is gone entirely - directory content (DIT structure, people, groups, svc-ldap/svcLdapAdmin) is now hand-managed runtime state (ldap-tui/kadmin), borg-backed like anything else persistent
    • nix keeps owning the slapd service (schema, ACLs, memberof/refint overlays) and the ldapBindPassword secret app hosts need to bind - it no longer creates or reconciles content
    • removes the create-only ldapadd that could never self-heal a bad uidNumber/gidNumber once seeded - the actual root cause of the prior sudo lockout (cn=wheel was gidNumber: 1001, cn=systemd-journal was 1002, vs. NixOS's real 1/62 - fixed live via ldapmodify this session)
    • deployed and verified live on verdandi: openldap/saslauthd/sssd healthy, seed unit stopped/removed, all prior directory content survived intact
  • .claude/CLAUDE.md: drops the stale "keep unused function args" rule - superseded by adopting deadnix, which now flags them as part of the nix flake check gate
  • first step of the actual standalone-HM/local-account-removal track: modules/homeConfigurations/server.nix adds a shared lament@server homeConfiguration (mirrors ishtar's lament@desktop split - same modules as the integrated server profile, decoupled from nixos-rebuild)
    • brigid pilots it (modules.lament.standalone = true) - lowest-stakes real server, not the identity box or the shared app tier
    • just home takes a profile arg now (default desktop) so servers can run just home server
    • local lamentUser account is untouched on brigid - this only proves standalone HM converges on real hardware before local-account removal gets attempted again
- `openldap.nix`: the `openldap-seed` unit is gone entirely - directory content (DIT structure, people, groups, `svc-ldap`/`svcLdapAdmin`) is now hand-managed runtime state (ldap-tui/kadmin), borg-backed like anything else persistent - nix keeps owning the slapd *service* (schema, ACLs, memberof/refint overlays) and the `ldapBindPassword` secret app hosts need to bind - it no longer creates or reconciles content - removes the create-only `ldapadd` that could never self-heal a bad `uidNumber`/`gidNumber` once seeded - the actual root cause of the prior sudo lockout (`cn=wheel` was `gidNumber: 1001`, `cn=systemd-journal` was `1002`, vs. NixOS's real `1`/`62` - fixed live via `ldapmodify` this session) - deployed and verified live on verdandi: `openldap`/`saslauthd`/`sssd` healthy, seed unit stopped/removed, all prior directory content survived intact - `.claude/CLAUDE.md`: drops the stale "keep unused function args" rule - superseded by adopting `deadnix`, which now flags them as part of the `nix flake check` gate - first step of the actual standalone-HM/local-account-removal track: `modules/homeConfigurations/server.nix` adds a shared `lament@server` homeConfiguration (mirrors ishtar's `lament@desktop` split - same modules as the integrated server profile, decoupled from `nixos-rebuild`) - `brigid` pilots it (`modules.lament.standalone = true`) - lowest-stakes real server, not the identity box or the shared app tier - `just home` takes a `profile` arg now (default `desktop`) so servers can run `just home server` - local `lamentUser` account is untouched on brigid - this only proves standalone HM converges on real hardware before local-account removal gets attempted again
nix keeps owning the slapd service (schema, ACLs, memberof/refint overlays)
and the ldapBindPassword secret; it no longer creates or reconciles
ou=people/ou=groups, uid=lament, svc-ldap, or svcLdapAdmin. those are runtime
state now - ldap-tui/kadmin by hand, borg-backed. removes the create-only
ldapadd that could never self-heal a bad uidNumber/gidNumber (the actual
root cause of the prior sudo lockout).
superseded by adopting deadnix, which now flags unused lambda args as part
of the nix flake check gate - leaving them in breaks the check instead of
being harmless.
brigid: pilot standalone home-manager for servers
All checks were successful
CI / check (pull_request) Successful in 55s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m30s
CI / dry-activate (pull_request) Successful in 32s
fac06d34af
new shared lament@server homeConfiguration mirrors the integrated profile
(btop/fastfetch/homeShell/hyfetch/starship + lamentHome), decoupled from
nixos-rebuild - same split ishtar already uses via lament@desktop. brigid
flips modules.lament.standalone = true first: lowest-stakes real server
(not the identity box, not shared app tier). local account stays declared
for now - that's the next step once standalone HM is confirmed converging
on real hardware. 'just home' now takes a profile arg (default desktop)
so servers can run 'just home server'.
lament force-pushed ldap-state-only-hm-split from fac06d34af
All checks were successful
CI / check (pull_request) Successful in 55s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m30s
CI / dry-activate (pull_request) Successful in 32s
to 1c7c7f0992
Some checks failed
CI / check (pull_request) Successful in 50s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m36s
CI / dry-activate (pull_request) Has been cancelled
2026-07-31 21:58:06 -05:00
Compare
lament force-pushed ldap-state-only-hm-split from 1c7c7f0992
Some checks failed
CI / check (pull_request) Successful in 50s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m36s
CI / dry-activate (pull_request) Has been cancelled
to 63d9964937
All checks were successful
CI / check (pull_request) Successful in 51s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m32s
CI / dry-activate (pull_request) Successful in 26s
2026-07-31 22:01:39 -05:00
Compare
lament force-pushed ldap-state-only-hm-split from 63d9964937
All checks were successful
CI / check (pull_request) Successful in 51s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m32s
CI / dry-activate (pull_request) Successful in 26s
to 4c407217f0
All checks were successful
CI / check (pull_request) Successful in 49s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m29s
CI / dry-activate (pull_request) Successful in 31s
2026-07-31 23:00:35 -05:00
Compare
servers: roll local-account removal out to minerva + athena
Some checks failed
CI / check (pull_request) Successful in 51s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m40s
CI / dry-activate (pull_request) Failing after 15s
ab3d0418a1
extends brigid's verified pilot (LDAP-only login/sudo confirmed live: wheel
+ systemd-journal resolve correctly via sssd, GSSAPI ticket-SSH doesn't
touch the removed local authorizedKeys, sudo -v succeeds). same story here
- neither host used any extraGroups beyond wheel/systemd-journal (video/
plugdev/docker/libvirtd/gamemode were desktop-only dead weight from the
shared list), both already correct in LDAP.

verdandi stays localAccount = true, explicitly, as a break-glass exception:
it's the identity box itself, so it's the one place where losing the local
account would mean no login path independent of its own slapd/krb5-kdc
staying healthy.
lament force-pushed ldap-state-only-hm-split from ab3d0418a1
Some checks failed
CI / check (pull_request) Successful in 51s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m40s
CI / dry-activate (pull_request) Failing after 15s
to 3cecf6b719
All checks were successful
CI / check (pull_request) Successful in 50s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m50s
CI / dry-activate (pull_request) Successful in 31s
2026-07-31 23:32:06 -05:00
Compare
persist sssd's cache across reboots
All checks were successful
CI / check (pull_request) Successful in 53s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 2m56s
CI / dry-activate (pull_request) Successful in 36s
64341fe25c
/var/lib/sss survives the impermanence wipe now - without this, a host
booting with no route to verdandi/LDAP has nothing to fall back on even
though sssd's cache_credentials/krb5_store_password_if_offline exist
specifically for that case (offline auth was verified working on brigid
this session, but only within a single boot - a reboot while offline would
have started sssd cold with nothing cached).

deploy this AFTER rebooting ishtar to clear its currently-stale cache (sssd
cached lament's group memberships hours before today's video/docker/
libvirtd groups landed in LDAP, and hadn't hit its ~90min entry_cache_timeout
yet - locked sudo out entirely, no root password fleet-wide to fall back on,
recovered via generation rollback at the boot menu). persisting a stale
cache would make that kind of lockout permanent instead of reboot-clearable,
so the reboot has to come first, deploy second.
sssd: kill the negative-cache race that poisoned lookups after boot
All checks were successful
CI / check (pull_request) Successful in 1m38s
CI / deploy (pull_request) Has been skipped
CI / build (pull_request) Successful in 26m13s
CI / dry-activate (pull_request) Successful in 38s
CI / check (push) Has been skipped
CI / build (push) Has been skipped
CI / dry-activate (push) Has been skipped
CI / deploy (push) Successful in 3m2s
b2803f7802
ishtar's sudo/login intermittently broke after some delay post-boot,
resolving cleanly right after a reboot then failing again later - getent/
whoami/sudo all failed silently (sssd.service stayed 'active', nothing
logged), while sssd's own NSS responder confirmed empty for both passwd and
group lookups (getent -s sss). traced to SSSD upstream issue #8194: a
lookup that races the LDAP backend's initial bind at boot gets negatively
cached (default entry_negative_timeout = 15s), and that negative entry can
get stuck rather than retried, hanging around far longer than 15s.

entry_negative_timeout = 0 in [nss] removes the failure mode outright - a
failed lookup is retried next time instead of remembered as failed.
ordering sssd.service after wireguard-internal closes the race at the
source instead of just papering over the symptom: sssd's first LDAP bind
no longer gets a shot at happening before the tunnel to verdandi is up.

only ishtar built/verified so far - fleet-wide rebuild still pending.
lament scheduled this pull request to auto merge when all checks succeed 2026-08-01 01:07:17 -05:00
lament changed title from ldap goes state-only, and brigid pilots standalone HM to ldap goes state-only, HM leaves the system config, and four hosts drop the local account 2026-08-01 01:08:23 -05:00
lament merged commit b2803f7802 into main 2026-08-01 01:32:07 -05:00
lament deleted branch ldap-state-only-hm-split 2026-08-01 01:32:07 -05:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
lament/pantheon!120
No description provided.