Document SOPS age secret workflow

This commit is contained in:
juvdiaz 2026-05-26 22:58:45 -06:00
parent ffb530694c
commit 391070d440
4 changed files with 79 additions and 0 deletions

8
.gitignore vendored
View File

@ -9,5 +9,13 @@
*.zip *.zip
apps/gitea/gitea-docker-backup apps/gitea/gitea-docker-backup
# Ignore decrypted secret material
*.dec.yaml
*.decrypted.yaml
*.plain.yaml
*.secret.local.yaml
.age-key.txt
sops-age.key
# Ignore older source iterations # Ignore older source iterations
*.old *.old

6
.sops.yaml.example Normal file
View File

@ -0,0 +1,6 @@
# Copy this file to .sops.yaml after replacing the age recipient with the
# public key generated on the Debian homelab server.
creation_rules:
- path_regex: '(^|/).*\.(secret|enc)\.ya?ml$'
encrypted_regex: '^(data|stringData|values)$'
age: age1replacewithyourpublicrecipient

View File

@ -15,6 +15,8 @@ The lab is intentionally small but production-shaped:
- Argo CD continuously reconciles Kubernetes manifests from this repo - Argo CD continuously reconciles Kubernetes manifests from this repo
- a local registry stores the website and demos images built for the worker - a local registry stores the website and demos images built for the worker
architecture architecture
- SOPS with age is the committed secret-management path for future encrypted
Kubernetes secrets
- an OCI jump box provides the public edge path back into the homelab over - an OCI jump box provides the public edge path back into the homelab over
Tailscale Tailscale
@ -198,6 +200,13 @@ settings without blocking existing pods during the first rollout. After reports
are clean, individual policies can be promoted to `Enforce` in are clean, individual policies can be promoted to `Enforce` in
`bootstrap/platform/main.tf`. `bootstrap/platform/main.tf`.
## Secrets
Use SOPS with age for secrets that need to live in Git. Start from
`.sops.yaml.example`, replace the age recipient with the public key generated on
the Debian host, and commit the resulting `.sops.yaml`. Keep the private age key
outside the repo. Operational notes are in `docs/secrets.md`.
## Edge Services ## Edge Services
The OCI jump box runs the public edge path: The OCI jump box runs the public edge path:

56
docs/secrets.md Normal file
View File

@ -0,0 +1,56 @@
# Secret Management
This repo uses SOPS with age for secrets that must be stored in Git. The
encrypted files can be committed, while the age private key stays on the Debian
homelab server or in a deliberately scoped CI secret.
## First-Time Setup
Install the tools on the Debian host:
```bash
sudo apt-get update
sudo apt-get install -y --no-install-recommends age sops
```
Generate the local age identity:
```bash
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
grep '^# public key:' ~/.config/sops/age/keys.txt
```
Copy `.sops.yaml.example` to `.sops.yaml`, replace the placeholder recipient
with the printed public key, and commit `.sops.yaml`. The public recipient is
not sensitive; the private identity in `~/.config/sops/age/keys.txt` is.
## File Naming
Use one of these suffixes for encrypted YAML:
```text
*.secret.yaml
*.enc.yaml
```
For Kubernetes `Secret` manifests, keep sensitive values under `stringData` or
`data` so the example `encrypted_regex` encrypts the right fields without
obscuring resource metadata needed by Argo CD and review diffs.
## Editing
Create or edit an encrypted file:
```bash
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops apps/example/app.secret.yaml
```
Check the decrypted render locally without writing it to the repo:
```bash
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops -d apps/example/app.secret.yaml
```
Decrypted scratch files are intentionally ignored by `.gitignore`; encrypted
files are not.