110 lines
3.1 KiB
Markdown
110 lines
3.1 KiB
Markdown
# Secrets Management
|
|
|
|
Layered approach to secrets in dev-env. None of this is enforced by the
|
|
module — these are conventions that pair well with the dev-env layout.
|
|
|
|
| Context | Tool | Storage |
|
|
|---|---|---|
|
|
| Local dev | `pass` | `~/.password-store` (GPG encrypted) |
|
|
| NixOS servers | `sops-nix` + `age` | Encrypted in git |
|
|
| Repo secrets | `git-crypt` or `.sops.yaml` | Encrypted files in repo |
|
|
|
|
The shared pre-commit hook (installed by `dev-env.gitHooks.enable`)
|
|
refuses to commit common secret patterns and unencrypted sops files.
|
|
See `dev-env/scripts/git-hooks/pre-commit` for the patterns.
|
|
|
|
## Local dev with `pass`
|
|
|
|
```bash
|
|
# pass is in dev-env's package set; gpg is in omni's defaults
|
|
gpg --gen-key # if you don't have one
|
|
pass init "your-email@example.com"
|
|
|
|
pass insert dev/lnbits/admin-key
|
|
pass insert dev/postgres/password
|
|
pass insert dev/bitcoin/rpc-password
|
|
|
|
pass dev/lnbits/admin-key # print
|
|
pass -c dev/lnbits/admin-key # to clipboard (clears after 45s)
|
|
export LNBITS_ADMIN_KEY=$(pass dev/lnbits/admin-key) # in scripts
|
|
```
|
|
|
|
## Server secrets with sops-nix
|
|
|
|
### Initial setup
|
|
|
|
```bash
|
|
age-keygen -o ~/.config/sops/age/keys.txt # generate your key
|
|
age-keygen -y ~/.config/sops/age/keys.txt # show your public key
|
|
# age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
```
|
|
|
|
### Per-project
|
|
|
|
In each deploy host directory:
|
|
|
|
```bash
|
|
cd ~/dev/deploy/unified/hosts/host5
|
|
|
|
cat > .sops.yaml << EOF
|
|
keys:
|
|
- &admin age1xxx... # you
|
|
- &host5 age1yyy... # the server's key
|
|
|
|
creation_rules:
|
|
- path_regex: secrets/host5\.yaml$
|
|
key_groups:
|
|
- age:
|
|
- *admin
|
|
- *host5
|
|
EOF
|
|
|
|
mkdir -p secrets
|
|
nvim secrets/host5.yaml # write the unencrypted file
|
|
sops -e -i secrets/host5.yaml # encrypt in place
|
|
```
|
|
|
|
The pre-commit hook will refuse to commit `secrets/host5.yaml` if it's
|
|
not encrypted. (False positive? `git commit --no-verify`.)
|
|
|
|
### Using in NixOS
|
|
|
|
```nix
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
imports = [ inputs.sops-nix.nixosModules.sops ];
|
|
|
|
sops.defaultSopsFile = ./secrets/host5.yaml;
|
|
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
|
|
|
sops.secrets."lnbits/admin_key" = {};
|
|
sops.secrets."postgres/password" = {};
|
|
|
|
services.lnbits = {
|
|
adminKeyFile = config.sops.secrets."lnbits/admin_key".path;
|
|
};
|
|
}
|
|
```
|
|
|
|
### Bootstrapping a server's age key
|
|
|
|
On each NixOS host (one-time):
|
|
|
|
```bash
|
|
sudo mkdir -p /var/lib/sops-nix
|
|
sudo age-keygen -o /var/lib/sops-nix/key.txt
|
|
sudo chmod 600 /var/lib/sops-nix/key.txt
|
|
sudo age-keygen -y /var/lib/sops-nix/key.txt # add to .sops.yaml
|
|
```
|
|
|
|
## Best practices
|
|
|
|
1. **Never commit unencrypted secrets.** The pre-commit hook helps but
|
|
isn't a substitute for paying attention.
|
|
2. **Rotate after team changes** — especially when removing keys.
|
|
3. **Different secrets per environment.** staging ≠ production.
|
|
4. **Backup your master keys.** GPG and age private keys are the only
|
|
thing standing between you and a total loss.
|
|
5. **No secrets in `.devenv.conf` / `/etc/dev-env/config.sh`.** Those
|
|
files are world-readable.
|