Skip to content

Security & Secrets Management (SOPS + age)

This project follows a "secure by default" approach appropriate for production-style systems.


Threat model (practical)

  • secrets must not be committed in plaintext
  • CI/CD must not leak keys into logs
  • runtime services should receive secrets via Kubernetes / environment injection

Secrets management approach

  • secrets are encrypted at rest using SOPS
  • the encryption backend is age
  • encrypted files (*.enc.*) are safe to store in git
  • plaintext secrets are generated only at deploy/runtime boundaries

Examples of encrypted assets: - .env.enc - Kubernetes secrets manifests (secret.enc.yaml) - Helm values (values-dev.enc.yaml) - registry tokens (gitlab-registry-token.enc.yaml)


CI/CD handling

  • CI decrypts secrets only in the minimal scope required for deployment
  • secrets are injected via protected variables / masked CI variables
  • decrypted files are treated as ephemeral artifacts and must not persist

Best practices checklist

  • [ ] SOPS/age private keys are stored only in protected CI variables
  • [ ] CI logs do not print decrypted values
  • [ ] Kubernetes secrets are namespace-scoped and access-controlled
  • [ ] least privilege for registry tokens and service accounts
  • [ ] rotation procedure documented (see Runbooks)

Next: ADRs

Architectural security decisions are recorded in ADR: - ADR-0004 — Secrets Management