Skip to main content

Secrets management

Where the ISC³ credentials live, who can read them, and where we want to take this.

Current situation

Sensitive values (BMC/iDRAC logins, PDU access, service credentials, …) live in docs/secretzone/ in this repository (ISC³) and in calc/secretzone/ for the CALC@HEI machines — the latter so they can move out with the rest of the CALC documentation. Both directories are excluded from the published site (exclude in docusaurus.config.ts), so access control is simply: whoever can read the private GitHub repository can read the secrets.

Limitations of the current scheme:

  • No granularity — repo access is all-or-nothing; there is no way to share one credential without sharing all of them.
  • Plaintext in git history — every clone carries every secret ever committed; removing a value from the file does not retract it.
  • No audit trail — nobody knows who consulted what, or when.

Target scheme (proposal)

The problem splits in two families that call for different tools:

Human-held secrets → Vaultwarden

For credentials a person reads occasionally (BMC, PDU web UI, the Infomaniak account, break-glass root): a self-hosted Vaultwarden instance, in an LXC container on Rumba next to the other services (Rumba is now a Proxmox VE node, so this becomes a container on that hypervisor).

  • Per-collection access — a Datacenter collection for the admins, narrower collections when someone (e.g. a TPI student) needs one credential and nothing else. Revoking = removing one person from one collection.
  • Zero-knowledge — encryption happens client-side; compromising the container does not expose the vault.
  • Real clients: browser extension, mobile, and the bw CLI.

Check first with the Sinf whether HES-SO already operates an institutional password manager — using it would beat self-hosting (no container to patch, no backup to own, offboarding follows the identity lifecycle).

Machine-consumed secrets → SOPS + age

For anything the Ansible playbooks inject, and as the direct upgrade path for secretzone/: SOPS with age keys.

  • Values are encrypted in place inside YAML/JSON files, which stay diffable and reviewable in git.
  • Each admin holds an age keypair listed as a recipient in .sops.yaml; adding someone is a re-encrypt, not a re-share.
  • Integrates with Ansible through the community.sops collection.
  • Prefer this over ansible-vault, whose single shared passphrase has no per-user identity — one person leaving means rotating for everyone.

The wiki pages then reference credentials by name and the encrypted files hold the values.

Break-glass set

The disaster recovery plans have a bootstrap problem : credentials needed to rebuild the datacenter must not live only in a service running in that datacenter. Keep a sealed offline copy (paper or encrypted USB, in a safe) of:

  • BMC / iDRAC access for the core machines
  • Hypervisor and storage root access
  • The vault's own recovery key

Migration checklist

  • Decide: Vaultwarden on Rumba vs. institutional service — self-hosted on rumba, deployed 2026-08-04 (service page)
  • Create the organization, its collections and enroll the admins — the vault runs, but holds nothing shared yet: first-time setup
  • Move human-held credentials out of secretzone/, rotating each value as it moves — the old values remain in git history and on every clone
  • Introduce SOPS + age for the Ansible-consumed values
  • Write and seal the break-glass set
  • Retire secretzone/ (keep the non-secret prose in the regular pages)