Files
blackroad-operating-system/ENV_VARS.md
Claude 2a8f12d5cb chore: phase 1 infrastructure implementation
Implement Phase 1 infrastructure from master orchestration plan.
This commit delivers production-ready deployment infrastructure,
comprehensive documentation, and workflow automation.

**Cloudflare DNS Infrastructure:**
- Add records.yaml with complete DNS config for all domains
- Add migrate_to_cloudflare.md with step-by-step migration guide
- Add cloudflare_dns_sync.py for automated DNS synchronization
- Update CLOUDFLARE_DNS_BLUEPRINT.md with implementation references

**Environment Variable Documentation:**
- Add ENV_VARS.md with comprehensive variable reference
- Document all services: Railway, GitHub Actions, Cloudflare, local
- Include security best practices and validation scripts
- Add troubleshooting guides and quick-start templates

**GitHub Actions Workflows:**
- Add railway-deploy-template.yml for Railway deployments
- Add frontend-deploy-template.yml for static site deployments
- Add codeql-analysis-template.yml for security scanning
- Add comprehensive-ci-template.yml for complete CI pipeline
- Add .github/dependabot.yml for automated dependency updates

**Frontend Infrastructure:**
- Add infra/frontend/LANDING_PAGE_PLAN.md with detailed implementation plan
- Include page structure, design system, content guidelines
- Document deployment options (GitHub Pages, Railway, Cloudflare Pages)

**Master Orchestration Updates:**
- Update MASTER_ORCHESTRATION_PLAN.md with implementation file references
- Add Phase 1 implementation checklist
- Document immediate, short-term, and medium-term next steps

**Impact:**
This implementation enables:
- Automated DNS management across 10+ domains
- Secure, documented deployment workflows
- Consistent environment configuration
- Automated security scanning and dependency updates
- Clear path to production for landing page

**Next Steps for Operator:**
1. Migrate DNS to Cloudflare using migrate_to_cloudflare.md
2. Configure GitHub and Railway secrets
3. Deploy backend with custom domains
4. Implement landing page using LANDING_PAGE_PLAN.md

Refs: #55 (Master Orchestration Prompt)
2025-11-18 02:51:52 +00:00

794 lines
18 KiB
Markdown

