Decommissioning a Host#
The operational procedure behind SCF AST-09 — Secure Disposal, Destruction or
Re-Use of Equipment (see modules/compliance/controls/AST-09.nix). Every host
that leaves the fleet goes through this runbook, and every run appends a row to
the decommission log. The removal commit’s SHA plus the log
row are the disposal evidence.
Procedure#
1. Repo removal (one atomic PR)#
- Delete the host’s entry from
hosts/default.nixand its directory/file underhosts/<system>/. Tag-driven discovery (builder/cache) drops the host from everynix.buildMachineslist automatically. - Remove the host’s SSH public keys from
modules/darwin/security/pubkeys/andmodules/nixos/security/pubkeys/(the NixOS side auto-globs the directory) and any explicitknownHostsentry inmodules/darwin/security/default.nix. - Remove the host from every
deploy.monitoredHostslist (grep the hostname — a dead entry generates offline alerts every health-check cycle). - Sops key revocation (only if the host had its own age anchor):
- Delete the host anchor and recipient references from
.sops.yaml, plus any user key that existed only for this host. - Remove the host’s secrets (e.g.sops unset secrets.yaml '["borgmatic"]["<hostname>"]'). - Re-key everything:just sops-updatekeys, then verify your own key still decrypts:sops --decrypt secrets.yaml > /dev/null. - Never remove your own user keys — rekey rollback depends on them. - Remove the BorgWarehouse registry entry from
modules/nixos/borg/repo.json. - Docs: delete the machine page, fix inbound links, remove the node from the
manual topology (
modules/topology/default.nix), update.claude/hosts.md. - Verify:
nix flake check,just docs-build, grep for the hostname → empty, eval the remaining darwin/nixos configurations. - Redeploy hosts whose
buildMachines/knownHosts/monitoring changed.
2. Outside the repo#
- Tailscale admin console — remove the node; confirm its device and any auth keys are gone from the tailnet.
- BorgWarehouse (voile) — freeze the host’s repository (no new backups arrive anyway once the client is wiped), note the purge date (90-day retention), and delete the repo when it arrives. Deleting the repo also revokes its per-repo SSH public key.
- Media sanitization — full-disk erase before the hardware leaves organizational control. All fleet disks are full-disk encrypted (LUKS2 / FileVault): destroying the volume key is cryptographic erasure, which is the sanitization floor even if a full wipe is interrupted. Record the wipe method and date in the log.
- Third-party management — if the machine was employer/MDM-managed, the MDM-side decommission belongs to that organization; note it in the log.
3. Log it#
Append a row to the table below in the same PR (or the follow-up PR that completes the outside-the-repo steps).
Decommission log#
| Date | Asset | Hardware | Keys / credentials | Backups | Git SHA |
|---|---|---|---|---|---|
| 2026-07-07 | work-laptop (MBP 13” M1, A2338) |
Wiped; employer owns the Jamf/MDM-side decommission | No sops anchor or repo SSH pubkeys ever existed; Tailscale node MacBook-Pro-0432 removed via admin console |
Borg repo 5e0c4351 frozen; 90-day retention, purge ≈ 2026-10-05 |
e4c9a9cd |
| 2026-07-07 | bedford-media-macmini (Intel Mac mini, Catalina) |
Wiped (FDE volume-key destruction = cryptographic erasure) | Host age anchor removed; key is byte-identical to office mini’s, which retains it — residual risk accepted (disk wiped, no rotation). tsunami-media user key revoked via rekey (secrets.yaml 19→18 recipients). SSH pubkey + knownHosts entries removed. Tailscale node removal via admin console |
Borg repo 78538ed3 frozen; 90-day retention, purge ≈ 2026-10-05 |
a31c5d0c |