Production Checklist
Use this checklist before deploying Rack Gateway to production. Each item addresses a security or operational requirement.
Pre-Deployment
Section titled “Pre-Deployment”Security Fundamentals
Section titled “Security Fundamentals”-
APP_SECRET_KEY and AUDIT_HMAC_SECRET generated securely
Terminal window openssl rand -base64 32At least 32 bytes each. Never reuse across environments, and never change
AUDIT_HMAC_SECRETonce events are written (it keys the audit hash chain). Store both securely. -
Running a release build
Terminal window ./rack-gateway-api build-info # must report: test bypasses: compiled out -
COLUMN_ENCRYPTION_KEY generated and backed up
Terminal window openssl rand -base64 32Encrypts stored TOTP seeds and the Slack token. Never reuse across environments, never use the development key, and back it up: without it users must re-enroll TOTP and Slack must be reconnected. See Column Encryption.
-
HTTPS enabled with valid certificates
- Let’s Encrypt or organization CA
- TLS 1.2+ only
- HSTS enabled
-
Domain configured correctly
DOMAINset to production hostname- DNS records configured
- SSL certificate covers domain
Authentication
Section titled “Authentication”-
Google OAuth configured
- Production OAuth client created
- Redirect URIs point to production domain
GOOGLE_ALLOWED_DOMAINrestricts to your organization
-
Admin users specified
ADMIN_USERScontains verified admin emails- At least 2 admins for redundancy
-
Session timeout configured
RGW_SETTING_SESSION_TIMEOUT_MINUTES, or Settings → Session Timeout- Default: 5 minutes of inactivity for web sessions (CLI sessions last 90 days from their last use)
Database
Section titled “Database”-
PostgreSQL properly configured
- Production-grade instance (not Docker)
- Encryption at rest enabled
- TLS connections that verify the server (
PGSSLMODE=verify-fullwithPGSSLROOTCERT) - Audit roles created, the gateway connecting as the app user and migrations as the admin user (see Database Setup)
- Migrations applied with
rack-gateway-api migratebefore the release starts
-
Database backups configured
- Automated daily backups
- Point-in-time recovery enabled
- Backup retention meets compliance requirements
-
Connection pool sized correctly
DB_MAX_OPEN_CONNSappropriate for load- Monitor connection usage
Infrastructure
Section titled “Infrastructure”-
Resource limits configured
- Memory limits prevent OOM kills
- CPU limits ensure fair sharing
- Instance count chosen (the default
convox.ymlruns one)
-
Health checks enabled
/api/v1/healthfor liveness and readiness (it fails for a minute after any audit write failure)- Appropriate intervals and thresholds
-
Reverse proxy configured
TRUSTED_PROXY_CIDRSlists the proxies in front of the gateway- WebSocket upgrades pass through, request bodies aren’t size-limited
Security Hardening
Section titled “Security Hardening”Network Security
Section titled “Network Security”-
Private network deployment (Recommended)
- Gateway accessible only via Tailscale/VPN
- Convox API not exposed publicly
- See Private Network Deployment
-
Firewall rules configured
- Only required ports open
- Database accessible only from gateway
- No unnecessary public endpoints
Access Control
Section titled “Access Control”-
MFA configured
- MFA enrollment required for all users
- Step-up MFA for sensitive actions
- Backup codes generated and stored securely
-
RBAC policies reviewed
- Least privilege principle applied
- No unnecessary admin accounts
- Roles assigned appropriately
-
API tokens managed
- Tokens have appropriate roles
- Token rotation schedule established
- Unused tokens deleted
Audit Logging
Section titled “Audit Logging”-
Audit logging reviewed
- Always on: every request is recorded before it acts, with user attribution
- Env values redacted;
audit_visible_env_varslists only harmless keys - Container log retention set (
LOG_RETENTION_DAYSinconvox.yml)
-
Audit anchoring configured (Recommended)
- S3 WORM bucket created
AUDIT_ANCHOR_BUCKETandAUDIT_ANCHOR_CHAIN_IDsetAUDIT_VERIFY_HEARTBEAT_URLset to a heartbeat monitor, so you hear when hourly verification stops- See S3 WORM Storage
-
HMAC secret configured
AUDIT_HMAC_SECRETset to secure random value- Never changes after initial deployment
- Documented for recovery
Monitoring and Operations
Section titled “Monitoring and Operations”Monitoring
Section titled “Monitoring”-
Error tracking enabled
SENTRY_DSNconfigured for backendSENTRY_JS_DSNconfigured for frontend- Alerts configured for errors
-
Metrics collection enabled
- Health endpoint monitoring, or
UPTIME_HEARTBEAT_URLpinged while the gateway is healthy - Database metrics tracked
- Alert thresholds configured
- Health endpoint monitoring, or
-
Log aggregation configured
- Logs shipped to centralized system
- Log retention meets requirements
- Searchable for incident response
Operational Readiness
Section titled “Operational Readiness”-
Runbooks documented
- Deployment procedures
- Rollback procedures
- Incident response playbooks
-
On-call rotation established
- Escalation procedures defined
- Contact information current
- Access credentials available
-
Disaster recovery tested
- Database restoration tested
- Failover procedures documented
- Recovery time objectives defined
Integration Verification
Section titled “Integration Verification”Convox Connectivity
Section titled “Convox Connectivity”-
Rack connection verified
RACK_TOKENvalid and not expiredRACK_HOSTpoints to correct rackrack-gateway rack infoworks through the gateway
-
Proxy functionality tested
rack-gateway appsreturns expected results- Build and deploy operations work
- Environment variable access works
Notifications
Section titled “Notifications”-
Email notifications configured (Optional)
POSTMARK_API_TOKENsetPOSTMARK_FROMverified in Postmark- Test email sent successfully
-
Slack notifications configured (Optional)
- Slack app installed
- Channels configured for events
- Test notification sent
CI/CD Integration
Section titled “CI/CD Integration”-
Deploy approvals configured (If using)
CIRCLECI_TOKENset, for CircleCI auto-approval- Approval job names match
- GitHub integration tested
service_image_patternsset for each app, pinning the image repository (approval-bound builds are refused without it)approved_deploy_commandslists the exact commands CI runs (an empty list allows none)vcs_reposet toowner/repofor CircleCI auto-approval
-
CI/CD tokens created
- API tokens with
cicdrole - Tokens stored securely in CI system
- Test deployment successful
- API tokens with
Post-Deployment Verification
Section titled “Post-Deployment Verification”-
Verify health endpoints
Terminal window curl https://gateway.example.com/api/v1/health -
Test user login
- Open web UI
- Continue with Google
- Verify correct roles assigned
-
Test MFA enrollment
- Enroll at least one MFA method
- Verify step-up MFA works
-
Test Convox operations
Terminal window rack-gateway appsrack-gateway ps -a myapp -
Verify audit logging
- Check recent audit events in web UI
- Verify events have correct user attribution
-
Test notifications
- Trigger a security event
- Verify email/Slack notification received
-
Test deploy workflow (If using)
- Create test approval request
- Approve and verify CI auto-approval
Compliance Checklist
Section titled “Compliance Checklist”SOC 2 Type II
Section titled “SOC 2 Type II”- Audit logging enabled with retention
- MFA enforced for all users
- Access control via RBAC
- Change management (deploy approvals)
- Monitoring and alerting configured
- Incident response procedures documented
Data Protection
Section titled “Data Protection”- Encryption at rest (database, S3)
- Encryption in transit (TLS)
- PII handling documented
- Data retention policies configured
- Access logging enabled
Security Best Practices
Section titled “Security Best Practices”- Secrets stored securely (not in git)
- Least privilege principle applied
- Regular security reviews scheduled
- Dependency updates monitored
- Penetration testing planned
Environment-Specific Settings
Section titled “Environment-Specific Settings”Production
Section titled “Production”# RequiredAPP_SECRET_KEY=$(openssl rand -base64 32)AUDIT_HMAC_SECRET=$(openssl rand -base64 32) # Never change it after the first eventCOLUMN_ENCRYPTION_KEY=$(openssl rand -base64 32) # Generate once and back it upDATABASE_URL=postgres://rack_gateway_app:...@db:5432/rack_gateway?sslmode=requireDOMAIN=gateway.example.comGOOGLE_CLIENT_ID=xxxGOOGLE_CLIENT_SECRET=xxxGOOGLE_ALLOWED_DOMAIN=example.comRACK_TOKEN=xxxADMIN_USERS=admin1@example.com,admin2@example.com
# RecommendedLOG_RETENTION_DAYS=400RACK_ALIAS=productionRACK_DISPLAY_NAME="Production"TRUSTED_PROXY_CIDRS=10.0.0.0/16 # The proxies in front of the gateway
# If using audit anchoringAUDIT_ANCHOR_BUCKET=audit-anchors-prodAUDIT_ANCHOR_CHAIN_ID=production
# If using emailPOSTMARK_API_TOKEN=xxxPOSTMARK_FROM=gateway@example.com
# If using SlackSLACK_CLIENT_ID=xxxSLACK_CLIENT_SECRET=xxx
# If using SentrySENTRY_DSN=https://xxx@sentry.io/xxxSENTRY_JS_DSN=https://xxx@sentry.io/xxxSENTRY_ENVIRONMENT=productionStaging
Section titled “Staging”# Similar to production but with staging-specific valuesAPP_SECRET_KEY=$(openssl rand -base64 32) # Different from prod!AUDIT_HMAC_SECRET=$(openssl rand -base64 32) # Different from prod!COLUMN_ENCRYPTION_KEY=$(openssl rand -base64 32) # Different from prod!DOMAIN=gateway-staging.example.comRACK_ALIAS=stagingRACK_DISPLAY_NAME="Staging"LOG_RETENTION_DAYS=90 # Shorter for stagingCommon Mistakes to Avoid
Section titled “Common Mistakes to Avoid”Final Sign-Off
Section titled “Final Sign-Off”Before going live, ensure these stakeholders have reviewed:
- Security team: Security hardening complete
- Operations team: Monitoring and runbooks ready
- Compliance team: Audit requirements met
- Development team: Integration testing complete
- Management: Go-live approval obtained
Next Steps
Section titled “Next Steps”- Security Hardening - Additional security measures
- Monitoring - Observability setup
- Troubleshooting - Common issues