Files
dendritic/.github/instructions/sops-secrets.instructions.md
2026-07-04 00:30:15 -05:00

4.0 KiB

description, applyTo
description applyTo
Use when working with SOPS in this repo: editing secrets, adding multiline values, changing recipients, or wiring sops-nix consumers. Captures repo conventions, safe commands, and validation habits. .sops.yaml, keys/secrets.yaml, modules/hosts/**/secrets.yaml, modules/hosts/**/*.nix, modules/programs/sops.nix, modules/features/**/*.nix, modules/services/**/*.nix

Using SOPS In This Repo

This repo treats SOPS files as the source of encrypted runtime material, and Nix code as the wiring that exposes those secrets to services. Keep those roles separate: edit secret values with SOPS, consume them through sops-nix paths, and keep recipient policy scoped to the machines or operators that actually need access.

Mental Model

  • Secrets live in encrypted YAML files; Nix modules should refer to secret paths, not decrypted values.
  • Host-only credentials belong in modules/hosts/<host>/secrets.yaml.
  • Shared credentials belong in keys/secrets.yaml only when multiple hosts intentionally consume the same material.
  • .sops.yaml controls who can decrypt each file; keep those recipient sets narrow and explicit.
  • Secret key names are an interface. Rename them only when every consumer changes in the same edit.

Editing Secrets

  • Use SOPS tooling for all value changes: sops <file>, edit-secrets, or sops set ....
  • Do not hand-edit ENC[...] payloads. That bypasses SOPS and breaks the encrypted document's integrity metadata.
  • Keep plaintext out of tracked files. Temporary plaintext files are acceptable only as local working inputs and should be removed after use.
  • Prefer SOPS_EDITOR=nvim sops <file> for interactive edits when editor choice matters.

For large or generated values, avoid putting the secret directly in shell history:

sops set --value-file <secrets-file> '["parent"]["key"]' /path/to/plaintext-value

If using inline sops set, the value argument must be valid JSON.

Multiline Values

Use YAML literal blocks for private keys, certificates, provisioner keys, and other values where newlines matter:

janus:
  ssh_user_ca_key: |-
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----
  • Use |- when the final trailing newline should be stripped.
  • Use | when the consuming program expects the final trailing newline.
  • Avoid folded style (>) for keys and certs because it rewrites line breaks.

Wiring Secrets Into Nix

  • Consume secrets through config.sops.secrets."<key>".path or config.sops.placeholder where templating requires it.
  • Do not read decrypted secret contents during Nix evaluation.
  • Set owner, group, and mode explicitly for non-root services.
  • Use path or sops.templates when a service needs a specific file layout instead of copying secret contents into the store or tracked files.
  • If moving a secret between shared and host-local files, update sops.defaultSopsFile, mysops.hostSecretFile, and every affected sops.secrets declaration together.

Recipient And Rotation Practices

  • Add dedicated .sops.yaml path_regex rules for host-local files before broad fallback rules.
  • Keep broad fallback rules conservative; do not expand them to grant casual access to every YAML or JSON file.
  • Run sops updatekeys <file> after changing recipients so data is rewrapped for the new key set.
  • Rotate or migrate in order: update recipients, re-encrypt affected files, update consumers, then validate affected hosts.

Validation Habits

After SOPS or sops-nix changes, check the contract rather than only the syntax:

  1. The expected secrets file is still selected by sops.defaultSopsFile or mysops.hostSecretFile.
  2. .sops.yaml has a specific rule for any host-local secrets.yaml touched.
  3. Secret names in YAML still match the sops.secrets."<key>" declarations.
  4. Services that need restart or reload behavior have restartUnits or reloadUnits set.
  5. Affected host evaluation/build catches missing secret keys before deployment.