-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.example
More file actions
274 lines (252 loc) · 11.8 KB
/
Copy path.env.example
File metadata and controls
274 lines (252 loc) · 11.8 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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# ---------------------------------------------------------------------------
# Forge environment configuration (example)
# Copy to `.env` and fill in real values. Never commit a populated `.env`.
# ---------------------------------------------------------------------------
# Core
FORGE_ENVIRONMENT=development
LOG_LEVEL=info
DOMAIN=localhost
# ---------------------------------------------------------------------------
# HARD-13 secrets & config. FORGE_SECRET_KEY is the instance master KEK and is
# REQUIRED in production (the api/worker/mcp-gateway refuse to boot without it —
# no ephemeral fallback). Generate one:
# python -c 'import secrets; print(secrets.token_urlsafe(32))'
# ---------------------------------------------------------------------------
FORGE_SECRET_KEY=change-me-generate-a-long-random-string
# Instead of an inline value, point at a mounted Docker/K8s secret file:
# FORGE_SECRET_KEY_FILE=/run/secrets/forge_secret_key
# Current KEK version + previous versions retained during a rotation window.
# FORGE_SECRET_KEY_VERSION=1
# FORGE_SECRET_KEY_V1=previous-kek-during-rotation-only
# Secret provider backend: env (default) | file (/run/secrets) | vault.
FORGE_SECRET_PROVIDER=env
# FORGE_SECRET_FILE_ROOT=/run/secrets
# Two-tier envelope encryption (rotatable per-secret data keys). On in prod.
FORGE_ENVELOPE_ENCRYPTION=true
# Automatic expiry (seconds) for minted agent-runner tokens (default 24h).
FORGE_AGENT_TOKEN_TTL=86400
# Dev-only: explicit opt-in to a process-ephemeral master key. NEVER in prod.
# FORGE_DEV_INSECURE=0
# HashiCorp Vault KV-v2 (only when FORGE_SECRET_PROVIDER=vault).
# FORGE_VAULT_ADDR=http://127.0.0.1:8200
# FORGE_VAULT_TOKEN=
# FORGE_VAULT_MOUNT=secret
# FORGE_VAULT_PATH=forge
# ---------------------------------------------------------------------------
# HARD-09 edge security controls. Defaults are safe; see
# docs/self-hosting/security.md for the operator guidance behind each knob.
# ---------------------------------------------------------------------------
# OpenAPI docs (/docs, /redoc, /openapi.json). Forced OFF when
# FORGE_ENVIRONMENT=production unless this is explicitly set.
FORGE_DOCS_ENABLED=true
# Per-caller request rate limit (in-process token bucket). /health is exempt.
FORGE_RATELIMIT_ENABLED=true
FORGE_RATELIMIT_RPM=120
FORGE_RATELIMIT_BURST=60
# Max request body before 413 (bytes; default 1 MiB).
FORGE_MAX_BODY_BYTES=1048576
# SSRF guard for admin-configured outbound URLs (embedder/reranker/MCP/OAuth).
# allow_private opts into RFC1918 targets (loopback + metadata stay blocked);
# outbound_allowlist is a JSON list of exact hostnames always permitted.
FORGE_SSRF_ALLOW_PRIVATE=false
FORGE_OUTBOUND_ALLOWLIST=[]
# Database (PostgreSQL + pgvector)
POSTGRES_USER=forge
POSTGRES_PASSWORD=change-me
POSTGRES_DB=forge
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
DATABASE_URL=postgresql+psycopg://forge:change-me@localhost:5432/forge
# Redis (queue, cache, sessions)
REDIS_URL=redis://localhost:6379/0
# Object storage (MinIO / S3-compatible)
MINIO_ROOT_USER=forge
MINIO_ROOT_PASSWORD=change-me
MINIO_ENDPOINT=http://localhost:9000
MINIO_BUCKET=forge-artifacts
# Auth (Better Auth / Auth.js)
AUTH_SECRET=change-me-generate-a-long-random-string
AUTH_URL=http://localhost:3000
# F37 auth & secrets (BYOK vault + platform keys)
# Versioned KEK map for the envelope vault. Generate a key with:
# python -c "import os,base64;print(base64.b64encode(os.urandom(32)).decode())"
# Format: "1:<base64-32B>" (comma-separate additional versions for rotation).
FORGE_VAULT_KEYS=
FORGE_VAULT_ACTIVE_KEY_VERSION=1
# HMAC pepper for platform API-key hashing (same generator as above).
API_KEY_PEPPER=
# Beat cadence for the expired platform-key purge (seconds; default 15m).
FORGE_AUTH_PURGE_KEYS_INTERVAL_SECONDS=900
# BYOK model provider (provider-agnostic; Anthropic reference impl)
MODEL_PROVIDER=anthropic
MODEL_PROVIDER_KEY=
EMBEDDING_PROVIDER=anthropic
EMBEDDING_MODEL=
RERANKER_URL=http://localhost:8080
RERANKER_MODEL=jina-reranker-v2-base-multilingual
# HARD-03 live cross-encoder reranker (BYOK). Provider `fixture` (default) keeps
# the offline deterministic reranker; `jina`/`cohere`/`selfhosted` build a
# budgeted, SSRF-guarded live client. BYOK keys are read on demand (never logged).
# See docs/runbooks/live-reranker.md.
FORGE_RERANK_ENABLED=true
FORGE_RERANK_PROVIDER=fixture
FORGE_RERANK_MODEL=
FORGE_RERANK_BASE_URL=
FORGE_RERANK_TIMEOUT_MS=800
FORGE_RERANK_CANDIDATES=50
FORGE_RERANK_ALLOW_INSECURE_URL=false
JINA_API_KEY=
COHERE_API_KEY=
JINA_RERANKER_URL=
# GitHub App integration
GITHUB_APP_ID=
GITHUB_APP_CLIENT_ID=
GITHUB_APP_CLIENT_SECRET=
GITHUB_APP_PRIVATE_KEY=
GITHUB_APP_WEBHOOK_SECRET=
# Slack integration
SLACK_BOT_TOKEN=
SLACK_SIGNING_SECRET=
# Incident alert webhooks (F17). Per-provider signing secrets — an absent secret
# makes that provider's webhook fail-closed (501 Not Configured). Signatures are
# verified over the exact raw request bytes (do not buffer/rewrite at the proxy).
FORGE_PAGERDUTY_WEBHOOK_SECRET=
FORGE_DATADOG_WEBHOOK_SECRET=
FORGE_SENTRY_WEBHOOK_SECRET=
FORGE_GRAFANA_WEBHOOK_SECRET=
# Recovery-monitoring knobs (the remediation retry budget is retry_policy.max_retries
# in the bundled incident.yaml, not an env var).
FORGE_INCIDENT_RECOVERY_WINDOW_SECONDS=300
FORGE_INCIDENT_RECOVERY_MAX_WINDOWS=6
# MinIO bucket for versioned postmortem snapshots.
FORGE_POSTMORTEMS_BUCKET=forge-postmortems
# External PM adapters (F18 — Jira, Linear). OAuth client creds are optional
# (api_token auth works without them). Webhook bodies for these routes MUST reach
# the API unbuffered/unrewritten (Linear HMAC is over the exact raw bytes).
JIRA_OAUTH_CLIENT_ID=
JIRA_OAUTH_CLIENT_SECRET=
LINEAR_OAUTH_CLIENT_ID=
LINEAR_OAUTH_CLIENT_SECRET=
PM_WEBHOOK_PUBLIC_URL=${API_URL}
PM_OUTBOUND_SCAN_SECONDS=20
PM_HEALTH_PROBE_SECONDS=300
PM_HTTP_TIMEOUT_SECONDS=30
PM_LINEAR_WEBHOOK_TOLERANCE_SECONDS=60
PM_BACKFILL_PAGE_SIZE=50
# Container sandboxing (F19). Default isolation is `worktree` (V1, host
# subprocess); set `container` to run task verification/build commands inside a
# per-task, locked-down Docker container. The worker reaches the daemon ONLY via
# the socket-proxy (never the raw socket); container egress is `none` by default.
FORGE_SANDBOX_KIND=worktree
FORGE_SANDBOX_DOCKER_HOST=tcp://docker-proxy:2375
FORGE_SANDBOX_IMAGE_PYTHON=ghcr.io/forge-platform/forge-sandbox-python:0.1.0
FORGE_SANDBOX_IMAGE_NODE=ghcr.io/forge-platform/forge-sandbox-node:0.1.0
FORGE_SANDBOX_IMAGE_GO=ghcr.io/forge-platform/forge-sandbox-go:0.1.0
# Comma list; empty -> defaults to the three images above. A policy.sandbox.image
# must be a member of this allowlist.
FORGE_SANDBOX_ALLOWED_IMAGES=
FORGE_WORKTREE_VOLUME=forge_repos
FORGE_SANDBOX_CPUS=2.0
FORGE_SANDBOX_MEMORY_MB=4096
FORGE_SANDBOX_PIDS_LIMIT=512
FORGE_SANDBOX_TMPFS_MB=1024
FORGE_SANDBOX_NETWORK=none
FORGE_SANDBOX_EGRESS_ALLOWLIST=pypi.org,files.pythonhosted.org,registry.npmjs.org
FORGE_SANDBOX_EXEC_TIMEOUT_SECONDS=1800
FORGE_SANDBOX_OUTPUT_CAP_BYTES=262144
FORGE_SANDBOX_RUN_UID=10001
FORGE_SANDBOX_RUN_GID=10001
FORGE_SANDBOX_REAP_INTERVAL_SECONDS=300
FORGE_SANDBOX_MAX_TTL_SECONDS=21600
# Service URLs (used by web / inter-service calls)
API_URL=http://localhost:8000
MCP_GATEWAY_URL=http://localhost:8001
NEXT_PUBLIC_API_URL=http://localhost:8000
# MCP sync-and-index (F20) — periodic ingestion of MCP resources into the index.
MCP_INDEX_POLL_SECONDS=300
MCP_INDEX_PAGE_SIZE=100
MCP_INDEX_MAX_RESOURCES=5000
MCP_INDEX_EMBED_BATCH=64
MCP_INDEX_CONCURRENCY=4
MCP_INDEX_DELETE_ON_DISABLE=true
# Saved workflow automations (F21) — rule engine.
# Max cascade depth before a firing is aborted (skipped_loop); loop protection.
FORGE_AUTOMATION_MAX_DEPTH=5
# Reconciliation-sweep cadence for any trigger envelopes whose enqueue was lost.
FORGE_AUTOMATION_SWEEP_INTERVAL_SECONDS=60
# ---------------------------------------------------------------------------
# Observability & cost accounting (HARD-10). Off by default: OBS_ENABLED=false
# installs no-op telemetry providers, attempts NO OTLP export, and adds near-
# zero overhead. Turn it on together with the `observability` compose profile
# (docker compose --profile observability up) to get the full OTLP -> collector
# -> Prometheus/Tempo/Loki + Grafana + Alertmanager stack.
# ---------------------------------------------------------------------------
# Master switch for real telemetry export (traces/metrics/logs over OTLP).
OBS_ENABLED=false
# OTLP push endpoint (the collector). Only used when OBS_ENABLED=true.
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
# Head-based trace sampler (parent-ratio); OTEL_TRACES_SAMPLER_ARG in [0,1].
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
# Add a workspace_id metric label (cardinality guard — leave false in prod).
OBS_METRIC_WORKSPACE_LABEL=false
# Expose the in-process Prometheus /metrics scrape surface (internal net only).
OBS_PROMETHEUS_SCRAPE=true
# Optional self-hosted log/trace sinks (defaults target the compose services).
LOKI_ENDPOINT=http://loki:3100
TEMPO_ENDPOINT=http://tempo:3200
# Grafana admin password + the Caddy /grafana basic-auth bcrypt hash.
GRAFANA_ADMIN_PASSWORD=forge-change-me
GRAFANA_BASIC_AUTH=
# Cost ledger: reporting currency (V1 USD only) + unknown-model behavior.
COST_DEFAULT_CURRENCY=USD
COST_UNPRICED_MODEL_BEHAVIOR=warn
# LangSmith stays an optional extra trace backend (Tempo is the default).
LANGSMITH_API_KEY=
# Workflow engine (F25) — V2 Temporal durable engine (opt-in; default keeps the
# V1 Postgres FSM). Set WORKFLOW_ENGINE_BACKEND=temporal AND start the `temporal`
# compose profile to use it. New runs pick the selected backend; in-flight runs
# keep theirs. These are read by the API + both workers + the CLI (no FORGE_ prefix).
WORKFLOW_ENGINE_BACKEND=postgres_fsm
TEMPORAL_HOST=temporal:7233
TEMPORAL_NAMESPACE=forge
TEMPORAL_TASK_QUEUE=forge-feature
# mTLS to the frontend (empty = plaintext on the internal network only).
TEMPORAL_TLS_CERT=
TEMPORAL_TLS_KEY=
TEMPORAL_TLS_CA=
# AES key (vault ref) for the RedactingEncryptionCodec (required when temporal).
TEMPORAL_CODEC_KEY=
TEMPORAL_WORKFLOW_EXEC_TIMEOUT=2592000
AGENT_ACTIVITY_TIMEOUT=7200
TEMPORAL_RETENTION_DAYS=30
# ---------------------------------------------------------------------------
# F32 Integration Marketplace — federated registries for community MCP
# connectors & skill profiles. The official registry URL + pubkey seed a
# per-workspace read-only `official` registry row. Catalog sync is SSRF-bounded
# (deny RFC1918 / link-local / metadata unless a host is allowlisted).
# ---------------------------------------------------------------------------
MARKETPLACE_OFFICIAL_REGISTRY_URL=https://marketplace.forge.dev/index.json
MARKETPLACE_OFFICIAL_REGISTRY_PUBKEY=
MARKETPLACE_SYNC_INTERVAL_MINUTES=60
MARKETPLACE_FETCH_TIMEOUT_SECONDS=20
MARKETPLACE_MAX_INDEX_BYTES=5242880
MARKETPLACE_MAX_MANIFEST_BYTES=262144
# Comma-separated hosts allowed to resolve to private ranges (internal registries).
MARKETPLACE_ALLOWED_REGISTRY_HOSTS=
MARKETPLACE_REQUIRE_SIGNATURE=false
# ---------------------------------------------------------------------------
# F33 Enterprise SSO (SAML 2.0 SP + SCIM 2.0 service provider).
# FORGE_PUBLIC_URL must be the externally reachable HTTPS URL — the SP entity
# id, ACS URL, SP metadata URL, and SCIM base URL are all derived from it.
# ---------------------------------------------------------------------------
FORGE_PUBLIC_URL=http://localhost:8000
# Clock-skew tolerance for SAML NotBefore/NotOnOrAfter validation (seconds).
FORGE_SAML_CLOCK_SKEW_SECONDS=120
# One-time AuthnRequest ids are held in the replay guard for this long.
FORGE_SAML_AUTHNREQUEST_TTL_SECONDS=600
# Entropy (bytes) for freshly minted per-workspace SCIM bearer tokens.
FORGE_SCIM_TOKEN_BYTES=32
# Worker beat cadences: IdP metadata refresh (cert rollover) + replay eviction.
FORGE_SSO_METADATA_REFRESH_SECONDS=21600
FORGE_SSO_REPLAY_CLEANUP_SECONDS=900