# Secrets Management OpenBoatmobile uses Terraform's native secrets handling: environment variables with the `TF_VAR_` prefix. ## Why Environment Variables? | Approach | Pros | Cons | |----------|------|------| | `TF_VAR_*` env vars | Standard Terraform, never in git, works with CI/CD | Must source before each session | | `.tfvars` file | Easy to edit | Easy to accidentally commit secrets | | HashiCorp Vault | Enterprise-grade | Complex setup, overkill for solo use | | SOPS (encrypted files) | Git-tracked encrypted secrets | Extra tooling required | We use `TF_VAR_*` because it's the Terraform standard and keeps secrets out of git by default. ## The .env File The `.env.example` template lists all configurable variables: ```bash # Copy to .env and fill in your values cp .env.example .env ``` **Never commit `.env`:** It's in `.gitignore` by default. ## Loading Secrets Before running Terraform: ```bash source .env ``` This exports all variables to your shell. Terraform automatically reads `TF_VAR_*` variables. ## Required Secrets | Variable | Description | How to Get | |----------|-------------|------------| | `TF_VAR_hcloud_token` | Hetzner API token | [Hetzner Console](https://console.hetzner.cloud/) → Security → API Tokens → Create Token | | `TF_VAR_venice_api_key` | Venice AI API key | [Venice.ai](https://venice.ai) → Settings → API Keys | | `TF_VAR_ssh_key_names` | SSH key name(s) | Name you gave the key in Hetzner Console | ## Optional Secrets | Variable | Description | How to Get | |----------|-------------|------------| | `TF_VAR_tailscale_auth_key` | Tailscale auth key | [Tailscale Admin](https://login.tailscale.com/admin/settings/keys) → Create Key | | `TF_VAR_discord_bot_token` | Discord bot token | [Discord Dev Portal](https://discord.com/developers/applications) | | `TF_VAR_brave_search_api_key` | Brave Search API key | [Brave Search API](https://api.search.brave.com/app/keys) | | `TF_VAR_do_token` | DigitalOcean API token | [DO API Settings](https://cloud.digitalocean.com/account/api/tokens) | ## SSH Key Setup ### Hetzner 1. Generate a key (if you don't have one): ```bash ssh-keygen -t ed25519 -C "your@email.com" ``` 2. Add to Hetzner Console: - Go to [Hetzner Console](https://console.hetzner.cloud/) → Security → SSH Keys - Click "Add SSH Key" - Paste the contents of `~/.ssh/id_ed25519.pub` - Give it a memorable name (e.g., "laptop-ed25519") 3. Use the name in your config: ```bash TF_VAR_ssh_key_names='["laptop-ed25519"]' ``` ### DigitalOcean 1. Same key generation as above 2. Add to DigitalOcean: - Go to [DO Settings](https://cloud.digitalocean.com/account/security) - Click "Add SSH Key" - Paste the public key contents 3. Use the fingerprint: ```bash # Get the fingerprint ssh-keygen -lf ~/.ssh/id_ed25519.pub # Example output: 256 SHA256:xxx... your@email.com (ED25519) # The fingerprint is the part after SHA256: TF_VAR_ssh_key_fingerprints='["abc123..."]' ``` ## CI/CD Integration For GitHub Actions or similar: ```yaml # .github/workflows/deploy.yml env: TF_VAR_hcloud_token: ${{ secrets.HCLOUD_TOKEN }} TF_VAR_venice_api_key: ${{ secrets.VENICE_API_KEY }} TF_VAR_ssh_key_names: '["deploy-key"]' ``` ## Security Best Practices 1. **Never commit `.env` or `.tfvars` with secrets** - These files are in `.gitignore` by default - Double-check before committing 2. **Use least-privilege API tokens** - Hetzner: Create project-specific tokens - Venice: Regenerate keys periodically 3. **Rotate secrets if compromised** - Hetzner: Delete old token, create new one - Venice: Regenerate in settings 4. **Use Tailscale for remote access** - No public HTTPS exposure - Tailnet provides encryption and auth ## Advanced: SOPS Integration For teams that want git-tracked encrypted secrets: 1. Install SOPS: `brew install sops` or `apt install sops` 2. Create an encrypted tfvars: ```bash sops --encrypt --input-type binary --output-type binary secrets.tfvars > secrets.tfvars.encrypted ``` 3. Decrypt at apply time: ```bash sops --decrypt secrets.tfvars.encrypted | terraform apply -var-file=- ``` This is overkill for solo use but useful for teams.