- best-practices/: 11 topic files + INDEX.md extracted from cluster-bootstrap and custom-claude-skills (validation, k8s, helm, ansible, secrets, debugging, etc.) - settings.yaml: pipeline config (log retention, tracked projects, max logs per run) - CLAUDE.md: updated with best-practices loading and pipeline documentation - memory/log/: first session log demonstrating the format Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
42 lines
2.0 KiB
Markdown
42 lines
2.0 KiB
Markdown
# Secrets Management
|
|
|
|
## SOPS + age
|
|
|
|
SOPS with age encryption is the standard across all projects. A single `.sops.yaml` at the repo root defines path-based encryption rules.
|
|
|
|
### File Naming
|
|
|
|
- `.sops.yaml` path-based rules match specific filename patterns (e.g., `**/*secret*.yaml`)
|
|
- Non-secret files must NOT contain `secret` in their name, or the pre-commit hook will encrypt them
|
|
- KSOPS generator files should be named `ksops-generator.yaml`, not `secret-generator.yaml`
|
|
|
|
### encrypted_regex Gotcha
|
|
|
|
When using `encrypted_regex` for selective field encryption (e.g., Ansible group_vars), variable names must contain a keyword that matches the regex (e.g., `password|private_key|api_key|secret|token`). Arbitrary key names are silently left unencrypted.
|
|
|
|
### SOPS Vars Plugin
|
|
|
|
Each Ansible project needs `vars_plugins_enabled = host_group_vars,community.sops.sops` in `ansible.cfg`. Files in `group_vars/` must be named after a group (e.g., `all.sops.yaml`), not arbitrary names.
|
|
|
|
### Interactive Editor Pitfalls
|
|
|
|
- `sops <file>` opens an interactive editor — fails in non-interactive sessions
|
|
- `sops -e /tmp/file` fails when the temp path doesn't match `.sops.yaml` rules
|
|
- Multiple `sops --set` calls can corrupt files — use the interactive editor for multi-field edits
|
|
|
|
## Credential Handling
|
|
|
|
- **Never pass secrets via command-line arguments** — visible in `ps` output
|
|
- Use `@file` references, environment variables sourced at runtime, or stdin
|
|
- For Ansible, use temp files with `trap rm` cleanup: `-e "@${tmpfile}"`
|
|
- Read secrets at execution time and use them ephemerally — never cache or persist values
|
|
- Reference the **existence** of a secret file in docs, never its contents
|
|
|
|
## Bootstrap Secrets
|
|
|
|
Some secrets are chicken-and-egg (e.g., the age decryption key for ArgoCD's KSOPS). These must be created manually as a bootstrap step and documented clearly.
|
|
|
|
## Backup Considerations
|
|
|
|
Backup plans must include encryption keys (age private keys, etc.) so that encrypted data in Git repos remains recoverable.
|