Retire Ansible Vault (last step, after P7/P8/R) #120

Open
opened 2026-10-13 14:25:43 -04:00 by jfraeys · 1 comment
Owner

Status 2026-10-13: not started; blocked on #117 (P8), #118 (P7) and #119 (R). Nothing in this list has been touched, and nothing should be until those are Met and the end-to-end check below passes.

Do this last, only after P7, P8 and R are Met. Full checklist: docs/secrets-management-sops.md, section "Retiring Ansible Vault". Until then every Ansible Vault fallback is the way back.

Prerequisites (each must be true before any deletion):

  • Acceptance chain from a simulated new workstation, with the recovery key from its actual offline copy (Bitwarden item sops-age-recovery-infra), not Keychain: recover key, decrypt, run Ansible against staging.
  • rotate-secret.sh proven on the real vault (see the P8 issue).
  • Staging-validate green end to end on main, CI green, a fresh-clone recovery drill passes.
  • Decide the fate of secrets/backup/ (see the R issue).

Then, in one PR, remove together (removing one config line without its pair breaks startup):

  • vault_password_file in ansible.cfg and ansible-profile.cfg, the dummy ANSIBLE_VAULT_PASSWORD_FILE in .forgejo/workflows/lint.yml, packer/ci-runner/ci-runner.pkr.hcl, roles/ci_ephemeral_provisioner/tasks/main.yml (+ its CLAUDE.md), playbooks/rotate-secret.yml (vault_pass_file).
  • The Ansible Vault branches in setup, scripts/lib/common-vault.sh, scripts/lib/setup/vault.sh, scripts/lib/manage/core.sh, rotate-secret.sh, rotate-ovh-s3-credentials.sh, regenerate-ci-ephemeral-ssh-key.sh, verify-vaultwarden-token.sh, deploy-services.sh, init-vaultwarden.sh.
  • Files and credentials: secrets/vault.yml.ansible-vault, secrets/.vault_pass, the ansible-vault/infra Keychain item, the Bitwarden ansible-vault password item, the Tier-1 row in docs/secrets-recovery.md.
  • Docs: docs/runbooks/vault-lockout.md (legacy) and the remaining ansible-vault mentions.
  • Run staging-validate and lint after, before deleting the old password from anywhere.
**Status 2026-10-13: not started; blocked on #117 (P8), #118 (P7) and #119 (R).** Nothing in this list has been touched, and nothing should be until those are Met and the end-to-end check below passes. Do this last, only after P7, P8 and R are Met. Full checklist: `docs/secrets-management-sops.md`, section "Retiring Ansible Vault". Until then every Ansible Vault fallback is the way back. Prerequisites (each must be true before any deletion): - [ ] Acceptance chain from a simulated new workstation, with the recovery key from its actual offline copy (Bitwarden item `sops-age-recovery-infra`), not Keychain: recover key, decrypt, run Ansible against staging. - [ ] `rotate-secret.sh` proven on the real vault (see the P8 issue). - [ ] Staging-validate green end to end on `main`, CI green, a fresh-clone recovery drill passes. - [ ] Decide the fate of `secrets/backup/` (see the R issue). Then, in one PR, remove together (removing one config line without its pair breaks startup): - [ ] `vault_password_file` in `ansible.cfg` and `ansible-profile.cfg`, the dummy `ANSIBLE_VAULT_PASSWORD_FILE` in `.forgejo/workflows/lint.yml`, `packer/ci-runner/ci-runner.pkr.hcl`, `roles/ci_ephemeral_provisioner/tasks/main.yml` (+ its CLAUDE.md), `playbooks/rotate-secret.yml` (`vault_pass_file`). - [ ] The Ansible Vault branches in `setup`, `scripts/lib/common-vault.sh`, `scripts/lib/setup/vault.sh`, `scripts/lib/manage/core.sh`, `rotate-secret.sh`, `rotate-ovh-s3-credentials.sh`, `regenerate-ci-ephemeral-ssh-key.sh`, `verify-vaultwarden-token.sh`, `deploy-services.sh`, `init-vaultwarden.sh`. - [ ] Files and credentials: `secrets/vault.yml.ansible-vault`, `secrets/.vault_pass`, the `ansible-vault`/`infra` Keychain item, the Bitwarden ansible-vault password item, the Tier-1 row in `docs/secrets-recovery.md`. - [ ] Docs: `docs/runbooks/vault-lockout.md` (legacy) and the remaining `ansible-vault` mentions. - [ ] Run `staging-validate` and lint after, before deleting the old password from anywhere.
Author
Owner

Add to the retirement checklist (found 2026-10-14 while sorting migration vs long-term scripts):

  • scripts/init-vaultwarden.sh and scripts/verify-vaultwarden-token.sh still reference secrets/vault.yml (Ansible Vault era). Decide per script: port to vault-set.py / the SOPS vault, or delete. Not verified whether either still works.
  • scripts/with-vault.sh: the bridge that decrypts SOPS into the secrets/vault.yml file the playbooks include_vars. Stays until the playbooks read SOPS-derived vars directly; remove with the last vault.yml consumer (see the note in scripts/deploy-services.sh).
  • Stale headers that still say vault.yml: scripts/gen-auth-secrets.sh (still used by init-secrets.sh and gen-staging-secrets.py, so keep the script, fix the header) and scripts/rotate-secret.sh.
  • scripts/check-secret-hygiene.py forbids secrets/vault.yml and secrets/backup/*; keep those rules after retirement.
  • secrets/backup/ (pre-cutover ciphertext): see #119 for the delete-the-password-first decision.
**Add to the retirement checklist (found 2026-10-14 while sorting migration vs long-term scripts):** - [ ] `scripts/init-vaultwarden.sh` and `scripts/verify-vaultwarden-token.sh` still reference `secrets/vault.yml` (Ansible Vault era). Decide per script: port to `vault-set.py` / the SOPS vault, or delete. Not verified whether either still works. - [ ] `scripts/with-vault.sh`: the bridge that decrypts SOPS into the `secrets/vault.yml` file the playbooks `include_vars`. Stays until the playbooks read SOPS-derived vars directly; remove with the last `vault.yml` consumer (see the note in `scripts/deploy-services.sh`). - [ ] Stale headers that still say `vault.yml`: `scripts/gen-auth-secrets.sh` (still used by `init-secrets.sh` and `gen-staging-secrets.py`, so keep the script, fix the header) and `scripts/rotate-secret.sh`. - [ ] `scripts/check-secret-hygiene.py` forbids `secrets/vault.yml` and `secrets/backup/*`; keep those rules after retirement. - [ ] `secrets/backup/` (pre-cutover ciphertext): see #119 for the delete-the-password-first decision.
Sign in to join this conversation.
No labels
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.

Dependencies

No dependencies set

Reference
jfraeys/infra#120
No description provided.