Harden the SSH-key rotation script suite to a uniform posture #18
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/nexus#18
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Bring the three SSH-key rotation scripts (
forge-ssh-key,nexus-host-key,vm-ssh-host-key) and the sharedrotation-common.shup to a single uniform safety posture, so rotating any key is equally safe, testable, and previewable regardless of which script runs. Today the three form an uneven maturity ladder —nexus-host-keyis the strongest; the other two lag on host-key pinning, state-shape validation, dry-run, and testability seams.Primary goals:
ageseam and consistent dirty-tree guards.rotate-tokenregistry.Security hardening
forge-ssh-key: pin the VM-side git-over-SSH verification. It runsssh … -o StrictHostKeyChecking=noto the Forge (scripts/forge-ssh-key:182,253), so the VM auto-accepts any presented host key on the exact step that proves the new key before retire drops the old one — a MITM window. Needs a VM-side known_hosts / Forge-host-key-pinning story that survives rebuilds. Design item.forge-ssh-key: harden the host-side git-over-SSH verify toStrictHostKeyChecking=yes/-F /dev/null, matchingnexus-host-key.rotation-common: extract a shared pinned-SSH-options builder. The pinned posture (-o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=…) is copy-pasted (scripts/vm-ssh-host-key:326-327,scripts/forge-ssh-keySSH_OPTS) rather than single-sourced inscripts/lib/rotation-common.sh; it encodes a security invariant, so drift between copies is a real risk.State-shape validation (model:
scripts/nexus-host-key:90assert_nexus_key_json_shape)vm-ssh-host-key: JSON state-shape validation on stage/activate/retire.vm-ssh-host-key: runtime retire proof — after re-encryption, assert the new key decrypts the target's secrets and the old public key is absent from the recipient graph.Operational safety parity
--dry-runtonexus-host-keyandvm-ssh-host-key(forge-ssh-keyhas it:scripts/forge-ssh-key:44,429,458). Previews planned changes, touches no key material.vm-ssh-host-key: replace the fixedsleep 2after sshd reload (scripts/vm-ssh-host-key:346) with a boundedssh-keyscanpoll for the staged key, so a slow reload no longer aborts a legitimate rotation.Testability and consistency
vm-ssh-host-key: routeagethrough an overridableAGE="${AGE:-age}"seam (siblings:scripts/nexus-host-key:26,scripts/forge-ssh-key:26); it currently callsagedirectly (e.g.scripts/vm-ssh-host-key:144), lacking the stub seam its suite needs.nexus-host-key(scripts/nexus-host-key:108) andvm-ssh-host-key(scripts/vm-ssh-host-key:111) assert only secrets clean, yet both read inventory specs;forge-ssh-keyadditionally guards inventory. Either add the inventory clean-check to the two, or document why they tolerate a dirty inventory. Conscious call.Coverage and docs
flake.nix: guarantee everytests/*.shis wired into the run list.checked_scripts(flake.nix:107) and the explicitbash tests/…run list (flake.nix:121-129) are hand-maintained parallel lists; a test added to the first but not the second passes CI while never running. Auto-discovertests/*.shor add a meta-check.forge-ssh-key: documentFORGE_SSH_KEY_TMPDIR/FORGE_SSH_KEY_ALLOW_NON_TMPFSinusage()— honored (scripts/forge-ssh-key:360,382) but undocumented, unlike the sibling scripts.Token registry (
rotate-token)registry_alias, add commands to show/verify/update provider metadata without touching token values, and detect ambiguous provider selectors. Forge UI token names are not editable and rotation keeps the name, so names are poor lifecycle markers.Scope
In: the three rotation scripts,
scripts/lib/rotation-common.sh, the provisioning-contractflake.nixcheck, androtate-tokenregistry ergonomics. Each task is independently landable. Out: broader VM-provisioning-script standardization, tracked in #17.