265 lines
5.7 KiB
Markdown
265 lines
5.7 KiB
Markdown
# USDA Vision - Nix Flake Setup
|
|
|
|
This directory now has a Nix flake for building and developing the USDA Vision system, with ragenix for managing secrets.
|
|
|
|
## Quick Start
|
|
|
|
### Development Environment
|
|
|
|
Enter the development shell with all tools:
|
|
|
|
```bash
|
|
cd usda-vision
|
|
nix develop
|
|
```
|
|
|
|
This gives you:
|
|
- Docker & Docker Compose
|
|
- Node.js 20 with npm/pnpm
|
|
- Python 3.11 with pip/virtualenv
|
|
- Supabase CLI
|
|
- Camera SDK (automatically in `LD_LIBRARY_PATH`)
|
|
- ragenix for secrets management
|
|
- All standard utilities (jq, yq, rsync, etc.)
|
|
|
|
### Building
|
|
|
|
Build the package:
|
|
|
|
```bash
|
|
nix build
|
|
# Or explicitly:
|
|
nix build .#usda-vision
|
|
```
|
|
|
|
Build just the camera SDK:
|
|
|
|
```bash
|
|
nix build .#camera-sdk
|
|
```
|
|
|
|
## Secrets Management with ragenix
|
|
|
|
### Initial Setup
|
|
|
|
1. **Generate or use an age key**:
|
|
|
|
```bash
|
|
# Option 1: Generate a new age key
|
|
mkdir -p ~/.config/age
|
|
age-keygen -o ~/.config/age/keys.txt
|
|
|
|
# Option 2: Use your SSH key
|
|
ssh-to-age < ~/.ssh/id_ed25519.pub
|
|
# Copy the output to secrets/secrets.nix
|
|
```
|
|
|
|
2. **Add your public key** to [secrets/secrets.nix](secrets/secrets.nix):
|
|
|
|
```nix
|
|
{
|
|
publicKeys = [
|
|
"age1your_public_key_here"
|
|
# or
|
|
"ssh-ed25519 AAAA... user@host"
|
|
];
|
|
}
|
|
```
|
|
|
|
3. **Create encrypted environment files**:
|
|
|
|
```bash
|
|
nix develop # Enter dev shell first
|
|
ragenix -e secrets/env.age
|
|
```
|
|
|
|
This opens your `$EDITOR` to edit the encrypted file. Add your environment variables:
|
|
|
|
```bash
|
|
# Web environment (Vite)
|
|
VITE_SUPABASE_URL=http://exp-dash:54321
|
|
VITE_SUPABASE_ANON_KEY=your-anon-key-here
|
|
# ... etc
|
|
```
|
|
|
|
For Azure OAuth:
|
|
|
|
```bash
|
|
ragenix -e secrets/env.azure.age
|
|
```
|
|
|
|
### Using Secrets in Development
|
|
|
|
In the development shell, you can:
|
|
|
|
```bash
|
|
# Edit secrets
|
|
ragenix -e secrets/env.age
|
|
|
|
# View decrypted content (careful in shared screens!)
|
|
age -d -i ~/.config/age/keys.txt secrets/env.age
|
|
|
|
# Re-encrypt all secrets after adding a new public key
|
|
ragenix -r
|
|
```
|
|
|
|
### Using Secrets in Production (NixOS)
|
|
|
|
The flake includes a NixOS module that handles secrets automatically:
|
|
|
|
```nix
|
|
# In your NixOS configuration
|
|
{
|
|
inputs.usda-vision.url = "path:/path/to/usda-vision";
|
|
|
|
# ... in your module:
|
|
imports = [ inputs.usda-vision.nixosModules.default ];
|
|
|
|
services.usda-vision = {
|
|
enable = true;
|
|
secretsFile = config.age.secrets.usda-vision-env.path;
|
|
};
|
|
|
|
# Configure ragenix/agenix to decrypt the secrets
|
|
age.secrets.usda-vision-env = {
|
|
file = inputs.usda-vision + "/secrets/env.age";
|
|
mode = "0644";
|
|
owner = "root";
|
|
};
|
|
}
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
usda-vision/
|
|
├── flake.nix # Flake definition with outputs
|
|
├── package.nix # Main application build
|
|
├── camera-sdk.nix # Camera SDK build
|
|
├── secrets.nix # ragenix configuration
|
|
├── secrets/
|
|
│ ├── secrets.nix # Public keys
|
|
│ ├── env.age # Encrypted .env (safe to commit)
|
|
│ ├── env.azure.age # Encrypted Azure config (safe to commit)
|
|
│ └── README.md # Secrets documentation
|
|
└── ... (rest of the app)
|
|
```
|
|
|
|
## Migration from Old Setup
|
|
|
|
### Old Workflow
|
|
- Manual `.env` file management
|
|
- Secrets in plaintext (git-ignored)
|
|
- Build defined in parent `default.nix`
|
|
|
|
### New Workflow
|
|
- Encrypted `.age` files in git
|
|
- Secrets managed with ragenix
|
|
- Self-contained flake in `usda-vision/`
|
|
- Development shell with all tools
|
|
|
|
### Migration Steps
|
|
|
|
1. **Encrypt existing `.env` files**:
|
|
|
|
```bash
|
|
cd usda-vision
|
|
nix develop
|
|
|
|
# Setup your age key first (see above)
|
|
|
|
# Encrypt the main .env
|
|
ragenix -e secrets/env.age
|
|
# Paste contents of old .env file, save and exit
|
|
|
|
# Encrypt Azure config
|
|
ragenix -e secrets/env.azure.age
|
|
# Paste contents of old .env.azure file, save and exit
|
|
```
|
|
|
|
2. **Delete unencrypted files** (they're git-ignored but still local):
|
|
|
|
```bash
|
|
rm .env .env.azure management-dashboard-web-app/.env
|
|
```
|
|
|
|
3. **Commit encrypted secrets**:
|
|
|
|
```bash
|
|
git add secrets/env.age secrets/env.azure.age secrets/secrets.nix
|
|
git commit -m "Add encrypted secrets with ragenix"
|
|
```
|
|
|
|
## Benefits
|
|
|
|
### Security
|
|
- ✅ Secrets encrypted at rest
|
|
- ✅ Safe to commit to git
|
|
- ✅ Key-based access control
|
|
- ✅ Audit trail (git history)
|
|
|
|
### Development
|
|
- ✅ Reproducible environment
|
|
- ✅ All tools included
|
|
- ✅ No manual setup
|
|
- ✅ Version-locked dependencies
|
|
|
|
### Deployment
|
|
- ✅ Declarative secrets management
|
|
- ✅ Automatic decryption on NixOS
|
|
- ✅ No manual key distribution
|
|
- ✅ Clean integration with existing infrastructure
|
|
|
|
## Common Tasks
|
|
|
|
### Add a new developer
|
|
|
|
1. They generate an age key or use their SSH key
|
|
2. They send you their public key
|
|
3. You add it to `secrets/secrets.nix`
|
|
4. Re-encrypt all secrets: `ragenix -r`
|
|
5. Commit and push
|
|
|
|
### Rotate a secret
|
|
|
|
1. Edit the encrypted file: `ragenix -e secrets/env.age`
|
|
2. Update the value
|
|
3. Save and exit
|
|
4. Commit: `git commit secrets/env.age -m "Rotate API key"`
|
|
|
|
### Build without flakes
|
|
|
|
If you need to build on a system without flakes enabled:
|
|
|
|
```bash
|
|
nix-build -E '(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) { src = ./.; }).defaultNix.default'
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### "error: getting status of '...': No such file or directory"
|
|
|
|
Make sure you're in the `usda-vision` directory when running `nix develop` or `nix build`.
|
|
|
|
### "cannot decrypt: no valid identity"
|
|
|
|
Your age private key isn't found. Check:
|
|
- `~/.config/age/keys.txt` exists
|
|
- Your public key is in `secrets/secrets.nix`
|
|
- You've run `ragenix -r` after adding your key
|
|
|
|
### "experimental feature 'flakes' not enabled"
|
|
|
|
Add to `~/.config/nix/nix.conf`:
|
|
```
|
|
experimental-features = nix-command flakes
|
|
```
|
|
|
|
Or run with: `nix --experimental-features 'nix-command flakes' develop`
|
|
|
|
## Further Reading
|
|
|
|
- [Nix Flakes](https://nixos.wiki/wiki/Flakes)
|
|
- [ragenix](https://github.com/yaxitech/ragenix)
|
|
- [age encryption](https://github.com/FiloSottile/age)
|