Secrets
Norn v2 uses SOPS + age for secret management. Secrets are encrypted at rest and decrypted at deploy time, then injected as environment variables into Nomad tasks.
How It Works
- Secrets are stored in a
secrets.enc.yamlfile alongside the app'sinfraspec.yaml - During the submit step of the deploy pipeline, Norn decrypts the file using SOPS
- Decrypted key-value pairs are merged into the environment variables passed to
nomad.Translate() - Nomad injects them as environment variables in the running containers
v1 vs v2
In v1, secrets were synced to Kubernetes Secrets and mounted into pods. In v2, there is no Kubernetes — secrets go directly from SOPS to Nomad environment variables during the pipeline.
Setup
1. Generate an age key
bash
age-keygen -o ~/.config/sops/age/keys.txtmacOS
SOPS on macOS looks for age keys at ~/Library/Application Support/sops/age/keys.txt. Symlink to avoid duplicating:
bash
ln -sf ~/.config/sops/age/keys.txt \
~/Library/Application\ Support/sops/age/keys.txt2. Create a .sops.yaml in the app directory
yaml
creation_rules:
- age: >-
age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3. Create and encrypt secrets
bash
# Create a plaintext file
cat > secrets.yaml <<EOF
DATABASE_URL: postgres://user:pass@host:5432/db
API_KEY: sk-1234567890
EOF
# Encrypt it
sops -e secrets.yaml > secrets.enc.yaml
rm secrets.yaml4. Declare expected keys in infraspec
yaml
secrets:
- DATABASE_URL
- API_KEYThe secrets list is informational — it tells the UI and CLI which keys to expect. The actual values come from secrets.enc.yaml.
CLI Management
bash
# List secret keys for an app
norn secrets myapp
# Set or update a secret
norn secrets set myapp DATABASE_URL=postgres://...
# Delete a secret
norn secrets delete myapp OLD_KEYThe set command decrypts the file, updates the key, and re-encrypts.