add sops nix for secret management
This commit is contained in:
parent
940c4c6679
commit
2ea7f853e4
5 changed files with 207 additions and 1 deletions
58
secrets/README.md
Normal file
58
secrets/README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Secrets with sops-nix
|
||||
|
||||
This repo wires [`sops-nix`](https://github.com/Mic92/sops-nix) into the Home Manager profile so secrets are decrypted on-demand into `~/.config/secrets`. The module is enabled by default and auto-generates an Age key if one does not already exist. Only the *encrypted* payloads under `secrets/*.sops.yaml` are meant to live in git; decrypted files never leave your machine.
|
||||
|
||||
## One-time setup
|
||||
1. Ensure `age` and `sops` are available (e.g. `nix develop` or `nix profile install nixpkgs#age nixpkgs#sops`).
|
||||
2. Generate or import an Age key. Either let Home Manager create one automatically on first activation or run `age-keygen -o ~/.config/sops/age/keys.txt` yourself.
|
||||
3. Capture the public half with `age-keygen -y -f ~/.config/sops/age/keys.txt` and add it to the `recipients` list in each encrypted file (`age1…`). Commit the public key under version control or share it through your password manager so other hosts can decrypt.
|
||||
4. (Optional) Store the private key securely in macOS Keychain or 1Password (`security add-generic-password …`) so rebuilds work without manual prompts.
|
||||
|
||||
## Managing secrets
|
||||
- Declare secrets in Home Manager under `rsydn.secrets.secrets`. Each entry is forwarded to `sops.secrets.<name>` and defaults to writing `~/.config/secrets/<name>` with mode `0400`.
|
||||
- Structure encrypted data however you like (`YAML`, `JSON`, `.env`). Only the encrypted file is tracked; plaintext never leaves `sops`.
|
||||
- Keep sensitive values scoped. Per-project secrets usually live in `.env.sops` + `direnv`; long-lived device secrets belong here.
|
||||
|
||||
Example snippet for `modules/home/rsydn/secrets.nix` consumers:
|
||||
|
||||
```nix
|
||||
rsydn.secrets.secrets = {
|
||||
"openai-api-key" = {
|
||||
sopsFile = ./secrets.sops.yaml;
|
||||
path = "${config.xdg.configHome}/secrets/openai-api-key";
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Create or update secrets by running:
|
||||
|
||||
```bash
|
||||
SOPS_AGE_KEY_FILE=$HOME/.config/sops/age/keys.txt \
|
||||
sops secrets/secrets.sops.yaml
|
||||
```
|
||||
|
||||
When Home Manager activates, the secret is decrypted to the target path. Source it in Nushell with something like:
|
||||
|
||||
```nu
|
||||
let-openai-key = (open $env.XDG_CONFIG_HOME ++ "/secrets/openai-api-key" | str trim)
|
||||
```
|
||||
|
||||
Because the secret stays on disk, prefer reading it only when needed (inside commands/functions) instead of exporting it globally. For project workflows, you can also load it into env vars temporarily:
|
||||
|
||||
```nu
|
||||
def with-openai-key [cmd] {
|
||||
let key = open $env.XDG_CONFIG_HOME ++ "/secrets/openai-api-key" | str trim
|
||||
with-env { OPENAI_API_KEY: $key } { nu -c $cmd }
|
||||
}
|
||||
```
|
||||
|
||||
To attach multiple secrets at once, use structured data (e.g. a YAML mapping) and parse it with Nushell's `from yaml`.
|
||||
|
||||
## Rotating keys
|
||||
If you regenerate your Age key, re-encrypt the file with the new recipient (`sops updatekeys secrets/secrets.sops.yaml`) and re-run `darwin-rebuild --dry-run --flake .#macbook-pro` to verify the deployment. Remember to remove old recipients so machines without access can no longer decrypt.
|
||||
|
||||
## Frequently asked questions
|
||||
- **Where do encrypted files live?** In this repo under `secrets/*.sops.yaml`; they are safe to commit.
|
||||
- **Where does plaintext live?** At runtime under `~/.config/secrets/*` (managed by Home Manager). Keep permissions tight and never add these paths to git.
|
||||
- **How do I share secrets with another machine?** Copy the Age public key from that machine into the `recipients` list, re-run `sops updatekeys`, commit, then pull and rebuild on the other host.
|
||||
- **Can I keep using `.env`?** Yes—encrypt it (e.g. `secrets/project.env.sops`) and load it with `sops exec-env` inside `direnv` so per-project shells receive the decrypted variables without storing them on disk.
|
||||
Loading…
Add table
Add a link
Reference in a new issue