-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
198 lines (197 loc) · 8.83 KB
/
Copy path.env.example
File metadata and controls
198 lines (197 loc) · 8.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
RAILS_ENV=development
HOST_MODE=caddy # caddy, ngrok, or direct
# Caddy admin API for auto-regenerating Caddyfile when tenants change (docker network address)
CADDY_ADMIN_URL=http://caddy:2019
AUTH_MODE=oauth # or honor_system for development
# Single-tenant mode: disables subdomain routing, uses PRIMARY_SUBDOMAIN for all requests
# For local single-tenant: SINGLE_TENANT_MODE=true, HOSTNAME=localhost:3000, AUTH_MODE=honor_system
# SINGLE_TENANT_MODE=true
NGROK_AUTHTOKEN=
HOSTNAME=harmonic.localhost
# scripts/setup.sh will create a tenant record for this subdomain if it doesn't already exist
# If using ngrok, set the subdomain to the ngrok subdomain (currently only works with static subdomains)
PRIMARY_SUBDOMAIN=www
# Auth subdomain should be different from the primary subdomain.
# The auth subdomain + hostname is what you register with OAuth providers like GitHub.
# This allows a single OAuth app to be used across multiple subdomains/tenants.
AUTH_SUBDOMAIN=auth
# Comma separated list of other subdomains to list on the homepage
OTHER_PUBLIC_SUBDOMAINS=
#
# Comma separated list of subdomains whose main collective is readable by
# anonymous (logged-out) visitors. Default-deny: leave unset for fully
# private deployments.
ANON_READABLE_TENANT_SUBDOMAINS=
#
# Redis configuration
# Development: password not required (use redis://redis:6379/0)
# Production: set REDIS_PASSWORD and use redis://:password@redis:6379/0
REDIS_PASSWORD=
REDIS_URL=redis://redis:6379/0
# For production with password: REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
POSTGRES_USER=harmonic
POSTGRES_PASSWORD=harmonic
POSTGRES_DB=harmonic_development
# execute ./scripts/generate-secret-key-base.sh to get a unique secret
SECRET_KEY_BASE=
RAILS_SERVE_STATIC_FILES=true
# OAuth
ENABLED_OAUTH_PROVIDERS=github
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# Web Push (VAPID). Generate a pair with:
# docker compose exec web bundle exec rails runner 'k = WebPush.generate_key; puts "VAPID_PUBLIC_KEY=#{k.public_key}"; puts "VAPID_PRIVATE_KEY=#{k.private_key}"'
# Leave blank to disable push (the subscribe UI hides without a public key).
# VAPID_SUBJECT defaults to https://$HOSTNAME; set a mailto: to override.
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
# VAPID_SUBJECT=
# Cloudflare Turnstile (auth-flow bot defense). Both keys are global, not
# per-tenant. Leave blank in dev/test/CI — TurnstileVerifier no-ops when the
# secret is blank, and the partial omits the widget when the site key is blank.
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
# If using DigitalOcean Spaces for ActiveStorage
DO_SPACES_ACCESS_KEY_ID=
DO_SPACES_SECRET_ACCESS_KEY=
DO_SPACES_REGION=
DO_SPACES_BUCKET=
DO_SPACES_ENDPOINT=
# Email configuration (optional - emails will be logged if not configured)
# For AWS SES, use these settings:
# SMTP_SERVER=email-smtp.<region>.amazonaws.com (e.g., email-smtp.us-east-1.amazonaws.com)
# SMTP_PORT=587
# SMTP_USERNAME=<Your SES SMTP username from IAM>
# SMTP_PASSWORD=<Your SES SMTP password from IAM>
# SMTP_DOMAIN=<Your verified domain>
# MAILER_FROM_ADDRESS=noreply@<your-verified-domain>
#
# AWS SES Setup Steps:
# 1. Verify your sending domain in SES console
# 2. Add SPF/DKIM records (SES provides these)
# 3. Request production access (initially in sandbox mode)
# 4. Create SMTP credentials in SES console (generates IAM user)
#
SMTP_SERVER=
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_DOMAIN=
MAILER_FROM_ADDRESS=
# LLM keys for LiteLLM (used by agent-runner; required for AI agents and the built-in personas).
# Set the key for whichever provider(s) your model_name aliases in
# config/litellm_config.yaml point to.
# ARCEE_API_KEY=
# ANTHROPIC_API_KEY=
# OPENAI_API_KEY=
# OPENROUTER_API_KEY=
#
# Default LLM models for newly-seeded built-in persona agents. Must match a
# model_name alias in config/litellm_config.yaml (or be gateway-resolvable
# on billing tenants). Unset = let the agent-runner fall back to the
# "default" alias (which itself is configurable in litellm_config).
# CADENCE_DEFAULT_MODEL=trinity-large-thinking-free
# MELODY_DEFAULT_MODEL=
# COUNTERPOINT_DEFAULT_MODEL=
#
# Monitoring and Alerting
# Sentry error tracking (https://sentry.io)
# Get DSN from your Sentry project settings
SENTRY_DSN=
# Optional: adjust sampling rates (0.0-1.0, default 0.1 = 10%)
# SENTRY_TRACES_SAMPLE_RATE=0.1
# SENTRY_PROFILES_SAMPLE_RATE=0.1
#
# Slack webhook for alerts (optional)
# Create incoming webhook at: https://api.slack.com/messaging/webhooks
SLACK_WEBHOOK_URL=
#
# Email recipients for critical alerts (comma-separated)
ALERT_EMAIL_RECIPIENTS=
#
# Metrics endpoint authentication token
# Required to access /metrics endpoint
METRICS_AUTH_TOKEN=
#
# Stripe Billing & AI Gateway
# Backend restricted key. Permissions (see docs/BILLING.md for the full table):
# Customers (write), Checkout Sessions (write), Subscriptions (write),
# Invoices (write), Products (write), Credit grants (write),
# Credit balance summary (read), Customer portal (write)
STRIPE_API_KEY=
# AI Gateway restricted key, used only as the Bearer token for llm.stripe.com.
# Permissions: Billing -> Meter events (write). Held by the llm-gateway
# service only (compose profile "stripe") — not by Rails or the agent-runner.
STRIPE_GATEWAY_KEY=
# Webhook endpoint signature verification secret
STRIPE_WEBHOOK_SECRET=
# Stripe Price ID (price_... prefix) — recurring $3/month account subscription
STRIPE_PRICE_ID=
# Stripe Product ID (prod_... prefix) for prepaid LLM credit grants.
# Required when any tenant has stripe_billing enabled — top-up checkout raises without it.
STRIPE_CREDIT_PRODUCT_ID=
# Pricing plan ID (bpp_... prefix) for the "Billing for LLM tokens" plan
# (create via Dashboard -> Pricing plans; markup % is set there). Top-up
# completion subscribes the customer to this plan; without it, gateway
# dispatch is refused because usage would meter but never bill.
STRIPE_PRICING_PLAN_ID=
# Maximum single top-up amount in cents (default 50000 = $500)
STRIPE_MAX_TOPUP_CENTS=50000
# LLM gateway external ingress (llm.<hostname>, /v1/chat/completions).
# External agents authenticate with llm_gateway-type API keys; access is
# gated per tenant by the llm_gateway feature flag. Per-key request limits
# bound a leaked key's burn rate until dollar spend ceilings exist.
# GATEWAY_EXTERNAL_RPM=20
# GATEWAY_EXTERNAL_RPD=500
# Request body size cap in bytes (default 1 MB)
# GATEWAY_MAX_BODY_BYTES=1048576
# Per-call balance gate (Rails): a payer's effective balance is a cached
# Stripe snapshot minus ledger spend since it was taken. TTL bounds staleness;
# the buffer is headroom above zero for in-flight calls not yet in the ledger.
# GATEWAY_BALANCE_SNAPSHOT_TTL_SECONDS=600
# GATEWAY_BALANCE_BUFFER_CENTS=25
# The spend delta reaches this far back BEFORE the snapshot: Stripe aggregates
# deductions with lag, so spend costed just before a snapshot may be missing
# from its balance — the overlap double-counts it rather than missing it.
# GATEWAY_BALANCE_OVERLAP_SECONDS=300
# Each in-flight (pending) call reserves this much in the spend sums until
# its real cost lands, so concurrent calls can't slip past the caps/gate.
# GATEWAY_PENDING_RESERVE_CENTS=25
# DEPRECATED fallback for the agent-runner only: tasks now carry llm_gateway_mode
# in the Redis stream payload (set by Rails per tenant), and this env var is used
# solely for payloads published before that field existed.
LLM_GATEWAY_MODE=litellm
#
# Agent Runner Service (see docs/AGENT_RUNNER.md)
# Shared secret used by both Rails and the agent-runner Node service for:
# (1) HMAC-SHA256 signing of /internal/* requests
# (2) HKDF key derivation for AES-256-GCM token encryption in the Redis stream
# Must be byte-identical on both sides. Generate with: openssl rand -hex 32
AGENT_RUNNER_SECRET=
# IP allowlist for /internal/* endpoints (comma-separated IPs or CIDRs).
# In production this must cover every internal service container (agent-runner
# AND llm-gateway) — use the Docker network CIDR rather than a single IP.
# Empty in dev/test lets any source through (reverse proxy already blocks /internal/*).
INTERNAL_ALLOWED_IPS=
#
# Session Security
# Absolute timeout: maximum session duration from login (in seconds)
# Default: 86400 (24 hours)
# SESSION_ABSOLUTE_TIMEOUT=86400
#
# Idle timeout: session expires after this much inactivity (in seconds)
# Default: 7200 (2 hours)
# SESSION_IDLE_TIMEOUT=7200
#
# Re-verification timeout: how long a TOTP re-verification is valid (in seconds)
# Applies to admin panel access and other sensitive actions.
# Default: 3600 (1 hour)
# REVERIFICATION_TIMEOUT=3600
#
# Dev-only 2FA bypass code: when set in development, this value is accepted
# at any TOTP prompt (including the initial setup confirmation), so test
# accounts don't need real authenticator setup. NEVER set this in any
# non-development environment — the bypass is hard-guarded by
# Rails.env.development?, but defense-in-depth means leaving the var unset
# anywhere else. Pick a value only you know.
# DEV_2FA_BYPASS_CODE=