Environment Secrets Management

Never committing API keys: Docker secrets, dotenv-vault for encrypted .env files, CI/CD environment variable injection (GitHub Actions secrets), and runtime secret rotation.

Environment Variables and Secret Management

What you'll learn

The complete production environment variable reference, three safe secrets management strategies, and how to rotate keys without downtime.

Complete Production .env Reference

# ─── Database ───────────────────────────────────────
DATABASE_URL=postgres://paperclip:PASSWORD@postgres:5432/paperclip
USE_PGLITE=false

# ─── Authentication ──────────────────────────────────
JWT_SECRET=64-char-hex-string-from-openssl-rand-hex-32
JWT_EXPIRY=7d

# ─── LLM Providers ───────────────────────────────────
ANTHROPIC_API_KEY=sk-ant-api03-...
OPENAI_API_KEY=sk-...
GROQ_API_KEY=gsk_...

# ─── Application ─────────────────────────────────────
NODE_ENV=production
PORT=3100
APP_URL=https://your-domain.com
LOG_LEVEL=info

# ─── Heartbeat ───────────────────────────────────────
DEFAULT_HEARTBEAT_CRON=*/5 * * * *
MAX_CONCURRENT_AGENTS=10

# ─── Webhooks ────────────────────────────────────────
WEBHOOK_SECRET=generate-a-random-32-char-string

Strategy 1: Docker Secrets (Recommended for Self-Hosted)

# docker-compose.yml
secrets:
  anthropic_key:
    file: ./secrets/anthropic_key.txt
  postgres_password:
    file: ./secrets/postgres_password.txt

services:
  api:
    secrets:
      - anthropic_key
    environment:
      ANTHROPIC_API_KEY_FILE: /run/secrets/anthropic_key

Paperclip reads _FILE variants and loads from the file path:

const apiKey = process.env.ANTHROPIC_API_KEY
  ?? fs.readFileSync(process.env.ANTHROPIC_API_KEY_FILE!, 'utf8').trim();

Strategy 2: HashiCorp Vault

For enterprise environments:

# Write secrets to Vault
vault kv put secret/paperclip \
  anthropic_key="sk-ant-..." \
  postgres_password="..."

# Read at container start via Vault Agent Sidecar
# or via the Vault CLI in an entrypoint script

Strategy 3: Cloud Provider Secret Managers

Platform Service
AWS Secrets Manager / Parameter Store
GCP Secret Manager
Azure Key Vault
Fly.io flyctl secrets set
Railway Project Variables UI

For Fly.io:

fly secrets set ANTHROPIC_API_KEY=sk-ant-...
fly secrets set POSTGRES_PASSWORD=your-secure-password

Rotating API Keys Without Downtime

  1. Add the new key alongside the old one as ANTHROPIC_API_KEY_V2
  2. Update adapter_config for half the agents to use api_key_env: ANTHROPIC_API_KEY_V2
  3. Verify new key works in the next heartbeat tick
  4. Update remaining agents
  5. Remove old ANTHROPIC_API_KEY and rename V2

What Never Goes in the Database

❌ Never store ✅ Store instead
Raw API keys Env var name (api_key_env)
Database passwords In env file / secret manager
JWT secret In env file / secret manager
User passwords Hashed with bcrypt

Checkpoint ✓

Sign in for progress tracking & Q&A →