# Agenix Secret Management Guide A guide for creating and managing encrypted secrets using agenix in the nixos-config project. ## Prerequisites - SSH key pair (ed25519 or rsa) in `~/.ssh/` - Access to the nixos-config repository - Secret added to `secrets.nix` with appropriate public keys --- ## Creating a New Secret ### Step 1: Add Secret to secrets.nix Edit `secrets.nix` and add a new entry: ```nix "secrets/.age".publicKeys = systems ++ users; ``` Where: - `` is the desired filename (without `.age`) - `systems` = hosts that can decrypt this secret - `users` = users that can decrypt this secret Example: ```nix "secrets/my-service-api-key.age".publicKeys = systems ++ users; ``` ### Step 2: Create the Encrypted Secret Navigate to the nixos-config directory: ```bash cd ~/p/NIX/nixos-config ``` Generate a secure random token (if needed): ```bash head -c 32 /dev/urandom | base64 | tr -d '\n' ``` Or use a specific value: ```bash echo -n "your-secret-value-here" > /tmp/token.txt ``` Encrypt and create the secret file: ```bash cat /tmp/token.txt | RULES=./secrets.nix nix develop . --command sh -c 'agenix -e secrets/.age' ``` The `-e` flag encrypts stdin content into the age file. If no stdin is provided, agenix opens your editor. ### Step 3: Verify the Secret Decrypt to verify: ```bash RULES=./secrets.nix nix develop . --command agenix -d secrets/.age ``` You should see your secret value printed to stdout. ### Step 4: Use in NixOS Configuration Reference the secret in your service config: ```nix { config, ... }: { # For environment files environmentFiles = [ config.age.secrets."my-secret-name".path ]; # For file-based secrets environmentFile = config.age.secrets."my-secret-name".path; } ``` The secret will be available at `/run/agenix/` when the system builds. --- ## Common Patterns ### Token-Based Registration (e.g., Tuwunel) ```nix # secrets.nix "secrets/tuwunel-registration-token.age".publicKeys = systems ++ users; ``` ```nix # services/tuwunel.nix settings.global = { allow_registration = true; registration_token_file = config.age.secrets."tuwunel-registration-token".path; }; ``` ### API Keys via Environment Files ```nix # secrets.nix "secrets/my-service-env.age".publicKeys = systems ++ users; ``` Create `my-service-env.age` containing: ``` MY_SERVICE_API_KEY=your-key-here DATABASE_URL=postgres://... ``` Reference in config: ```nix environmentFiles = [ config.age.secrets."my-service-env".path ]; ``` ### File-Based Secrets For binary files or specific file paths: ```nix settings = { tls.cert = config.age.secrets."tls-cert".path; tls.key = config.age.secrets."tls-key".path; }; ``` --- ## Agenix Command Reference | Command | Description | |---------|-------------| | `agenix -e ` | Edit/create encrypted secret (opens editor or uses stdin) | | `agenix -d ` | Decrypt and print to stdout | | `agenix -r` | Re-encrypt all secrets (after changing public keys) | | `agenix --validate-config` | Validate secrets.nix syntax | ### Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `RULES` | `./secrets.nix` | Path to secrets.nix file | | `EDITOR` | `$EDITOR` | Editor for interactive editing | --- ## Troubleshooting ### "No identity found to decrypt" **Cause**: No SSH private key available. **Solution**: Ensure your private key is in `~/.ssh/`: - `~/.ssh/id_rsa` - `~/.ssh/id_ed25519` - Or specify with `-i /path/to/private/key` ### "Failed to find config root" **Cause**: Agenix can't find `secrets.nix`. **Solution**: Use `RULES=./secrets.nix` or run from the nixos-config directory. ### Rekeying Secrets After adding new public keys to `secrets.nix`, re-encrypt all secrets: ```bash cd ~/p/NIX/nixos-config RULES=./secrets.nix nix develop . --command agenix -r ``` --- ## Security Notes - Never commit plaintext secrets to git - Always use `secrets.nix` for encryption keys - Include only necessary hosts/users in public keys - Rotate secrets periodically - Use `agenix -r` after modifying public keys