# Environment Variables Documentation
**Version:** 1.0
**Date:** 2025-11-18
**Purpose:** Complete reference for all environment variables across BlackRoad OS infrastructure
---
## Overview
This document provides the **complete list** of environment variables used across the BlackRoad OS ecosystem. It covers:
- **Required variables** for core functionality
- **Optional variables** for integrations and features
- **Where to set them** (Railway, GitHub Actions, local development)
- **How to generate secret values** safely
- **Security best practices**
---
## Table of Contents
1. [Core Application](#core-application)
2. [Database & Cache](#database--cache)
3. [Authentication & Security](#authentication--security)
4. [API Integrations](#api-integrations)
5. [Infrastructure](#infrastructure)
6. [Deployment](#deployment)
7. [Observability](#observability)
8. [Where to Set Variables](#where-to-set-variables)
9. [Security Best Practices](#security-best-practices)
10. [Quick Start Templates](#quick-start-templates)
---
## Core Application
### ENVIRONMENT
**Required:** Yes
**Default:** `development`
**Valid values:** `development`, `staging`, `production`
**Description:** Runtime environment identifier
**Where to set:**
- **Railway (production):** `production`
- **Railway (staging):** `staging`
- **Local:** `development`
**Example:**
```bash
ENVIRONMENT=production
```
### DEBUG
**Required:** No
**Default:** `False`
**Valid values:** `True`, `False`
**Description:** Enable debug mode (verbose logging, stack traces)
**⚠️ Security Warning:** MUST be `False` in production!
**Where to set:**
- **Railway:** `False`
- **Local:** `True` (for development)
**Example:**
```bash
DEBUG=False
```
### SECRET_KEY
**Required:** Yes
**Description:** Secret key for signing sessions, JWT tokens, and encryption
**How to generate:**
```bash
# Option 1: Using openssl
openssl rand -hex 32
# Option 2: Using Python
python -c "import secrets; print(secrets.token_hex(32))"
```
**⚠️ Security:**
- MUST be unique per environment (production ≠ staging ≠ local)
- MUST be at least 32 characters
- NEVER commit to git
- Rotate quarterly or after suspected compromise
**Where to set:**
- **Railway (production):** Generate unique value
- **Railway (staging):** Generate different unique value
- **Local:** Generate local value (in `.env`, gitignored)
**Example:**
```bash
SECRET_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
```
### API_BASE_URL
**Required:** Yes
**Description:** Public URL for the backend API (used by frontend for API calls)
**Where to set:**
- **Railway (production):** `https://os.blackroad.systems`
- **Railway (staging):** `https://staging.blackroad.systems`
- **Local:** `http://localhost:8000`
**Example:**
```bash
API_BASE_URL=https://os.blackroad.systems
```
### FRONTEND_URL
**Required:** Yes
**Description:** Public URL for the frontend (used for CORS, redirects, emails)
**Where to set:**
- **Railway (production):** `https://os.blackroad.systems`
- **Railway (staging):** `https://staging.blackroad.systems`
- **Local:** `http://localhost:8000`
**Example:**
```bash
FRONTEND_URL=https://os.blackroad.systems
```
### ALLOWED_ORIGINS
**Required:** Yes
**Description:** Comma-separated list of allowed CORS origins
**Where to set:**
- **Railway (production):** `https://os.blackroad.systems,https://blackroad.ai,https://blackroad.network`
- **Railway (staging):** `https://staging.blackroad.systems`
- **Local:** `http://localhost:8000,http://localhost:3000`
**Example:**
```bash
ALLOWED_ORIGINS=https://os.blackroad.systems,https://blackroad.ai
```
### PORT
**Required:** No (Railway auto-detects)
**Default:** `8000`
**Description:** HTTP port for the backend server
**Where to set:**
- **Railway:** Not needed (Railway sets `$PORT` automatically)
- **Local:** `8000` (or any available port)
**Example:**
```bash
PORT=8000
```
---
## Database & Cache
### DATABASE_URL
**Required:** Yes
**Description:** PostgreSQL connection string (sync driver)
**Format:** `postgresql://user:password@host:port/database`
**Where to set:**
- **Railway:** Auto-injected via `${{Postgres.DATABASE_URL}}`
- **Local:** `postgresql://user:pass@localhost:5432/blackroad_dev`
**Example:**
```bash
DATABASE_URL=postgresql://user:password@localhost:5432/blackroad_dev
```
**How to use Railway reference:**
In Railway dashboard → Service → Variables:
```
DATABASE_URL=${{Postgres.DATABASE_URL}}
```
### DATABASE_ASYNC_URL
**Required:** Yes (for async database operations)
**Description:** PostgreSQL connection string (async driver)
**Format:** `postgresql+asyncpg://user:password@host:port/database`
**Where to set:**
- **Railway:** Convert `DATABASE_URL` to async:
```
DATABASE_ASYNC_URL=${{Postgres.DATABASE_URL_ASYNC}}
```
Or manually construct:
```bash
# If Railway doesn't provide async URL, derive from sync URL
# Replace 'postgresql://' with 'postgresql+asyncpg://'
```
- **Local:** `postgresql+asyncpg://user:pass@localhost:5432/blackroad_dev`
**Example:**
```bash
DATABASE_ASYNC_URL=postgresql+asyncpg://user:password@localhost:5432/blackroad_dev
```
### REDIS_URL
**Required:** Yes
**Description:** Redis connection string for caching and sessions
**Format:** `redis://host:port/db` or `redis://user:password@host:port/db`
**Where to set:**
- **Railway:** Auto-injected via `${{Redis.REDIS_URL}}`
- **Local:** `redis://localhost:6379/0`
**Example:**
```bash
REDIS_URL=redis://localhost:6379/0
```
**How to use Railway reference:**
In Railway dashboard → Service → Variables:
```
REDIS_URL=${{Redis.REDIS_URL}}
```
---
## Authentication & Security
### ACCESS_TOKEN_EXPIRE_MINUTES
**Required:** No
**Default:** `30`
**Description:** JWT access token expiration time (in minutes)
**Recommended values:**
- **Production:** `15` - `30` (shorter = more secure)
- **Development:** `60` - `120` (longer = less login friction)
**Example:**
```bash
ACCESS_TOKEN_EXPIRE_MINUTES=30
```
### REFRESH_TOKEN_EXPIRE_DAYS
**Required:** No
**Default:** `7`
**Description:** JWT refresh token expiration time (in days)
**Recommended values:**
- **Production:** `7` - `14`
- **Development:** `30`
**Example:**
```bash
REFRESH_TOKEN_EXPIRE_DAYS=7
```
### WALLET_MASTER_KEY
**Required:** Yes (for blockchain features)
**Description:** Master key for wallet/blockchain operations
**How to generate:**
```bash
openssl rand -hex 32
```
**⚠️ Security:**
- CRITICAL: Losing this key means losing access to blockchain wallets
- Backup securely (encrypted password manager, hardware security module)
- NEVER expose in logs or error messages
**Example:**
```bash
WALLET_MASTER_KEY=your-generated-master-key-here
```
---
## API Integrations
### OPENAI_API_KEY
**Required:** For AI features (Lucidia, agents)
**Description:** OpenAI API key for GPT models
**How to get:**
1. Go to https://platform.openai.com/api-keys
2. Create new secret key
3. Copy key (starts with `sk-`)
**Example:**
```bash
OPENAI_API_KEY=sk-proj-1234567890abcdef...
```
### ANTHROPIC_API_KEY
**Required:** For Claude integration
**Description:** Anthropic API key for Claude models
**How to get:**
1. Go to https://console.anthropic.com/settings/keys
2. Create new API key
3. Copy key
**Example:**
```bash
ANTHROPIC_API_KEY=sk-ant-1234567890abcdef...
```
### GITHUB_TOKEN
**Required:** For GitHub integrations (agents, automation)
**Description:** GitHub Personal Access Token (PAT)
**How to get:**
1. Go to https://github.com/settings/tokens
2. Generate new token (classic or fine-grained)
3. Required scopes: `repo`, `workflow`, `read:org`
**Example:**
```bash
GITHUB_TOKEN=ghp_1234567890abcdefghijklmnopqrstuvwxyz
```
### STRIPE_SECRET_KEY
**Required:** For payment features
**Description:** Stripe API secret key
**How to get:**
1. Go to https://dashboard.stripe.com/apikeys
2. Copy "Secret key" (starts with `sk_test_` or `sk_live_`)
**⚠️ Use test key for development:**
```bash
# Development/Staging
STRIPE_SECRET_KEY=sk_test_...
# Production
STRIPE_SECRET_KEY=sk_live_...
```
### STRIPE_PUBLISHABLE_KEY
**Required:** For frontend payment UI
**Description:** Stripe publishable key (safe to expose in frontend)
**Example:**
```bash
STRIPE_PUBLISHABLE_KEY=pk_test_1234567890abcdef...
```
### AWS_ACCESS_KEY_ID
**Required:** For AWS S3 storage
**Description:** AWS IAM access key ID
**How to get:**
1. AWS Console → IAM → Users → Security Credentials
2. Create access key
3. Download/save credentials
**Example:**
```bash
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
```
### AWS_SECRET_ACCESS_KEY
**Required:** For AWS S3 storage
**Description:** AWS IAM secret access key
**Example:**
```bash
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```
### AWS_S3_BUCKET
**Required:** For AWS S3 storage
**Description:** S3 bucket name for file uploads
**Example:**
```bash
AWS_S3_BUCKET=blackroad-uploads-production
```
### AWS_REGION
**Required:** For AWS S3 storage
**Default:** `us-east-1`
**Description:** AWS region for S3 bucket
**Example:**
```bash
AWS_REGION=us-east-1
```
---
## Infrastructure
### CF_API_TOKEN
**Required:** For Cloudflare automation
**Description:** Cloudflare API token for DNS/cache management
**How to get:**
1. Cloudflare dashboard → My Profile → API Tokens
2. Create token with "Zone.DNS" edit permissions
3. Copy token
**Where to set:**
- **GitHub Actions:** As secret `CF_API_TOKEN`
- **Local:** Export when running DNS scripts
**Example:**
```bash
CF_API_TOKEN=your-cloudflare-api-token
```
### CF_ZONE_ID
**Required:** For Cloudflare automation
**Description:** Cloudflare zone ID for a specific domain
**How to get:**
1. Cloudflare dashboard → Select domain
2. Overview page → Right sidebar → Zone ID
**Where to set:**
- **GitHub Actions:** As secret `CF_ZONE_ID`
- **records.yaml:** In domain configuration
**Example:**
```bash
CF_ZONE_ID=1234567890abcdef1234567890abcdef
```
### RAILWAY_TOKEN
**Required:** For Railway CLI/CI deployments
**Description:** Railway API token for deployments
**How to get:**
```bash
railway login
railway tokens create
```
**Where to set:**
- **GitHub Actions:** As secret `RAILWAY_TOKEN`
- **Local:** Export when using Railway CLI
**Example:**
```bash
RAILWAY_TOKEN=your-railway-api-token
```
### RAILWAY_SERVICE_ID
**Required:** For specific service deployments
**Description:** Railway service ID to deploy to
**How to get:**
1. Railway dashboard → Service → Settings
2. Copy Service ID
**Where to set:**
- **GitHub Actions:** As repository variable
**Example:**
```bash
RAILWAY_SERVICE_ID=abc123def456
```
---
## Deployment
### SENTRY_DSN
**Required:** For error monitoring
**Description:** Sentry Data Source Name for error tracking
**How to get:**
1. Go to https://sentry.io
2. Create new project
3. Copy DSN from project settings
**Example:**
```bash
SENTRY_DSN=https://1234567890abcdef@o123456.ingest.sentry.io/1234567
```
### SENTRY_ENVIRONMENT
**Required:** No (if using SENTRY_DSN)
**Default:** Uses `ENVIRONMENT` value
**Description:** Sentry environment tag
**Example:**
```bash
SENTRY_ENVIRONMENT=production
```
---
## Observability
### LOG_LEVEL
**Required:** No
**Default:** `INFO`
**Valid values:** `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
**Description:** Application logging level
**Recommended:**
- **Production:** `WARNING` or `INFO`
- **Staging:** `INFO` or `DEBUG`
- **Development:** `DEBUG`
**Example:**
```bash
LOG_LEVEL=INFO
```
---
## Where to Set Variables
### Railway (Production & Staging)
1. Go to Railway dashboard → Your project
2. Select service (e.g., `backend`)
3. Go to **Variables** tab
4. Click **New Variable**
5. Enter name and value
6. Click **Add**
**Railway Reference Variables:**
Use `${{ServiceName.VARIABLE}}` to reference values from other services:
```
DATABASE_URL=${{Postgres.DATABASE_URL}}
REDIS_URL=${{Redis.REDIS_URL}}
```
**Shared Variables:**
For variables used across services, use **Shared Variables**:
1. Variables tab → **Shared Variables**
2. Add variable (e.g., `SECRET_KEY`)
3. All services can access
### GitHub Actions
1. Go to repository → Settings → Secrets and variables → Actions
2. Click **New repository secret**
3. Enter name and value
4. Click **Add secret**
**Required GitHub Secrets:**
- `RAILWAY_TOKEN` - For Railway deployments
- `CF_API_TOKEN` - For DNS automation
- `SENTRY_DSN` - For error monitoring (optional)
**How to use in workflows:**
```yaml
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
```
### Local Development
1. Copy environment template:
```bash
cp backend/.env.example backend/.env
```
2. Edit `.env` file with your local values:
```bash
nano backend/.env # or use your preferred editor
```
3. The `.env` file is gitignored - safe to add real values
4. FastAPI automatically loads `.env` via `python-dotenv`
**⚠️ Never commit `.env` files to git!**
---
## Security Best Practices
### 1. Secret Generation
- **Always use cryptographically secure random generators**
- Minimum 32 characters for secrets
- Use different secrets per environment
**Good:**
```bash
openssl rand -hex 32
python -c "import secrets; print(secrets.token_hex(32))"
```
**Bad:**
```bash
# Don't use predictable values
SECRET_KEY=password123
SECRET_KEY=my-app-secret
```
### 2. Secret Storage
- ✅ Railway environment variables (encrypted at rest)
- ✅ GitHub Actions secrets (encrypted)
- ✅ `.env` files (gitignored)
- ✅ Password managers (1Password, LastPass, Bitwarden)
- ❌ NEVER commit secrets to git
- ❌ NEVER hardcode in source code
- ❌ NEVER expose in logs or error messages
### 3. Secret Rotation
- Rotate `SECRET_KEY` quarterly
- Rotate API keys after suspected compromise
- Update credentials after team member departure
- Keep backups of old secrets (for rollback)
### 4. Principle of Least Privilege
- Give each service only the permissions it needs
- Use separate database users for different services
- Use read-only API keys where possible
- Limit token scopes (GitHub, Stripe, etc.)
### 5. Verification
Before deploying to production:
- [ ] All required variables are set
- [ ] No placeholder values (e.g., `REPLACE_ME`)
- [ ] Secrets are unique per environment
- [ ] `DEBUG=False` in production
- [ ] CORS origins match production domains
- [ ] Database backups are configured
---
## Quick Start Templates
### Production Railway (backend service)
```bash
# Core
ENVIRONMENT=production
DEBUG=False
SECRET_KEY=[generate-unique-32-char-string]
API_BASE_URL=https://os.blackroad.systems
FRONTEND_URL=https://os.blackroad.systems
ALLOWED_ORIGINS=https://os.blackroad.systems,https://blackroad.ai
# Database (auto-injected by Railway)
DATABASE_URL=${{Postgres.DATABASE_URL}}
DATABASE_ASYNC_URL=${{Postgres.DATABASE_URL_ASYNC}}
REDIS_URL=${{Redis.REDIS_URL}}
# Auth
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
WALLET_MASTER_KEY=[generate-unique-32-char-string]
# AI (add when ready)
# OPENAI_API_KEY=sk-proj-...
# ANTHROPIC_API_KEY=sk-ant-...
# Observability (add when ready)
# SENTRY_DSN=https://...
# LOG_LEVEL=WARNING
```
### Local Development (.env)
```bash
# Core
ENVIRONMENT=development
DEBUG=True
SECRET_KEY=local-dev-secret-key-not-for-production
API_BASE_URL=http://localhost:8000
FRONTEND_URL=http://localhost:8000
ALLOWED_ORIGINS=http://localhost:8000,http://localhost:3000
# Database (Docker Compose)
DATABASE_URL=postgresql://blackroad:blackroad@localhost:5432/blackroad_dev
DATABASE_ASYNC_URL=postgresql+asyncpg://blackroad:blackroad@localhost:5432/blackroad_dev
REDIS_URL=redis://localhost:6379/0
# Auth
ACCESS_TOKEN_EXPIRE_MINUTES=120
REFRESH_TOKEN_EXPIRE_DAYS=30
WALLET_MASTER_KEY=local-dev-wallet-key
# AI (optional - use your own keys)
# OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-ant-...
```
### GitHub Actions Secrets
```bash
# Required
RAILWAY_TOKEN=[get-from-railway-cli]
CF_API_TOKEN=[get-from-cloudflare]
# Optional
SENTRY_DSN=[get-from-sentry]
```
---
## Validation Script
Use this script to validate your environment variables:
```bash
#!/bin/bash
# File: scripts/validate_env.sh
set -e
echo "Validating environment variables..."
# Check required variables
REQUIRED_VARS=(
"ENVIRONMENT"
"SECRET_KEY"
"DATABASE_URL"
"REDIS_URL"
"API_BASE_URL"
"FRONTEND_URL"
"ALLOWED_ORIGINS"
)
MISSING_VARS=()
for VAR in "${REQUIRED_VARS[@]}"; do
if [ -z "${!VAR}" ]; then
MISSING_VARS+=("$VAR")
fi
done
if [ ${#MISSING_VARS[@]} -gt 0 ]; then
echo "❌ Missing required environment variables:"
printf ' - %s\n' "${MISSING_VARS[@]}"
exit 1
fi
# Check SECRET_KEY length
if [ ${#SECRET_KEY} -lt 32 ]; then
echo "❌ SECRET_KEY must be at least 32 characters"
exit 1
fi
# Check DEBUG in production
if [ "$ENVIRONMENT" = "production" ] && [ "$DEBUG" = "True" ]; then
echo "⚠️ WARNING: DEBUG=True in production environment!"
exit 1
fi
echo "✅ Environment variables validated successfully!"
```
**Run before deploy:**
```bash
chmod +x scripts/validate_env.sh
source backend/.env && ./scripts/validate_env.sh
```
---
## Troubleshooting
### Variable Not Loading
**Problem:** Application doesn't see environment variable
**Solutions:**
1. **Railway:** Check service Variables tab - is variable set?
2. **Local:** Is `.env` file in correct location (`backend/.env`)?
3. **Restart:** Restart application after changing variables
4. **Syntax:** Check for typos in variable names
### Database Connection Fails
**Problem:** `DatabaseConnectionError` or similar
**Solutions:**
1. Check `DATABASE_URL` format is correct
2. Railway: Verify Postgres plugin is attached
3. Local: Check Docker Compose is running (`docker-compose ps`)
4. Check database credentials are correct
### CORS Errors
**Problem:** Frontend can't call API (CORS error in browser console)
**Solutions:**
1. Check `ALLOWED_ORIGINS` includes frontend domain
2. Include protocol: `https://` not just `domain.com`
3. No trailing slash: `https://domain.com` not `https://domain.com/`
4. Railway: Wait 1-2 minutes for variable updates to apply
---
**This document is the single source of truth for environment variables. Keep it updated as new variables are added.**
**Where AI meets the open road.** 🛣️