This document provides templates for setting secrets in Fly.io for all Ampel applications.
NEVER commit actual secrets to version control!
This file contains templates only. Generate actual secrets using secure methods (see below).
Generate secure random secrets using OpenSSL:
# Generate 256-bit (32-byte) random keys
openssl rand -hex 32
# Generate 128-bit (16-byte) random keys
openssl rand -hex 16
# Generate base64-encoded keys
openssl rand -base64 32Set secrets for the API server (ampel-api):
# Database connection (get from `fly postgres db list --app ampel-db`)
fly secrets set \
--app ampel-api \
DATABASE_URL="postgres://postgres:<PASSWORD>@ampel-db.flycast:5432/ampel"
# Redis connection (get from `fly redis status --app ampel-redis`)
fly secrets set \
--app ampel-api \
REDIS_URL="redis://default:<PASSWORD>@ampel-redis.flycast:6379"
# JWT secret (generate with `openssl rand -hex 32`)
fly secrets set \
--app ampel-api \
JWT_SECRET="<RANDOM_256_BIT_KEY>"
# Encryption key for provider PAT tokens (generate with `openssl rand -base64 32`)
fly secrets set \
--app ampel-api \
ENCRYPTION_KEY="<RANDOM_256_BIT_KEY>"
# CORS origins (frontend URL)
fly secrets set \
--app ampel-api \
CORS_ORIGINS="https://ampel-frontend.fly.dev"Create a .env.production file (DO NOT COMMIT):
DATABASE_URL=postgres://postgres:<PASSWORD>@ampel-db.flycast:5432/ampel
REDIS_URL=redis://default:<PASSWORD>@ampel-redis.flycast:6379
JWT_SECRET=<RANDOM_256_BIT_KEY>
ENCRYPTION_KEY=<RANDOM_256_BIT_KEY>
CORS_ORIGINS=https://ampel-frontend.fly.devThen import:
fly secrets import --app ampel-api < .env.productionNote: Personal Access Tokens (PATs) are configured per-user via the UI after deployment. See PAT_SETUP.md for details.
Set secrets for the background worker (ampel-worker):
# Database connection (same as API)
fly secrets set \
--app ampel-worker \
DATABASE_URL="postgres://postgres:<PASSWORD>@ampel-db.flycast:5432/ampel"
# Redis connection (same as API)
fly secrets set \
--app ampel-worker \
REDIS_URL="redis://default:<PASSWORD>@ampel-redis.flycast:6379"
# Encryption key (MUST BE SAME AS API for token decryption)
fly secrets set \
--app ampel-worker \
ENCRYPTION_KEY="<SAME_KEY_AS_API>"Set secrets for the frontend (ampel-frontend):
# API endpoint URL
fly secrets set \
--app ampel-frontend \
VITE_API_URL="https://ampel-api.fly.dev"Note: For Vite apps, build-time environment variables must be prefixed with VITE_.
Add the Fly.io deploy token to GitHub repository secrets:
-
Generate deploy token:
fly tokens create deploy -x 999999h
-
Copy the entire output (including
FlyV1prefix) -
Go to GitHub repository → Settings → Secrets and variables → Actions
-
Create new repository secret:
- Name:
FLY_API_TOKEN - Value:
<PASTE_TOKEN_HERE>
- Name:
Rotate secrets on the following schedule:
- JWT_SECRET: Every 90 days
- ENCRYPTION_KEY: Every 180 days (requires re-encrypting provider PAT tokens)
- Database Password: Every 180 days
- Deploy Tokens: Every 365 days
Note: Provider Personal Access Tokens (PATs) are managed by users through the UI and should be rotated according to each provider's security recommendations.
- Generate new secret value
- Set new secret:
fly secrets set --app <app> <KEY>="<NEW_VALUE>" - Verify deployment:
fly status --app <app> - Update documentation
- Revoke old secret (if applicable)
Verify secrets are set correctly:
# List secret names (values are encrypted)
fly secrets list --app ampel-api
fly secrets list --app ampel-worker
fly secrets list --app ampel-frontend
# Check app logs for secret injection
fly logs --app ampel-api
# Test database connection
fly ssh console --app ampel-api -C "psql \$DATABASE_URL -c 'SELECT 1;'"
# Test Redis connection
fly ssh console --app ampel-api -C "redis-cli -u \$REDIS_URL PING"Ampel uses Personal Access Tokens (PATs) instead of OAuth for provider authentication. This provides:
- Simpler setup: No OAuth application registration required
- Better security: Users control their own tokens
- Flexibility: Per-user token management via UI
After deploying Ampel:
- Users register/login to Ampel
- Navigate to Settings → Provider Accounts
- Add provider account with PAT token
- Token is encrypted with
ENCRYPTION_KEYand stored securely
See PAT_SETUP.md for detailed instructions on creating PATs for:
- GitHub:
https://github.com/settings/tokens - GitLab:
https://gitlab.com/-/profile/personal_access_tokens - Bitbucket:
https://bitbucket.org/account/settings/app-passwords/
Required Scopes:
- GitHub:
repo(full access) orpublic_repo(public repos only) - GitLab:
read_api,read_repository - Bitbucket:
repository:read,pullrequest:read
Secrets require app restart. Fly.io automatically restarts apps when secrets are set.
Verify restart:
fly status --app ampel-api
fly logs --app ampel-apiVerify Flycast address:
fly postgres db list --app ampel-dbEnsure connection string uses .flycast domain, not .fly.dev.
Ensure ENCRYPTION_KEY is:
- Base64-encoded 32-byte key
- Same across API and Worker
- Generated with:
openssl rand -base64 32
Test decoding:
echo "YOUR_KEY" | base64 -d | wc -c
# Should output: 32- Never commit secrets - Use
.gitignorefor.env.*files - Use strong random secrets - Minimum 256-bit (32 bytes)
- Rotate regularly - Follow rotation schedule
- Store in password manager - Use 1Password, LastPass, or similar
- Limit access - Only deploy keys in CI/CD, not developer machines
- Audit regularly - Review
fly secrets listmonthly - Monitor logs - Watch for secret exposure in logs
- Use separate keys per environment - Dev, staging, production
Document Version: 1.0 Last Updated: 2025-12-22