feat(secrets): decrypt the login password from sops (task 0010) #3
Reference in New Issue
Block a user
Delete Branch "task-0010-sops-skeleton-and-password"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements
.claude/tasks/0010-sops-skeleton-and-password.md.Wires
sops-nixinto the shared base config as unconditional plumbing, with the two-tier age identity model thespec calls for: an admin identity held only in the operator's password manager, and a
neogaiaidentity generated on the machine onto its LUKS-encrypted root. Both
sshKeyPathsdefaults are cleared, since sops-nix otherwise falls back to the SSH host keys — the exact coupling the spec forbids, and what keeps those keys free to beco
me secrets in 0011.
The primary user's password hash now lives in
secrets/shared.yaml, encrypted to admin plusneogaia, consumedthrough
hashedPasswordFileand markedneededForUsersso it decrypts before accounts are created.Deviation
users.mutableUsers = falsewas needed and is not in the plan. NixOS applies a declared hash to an account thatalready exists in
/etc/shadowonly when that flag is false, so at the default the hand-set password would have been kept and this change would have been silently inert — the manual acceptance criterion would have passed w
hile proving nothing.
Consequences:
passwdno longer works (rotation is re-mkpasswd, re-encrypt, rebuild), and root is now locked(
!), which blocks direct root login and thesuloginemergency prompt.sudofrom wheel is unaffected, and generation rollback or
init=/bin/shremains available. Worth folding back into the parent spec before the servers exist.
Verification
nix flake checkbuilds theneogaiatoplevel.the key 'alexion-passwrd' can not be found; a missing secrets file fails withPath 'secrets/absent.yaml' does not exist in Git repository.nixos-rebuild switchsucceeded,/run/secrets-for-users/alexion-passwordmaterialized,/etc/shadowcarries the decrypted hash, and console login against it was confirmed by the operator.
Review
Overall: HIGH
system/default.nixis the shared base, so every future host inheritsmutableUsers = fa lseand a file-backed password; one without an identity gets an unusable account.verting the option does not unlock it).
nix flake checkonly proves evaluation; decryption and login are manual by nature.recipient list is the access-control model.
All four Standards findings were fixed in the diff (over-long
.sops.yamlheader; a comment justifying againstan alternative and describing future state; an inaccurate
mutableUserscomment; the secret name constructed attwo sites, now a single
passwordSecretbinding). The fixes were comment-only plus aletbinding — the rebuilt derivation hash was identical, confirming no behavioural change.
Unaddressed:
users.mutableUsers = falseis undeclared scope. Kept deliberately: it is load-bearing, and reverting it makes the feature inert. Recording it in the spec is follow-up work, not a code change.
services.oogaiawith no declaredauthorizedKeys,so SSH cannot rescue a console lockout. O 0011, which touches the
sshdconfiguration anyway.
df5bfbbd3dtoce103a7353