Sanitized for public release: - Removed all API keys, tokens, and secrets - Removed personal Discord IDs from hermes-openclaw.json - Updated git URLs to be generic placeholders - All sensitive data uses environment variable interpolation
4.2 KiB
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:
# 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:
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 → Security → API Tokens → Create Token |
TF_VAR_venice_api_key |
Venice AI API key | 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 → Create Key |
TF_VAR_discord_bot_token |
Discord bot token | Discord Dev Portal |
TF_VAR_brave_search_api_key |
Brave Search API key | Brave Search API |
TF_VAR_do_token |
DigitalOcean API token | DO API Settings |
SSH Key Setup
Hetzner
-
Generate a key (if you don't have one):
ssh-keygen -t ed25519 -C "your@email.com" -
Add to Hetzner Console:
- Go to Hetzner Console → Security → SSH Keys
- Click "Add SSH Key"
- Paste the contents of
~/.ssh/id_ed25519.pub - Give it a memorable name (e.g., "laptop-ed25519")
-
Use the name in your config:
TF_VAR_ssh_key_names='["laptop-ed25519"]'
DigitalOcean
-
Same key generation as above
-
Add to DigitalOcean:
- Go to DO Settings
- Click "Add SSH Key"
- Paste the public key contents
-
Use the fingerprint:
# 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:
# .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
-
Never commit
.envor.tfvarswith secrets- These files are in
.gitignoreby default - Double-check before committing
- These files are in
-
Use least-privilege API tokens
- Hetzner: Create project-specific tokens
- Venice: Regenerate keys periodically
-
Rotate secrets if compromised
- Hetzner: Delete old token, create new one
- Venice: Regenerate in settings
-
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:
-
Install SOPS:
brew install sopsorapt install sops -
Create an encrypted tfvars:
sops --encrypt --input-type binary --output-type binary secrets.tfvars > secrets.tfvars.encrypted -
Decrypt at apply time:
sops --decrypt secrets.tfvars.encrypted | terraform apply -var-file=-
This is overkill for solo use but useful for teams.