Add agenix secrets management
Phase 3: Encrypted secrets - Add secrets module with agenix integration - Create secrets/secrets.nix template for key definitions - Installer generates SSH key if missing - Installer creates personalized secrets.nix with user's key - Full documentation in docs/SECRETS.md Features: - Secrets encrypted with age using SSH keys - Decrypted automatically at system activation - Safe to commit .age files to git - Support for WiFi passwords, API keys, service credentials Usage: agenix -e secrets/my-secret.age age.secrets.my-secret.file = ./secrets/my-secret.age; Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
149
docs/SECRETS.md
Normal file
149
docs/SECRETS.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Secrets Management with agenix
|
||||
|
||||
Nomarchy uses [agenix](https://github.com/ryantm/agenix) for managing encrypted secrets. Secrets are encrypted with age using SSH public keys and decrypted at system activation.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Secrets are encrypted** with your SSH public key(s)
|
||||
2. **Stored in git** as `.age` files (safe to commit)
|
||||
3. **Decrypted at boot** using the host's SSH private key
|
||||
4. **Available at runtime** in `/run/agenix/`
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Get Your SSH Public Key
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
|
||||
```
|
||||
|
||||
### 2. Get the Host's SSH Public Key
|
||||
|
||||
After first boot:
|
||||
```bash
|
||||
ssh-keyscan localhost 2>/dev/null | grep ed25519
|
||||
```
|
||||
|
||||
Or from your hardware-configuration.nix's host:
|
||||
```bash
|
||||
ssh-keyscan <hostname> 2>/dev/null | grep ed25519
|
||||
```
|
||||
|
||||
### 3. Edit secrets/secrets.nix
|
||||
|
||||
```nix
|
||||
let
|
||||
user = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...";
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...";
|
||||
allKeys = [ user host ];
|
||||
in {
|
||||
"wifi-home.age".publicKeys = allKeys;
|
||||
"github-token.age".publicKeys = allKeys;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Create a Secret
|
||||
|
||||
```bash
|
||||
cd ~/.config/nomarchy
|
||||
agenix -e secrets/wifi-home.age
|
||||
```
|
||||
|
||||
This opens your editor. Enter the secret content, save, and exit.
|
||||
|
||||
### 5. Use the Secret in Your Config
|
||||
|
||||
```nix
|
||||
# In your custom module
|
||||
{ config, ... }: {
|
||||
age.secrets.wifi-home = {
|
||||
file = ./secrets/wifi-home.age;
|
||||
owner = "root";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
# Use the decrypted secret
|
||||
networking.wireless.networks."MyNetwork".pskRaw =
|
||||
"file:${config.age.secrets.wifi-home.path}";
|
||||
}
|
||||
```
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### WiFi Passwords
|
||||
|
||||
```nix
|
||||
age.secrets.wifi-password.file = ./secrets/wifi.age;
|
||||
|
||||
# For NetworkManager (wpa_supplicant)
|
||||
networking.wireless.networks."NetworkName".psk =
|
||||
builtins.readFile config.age.secrets.wifi-password.path;
|
||||
```
|
||||
|
||||
### API Keys
|
||||
|
||||
```nix
|
||||
age.secrets.github-token = {
|
||||
file = ./secrets/github-token.age;
|
||||
owner = "youruser";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
# In your shell config
|
||||
home.sessionVariables.GITHUB_TOKEN =
|
||||
"$(cat ${config.age.secrets.github-token.path})";
|
||||
```
|
||||
|
||||
### Service Credentials
|
||||
|
||||
```nix
|
||||
age.secrets.syncthing-key = {
|
||||
file = ./secrets/syncthing-key.age;
|
||||
owner = "youruser";
|
||||
};
|
||||
|
||||
services.syncthing.key = config.age.secrets.syncthing-key.path;
|
||||
```
|
||||
|
||||
## Re-keying Secrets
|
||||
|
||||
If you change hosts or keys, re-encrypt all secrets:
|
||||
|
||||
```bash
|
||||
cd ~/.config/nomarchy
|
||||
agenix --rekey
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- **Never commit unencrypted secrets**
|
||||
- Keep your SSH private key secure
|
||||
- The host's SSH key is generated during install
|
||||
- Secrets are decrypted to a tmpfs (`/run/agenix/`)
|
||||
- Consider using separate keys for different security levels
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No identity found"
|
||||
Ensure `/etc/ssh/ssh_host_ed25519_key` exists and is readable by root.
|
||||
|
||||
### "Failed to decrypt"
|
||||
Check that the host's public key is in `secrets.nix` and re-encrypt:
|
||||
```bash
|
||||
agenix --rekey
|
||||
```
|
||||
|
||||
### "Secret file not found"
|
||||
Make sure the `.age` file exists and the path in your config is correct.
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
~/.config/nomarchy/
|
||||
├── secrets/
|
||||
│ ├── secrets.nix # Key definitions
|
||||
│ ├── wifi.age # Encrypted WiFi password
|
||||
│ └── github.age # Encrypted API key
|
||||
└── flake.nix
|
||||
```
|
||||
Reference in New Issue
Block a user