# 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)