Configuration Reference
Every MERGEN_* environment variable the server reads, classified by who is qualified to decide its value. This reference is generated from the same registry the build enforces — an unregistered setting is a red build, so this page cannot silently fall out of date.
One invariant governs everything here: no setting below can make the gate approve something it would otherwise have blocked — except the explicitly guarded settings, which exist for narrow recovery/migration cases and are surfaced loudly wherever they are active.
Organization policy
Settings a security admin decides — approval rules, retention, quorum, module switches. These are what teams buy Mergen to customize. None of them can weaken a gate verdict.
MERGEN_AUTOPILOT
type: boolean — default: false — module: autopilot
Enable autonomous incident fix execution (Gate B). Off by default; shadow mode is forced on first enable unless explicitly disabled.
MERGEN_AUTOPILOT_LEVEL
type: string — default: unset — module: autopilot
Autopilot autonomy level cap.
MERGEN_SHADOW_MODE
type: boolean — default: unset — module: autopilot
Dry-run the AUTOPILOT (Gate B): diagnose but never execute fixes. Defaults to true when autopilot is first enabled.
MERGEN_BLOCK_BYPASS
type: boolean — default: true
Lets an operator — never the agent — self-issue a single-use terminal token to re-run a BLOCK from an editable rule. This is a recovery valve, not a HOLD-style approval request: nothing is sent to the agent, no one is asked to approve anything. false = every BLOCK is final (stricter). Immutable/hard-safety rules are never bypassable regardless.
MERGEN_BYPASS_TTL_MINUTES
type: int — default: 10
Minutes an operator-issued BLOCK bypass token stays valid before it expires (clamped 1-1440). The window does not extend on use — the re-run must land within it.
MERGEN_APPROVAL_REUSE_MINUTES
type: int — default: 10
Minutes a HITL hold approval is honored for exactly one re-run of exactly that command (clamped 1-1440). Single-use and exact-match regardless of the window length.
MERGEN_CORPUS_HOLD
type: boolean — default: false — module: override-corpus
Opt-in per-command override-corpus lookup at Gate A: a command matching a prior override/incident escalates to HOLD with a cited reason. HOLD-only, never BLOCK/PASS.
MERGEN_AUTO_CORPUS_PROPOSE
type: boolean — default: true — module: policy-suggester
Every 6h, stage repeatedly-overridden corpus patterns as HOLD-only policy proposals for one-click approval. Never auto-activates, never proposes a BLOCK.
MERGEN_CHANGE_GATE_DETECTORS
type: boolean — default: true — module: change-gate
POST /ci/gate (Gate C, Change Authorization): deterministic diff-content detectors — secret introduction, test deletion, auth-bypass, CI-check removal, permission/config weakening. The highest-confidence detectors are BLOCK-eligible; see change-gate.ts for the per-detector severity table.
MERGEN_CHANGE_GATE_SCOPE
type: boolean — default: true — module: change-gate
POST /ci/gate (Gate C, Change Authorization): task-to-diff scope match — keyword/path heuristic comparing the supplied taskDescription/planSummary against changed files, not a semantic review. Capped at REQUIRE_REVIEW; can never itself produce BLOCK or PASS.
MERGEN_CHANGE_GATE_MODE
type: enum — values: off · shadow · enforce — default: enforce — module: change-gate
POST /ci/gate (Gate C): off skips Gate C entirely (corpus/size/blast-radius findings elsewhere in /ci/gate are unaffected). shadow runs every detector and the scope match, populates the API response and PR comment (with a shadow-mode banner and what verdict it WOULD have produced), but never changes the actual verdict, never fails the CI build, and never applies the review label — for measuring false-positive rate on real traffic before enabling enforcement. enforce (default) is full effect.
MERGEN_RISK_HOLD_THRESHOLD
type: float — default: unset
Opt-in risk-score escalation: a passing call with composite risk at/above this threshold escalates PASS→HOLD. Unset = off.
MERGEN_SCRIPT_TRUST_WINDOW_SECONDS
type: int — default: 30 — module: script-trust
Script-wrapping evasion guard: scripts modified within this window are auto-held. 0 disables only the freshness check (git-tracked + in-workspace checks stay).
MERGEN_OBSERVATION_WINDOW_DAYS
type: int — default: 14
Length of the first-install gate observation window (Gate A evaluates and logs every call but editable-rule blocks/holds pass through; immutable hard-safety rules still enforce from minute one). Integer days, clamped 1-90 — an out-of-range or non-integer value refuses to start rather than silently reverting; below 3 boots with a warning (too little traffic to build trust). Enforcement date is always startedAt + this value, recomputed live, so changing it mid-window shifts the date deterministically instead of extending from "now". MERGEN_POLICY_DRY_RUN=false skips observation entirely regardless of this value; POST /onboarding/promote-enforcement ends it early.
MERGEN_GATE_RECOVERY_COMMANDS
type: csv — default: unset
Additive, exact-match-only extension of the built-in recovery allowlist gate-check exempts from the network round-trip. Entries with shell metacharacters are rejected.
MERGEN_GATE_AUTOSTART
type: boolean — default: true
gate-check auto-starts a missing workspace server (clean unreachable only, never a wedged one) and evaluates the command against the fresh gate. Disabling cannot weaken the gate — unavailability then fails closed per MERGEN_GATE_AVAILABILITY_MODE; a deliberate mergen-server stop pauses auto-start until an explicit start.
MERGEN_REQUIRE_GATE_HEARTBEAT
type: boolean — default: false
Require a fresh gate heartbeat for health to report ok (stricter when true).
MERGEN_TRUSTED_HUMANS
type: csv — default: unset
Principals treated as verified humans for policy conditions.
MERGEN_ACTOR_ROLES
type: string — default: unset
Actor→role mapping consumed by policy rule role conditions.
MERGEN_HITL_QUORUM_RULES
type: csv — default: unset — module: hitl
pattern:count pairs — a hold matching a pattern requires N distinct approvers before the Promise resolves.
MERGEN_LEDGER_RETENTION_DAYS
type: int — default: 90
Durable per-agent action ledger retention (every PASS/HOLD/BLOCK). Rows past the window are pruned hourly; 1M-row hard cap.
MERGEN_RETENTION_HOURS
type: int — default: unset
In-memory/ring-buffer event retention in hours. Distinct from MERGEN_LEDGER_RETENTION_DAYS (the durable gate-decision ledger).
MERGEN_REDACT_KEYS
type: csv — default: unset
Additional key names for the PII shield to redact (additive — stricter).
MERGEN_CAPTURE_TERMINAL_RETAIN
type: enum — values: none · metadata_only · redacted · full — default: redacted
What terminal-command text is written to the durable action ledger, AFTER the PASS/HOLD/BLOCK decision is already made — never a precondition for making one (see docs/internal/CAPTURE_POLICY_DESIGN.md). none/metadata_only retain no command text; redacted/full both pass the command through the PII/secret redaction pass unconditionally — "full" means full operational context subject to mandatory redaction, never byte-for-byte raw capture. No findings_only mode for this category — a bare command has no sub-findings to summarize (see change-gate detector findings for where findings_only applies instead). A tampered or unsigned signed-settings file falls back to 'none' (the strictest mode), not to this default — see capture-policy.ts. NOT RETROACTIVE: changing this value only affects future ledger writes — rows already written (including under the pre-2026-07-25 unconditional-raw default) keep whatever content they were written with. There is no migration or purge tool yet; see docs/internal/CAPTURE_POLICY_DESIGN.md's "Existing installations" section.
MERGEN_CAPTURE_FILECHANGES_RETAIN
type: enum — values: none · metadata_only · findings_only — default: findings_only
What Gate C (POST /ci/gate, Change Authorization) change-detector finding detail is attached to the CI-gate JSON response (changeGate.deterministicFindings/findingsSummary, and the lineHits.hits/policyGate matches from the same evidence category), AFTER the verdict is already computed — never a precondition for computing one (see docs/internal/CAPTURE_POLICY_DESIGN.md). none/metadata_only retain no per-finding evidence text (metadata_only keeps file paths, counts, and detector/severity categories only). findings_only (default) returns the full per-finding shape with evidence passed through the PII/secret redaction pass unconditionally. No redacted/full mode yet for this category — those need diff-hunk-extraction machinery this slice does not build. verdict/riskScore/reasons[] are unaffected by this SETTING at every mode (the free-text detector/reason/line stay raw always, verified fixed templates) — but reasons[] entries DO have their file-path token redacted unconditionally, independent of this setting, same baseline-hygiene rule as changeGate.deterministicFindings[].file (a path can embed a secret). A tampered or unsigned signed-settings file falls back to 'none' (the strictest mode), not to this default (which is itself fairly permissive) — see capture-policy.ts. NOT RETROACTIVE — see MERGEN_CAPTURE_TERMINAL_RETAIN's note above; the same caveat applies here.
MERGEN_CAPTURE_CLOUD_RETAIN
type: enum — values: local_only · metadata_only · match_local — default: local_only
Second gate applied on top of (never instead of, and never more permissive than) terminal.retain/fileChanges.retain, governing what may leave THIS MACHINE at all — Mergen's own SaaS (the live cloud-approval relay, audit-events sync, approvals sync), the self-hosted fleet-audit sync plane, and any customer-configured SIEM sink. effectiveOutboundMode = stricter(local mode, this ceiling), composed at the moment of each egress attempt, never cached from the local write. local_only (default) ceilings each category at its own most-restrictive local mode (none); metadata_only ceilings at each category's own metadata_only shape; match_local applies no additional ceiling beyond whatever the local retain mode already decided. Defaults to the strictest legal value here (unlike terminal/fileChanges's moderate defaults) because crossing the machine boundary is a materially larger trust boundary than local disk. A tampered or unsigned signed-settings file falls back to local_only (already the strictest legal value) — see capture-policy.ts.
MERGEN_SSO_REQUIRED
type: boolean — default: false — module: identity
Require SSO bearer auth on all mutating requests (stricter when true).
MERGEN_SSO_ALLOWED_EMAILS
type: csv — default: unset — module: identity
Allow-list of SSO principals permitted to authenticate.
MERGEN_OIDC_GROUP_ROLE_MAP
type: string — default: unset — module: idp
IDP group→Mergen RBAC role mapping.
MERGEN_SANDBOX
type: enum — values: docker · seatbelt — default: unset — module: sandbox
Sandbox mergen-server exec: docker (container) or seatbelt (macOS). Opt-in; falls back to direct host execution with a loud warning if the backend is unavailable.
MERGEN_SANDBOX_NETWORK
type: enum — values: none · bridge — default: none — module: sandbox
Sandbox network access: none (default) or bridge.
MERGEN_SANDBOX_IMAGE
type: string — default: unset — module: sandbox
Docker backend image (must contain the wrapped command's toolchain).
MERGEN_SANDBOX_EXTRA_WRITE_PATHS
type: csv — default: unset — module: sandbox
Seatbelt backend: extra absolute paths the sandboxed command may write to.
MERGEN_SANDBOX_DOCKER_RUNTIME
type: string — default: unset — module: sandbox
Alternate OCI runtime (e.g. gVisor runsc) for the Docker backend; falls back to runc with a warning if unregistered.
MERGEN_EBPF_VERIFY
type: boolean — default: unset — module: sandbox
eBPF-based execution verification (Linux): cross-checks that what ran matches what was gated.
MERGEN_SLACK_OVERRIDE_LOOP
type: boolean — default: unset — module: override-corpus
Auto-scan the incident channel every 6h for postmortem threads to build override corpus entries.
MERGEN_REQUIRE_GITHUB_WEBHOOK_SECRET
type: boolean — default: false — module: github
Reject all GitHub webhooks instead of accepting unverified ones in local diagnosis-only mode (stricter when true; autopilot/cloud always reject unverified).
MERGEN_SIEM_LEDGER_VERDICTS
type: csv — default: block,hold — module: siem
Which action-ledger verdicts to stream to SIEM sinks. Every PASS is still recorded locally; this only governs forwarding.
MERGEN_AUTO_WATCH
type: boolean — default: true — module: process-watch
Auto-watch local processes.
MERGEN_AUTO_ATTACH_PORTS
type: csv — default: unset — module: process-watch
Ports to auto-attach the process watcher to.
MERGEN_WATCH
type: boolean — default: unset — module: process-watch
Process watch toggle.
MERGEN_DEGRADATION_WATCH
type: boolean — default: unset — module: degradation-watch
Background degradation watcher.
MERGEN_CAUSALITY_WINDOW_MIN
type: int — default: unset — module: incident-memory
Causal-analysis lookback window in minutes.
MERGEN_SEVERE_ERR_COUNT
type: int — default: unset
Error-count threshold for severe-incident classification.
MERGEN_SEVERE_WINDOW_MS
type: int — default: unset
Window for severe-incident error counting.
MERGEN_SEVERE_DURATION_MS
type: int — default: unset
Duration threshold for severe-incident classification.
MERGEN_DOWNTIME_COST_PER_HOUR
type: float — default: unset
Downtime cost input for impact-report economics.
MERGEN_REVENUE_PER_MINUTE_USD
type: float — default: unset
Revenue-per-minute input for impact-report economics.
MERGEN_TOPOLOGY_MAX_EDGE_AGE_DAYS
type: int — default: unset
Max age of service-graph edges before pruning.
MERGEN_POLICY_MERGE
type: string — default: unset — module: policy-sync
Merge behavior when syncing remote policy with local rules.
MERGEN_GIT_SYNC
type: boolean — default: unset — module: calibration
Sync calibration data via git.
MERGEN_GIT_ADR_SYNC
type: boolean — default: unset — module: override-corpus
Scan git history + ADRs daily for operational constraints to materialize as override corpus entries.
Guarded settings
Settings that weaken enforcement by design. They exist for narrow, legitimate cases (onboarding trials, policy migration, break-glass recovery) and are impossible to miss when active: mergen-server doctor, GET /health/integrations, the startup banner, and audit surfaces all report them. Each entry below states exactly what the dangerous value does.
MERGEN_GATE_AVAILABILITY_MODE
type: enum — values: fail-closed · fail-open — default: fail-closed
gate-check behavior when a decision genuinely cannot be obtained (server unreachable/timeout). Never applies to a computed BLOCK. fail-open is for onboarding trials only.
⚠️ When active: fail-open — a wedged, absent, or timed-out gate ALLOWS tool calls through instead of blocking them. Intended only for initial onboarding/shadow trials; never set as a team default.
MERGEN_POLICY_DRY_RUN
type: boolean — default: false
Policy dry-run: verdicts are computed and logged but NOT enforced. For policy testing before rollout. Explicit false also vetoes the onboarding-window auto-dry-run.
⚠️ When active: policy dry-run — BLOCK/HOLD verdicts are logged but NOT enforced. Every agent action executes. Unset once policy testing is done.
MERGEN_ALLOW_UNSIGNED_POLICY
type: boolean — default: false
Accept an unsigned enterprise-policy.json (migration escape hatch). Refuses to start unless MERGEN_UNSAFE_ALLOW_UNSIGNED=true is also set.
⚠️ When active: unsigned policy accepted — anything with filesystem access (including AI agents) can rewrite live enforcement policy without detection. Unset once policy migration is complete.
Requires
MERGEN_UNSAFE_ALLOW_UNSIGNED=trueto also be set — refuses to activate alone.
MERGEN_UNSAFE_ALLOW_UNSIGNED
type: boolean — default: false
Confirmation flag for MERGEN_ALLOW_UNSIGNED_POLICY — meaningless alone.
⚠️ When active: MERGEN_UNSAFE_ALLOW_UNSIGNED=true is set — unsigned-policy acceptance is armed (active only with MERGEN_ALLOW_UNSIGNED_POLICY=true).
MERGEN_PANIC_BYPASS_UNTIL
type: int — default: unset
Epoch-ms until which the panic bypass suspends gate enforcement (break-glass). Also settable via file; every use is logged and time-bounded.
⚠️ When active: PANIC BYPASS ACTIVE — gate enforcement is suspended until the configured time. If this is not a live break-glass emergency, unset it now.
MERGEN_PANIC_BYPASS_REASON
type: string — default: unset
Operator-supplied reason recorded on panic-bypass audit events.
⚠️ When active: panic-bypass reason is set (informational — MERGEN_PANIC_BYPASS_UNTIL controls activation).
MERGEN_DISABLE_LOOPBACK_TOKEN
type: boolean — default: false
Disable the loopback-token guard on local API requests (for legacy clients / containerized setups where the token file cannot be shared). Weakens local API auth to the pre-token posture.
⚠️ When active: loopback-token guard DISABLED — any local process can call the API without the per-boot token, relying only on the shared-secret guards. Intended for containerized/legacy setups; unset once the token file can be shared.
MERGEN_ZERO_RETENTION
type: boolean — default: false
VPC/regulated mode: no on-disk event retention. Deliberate privacy posture, but it also thins the local audit trail — treat as a conscious trade-off.
⚠️ When active: zero-retention mode — events are not persisted to disk. Audit reconstruction after an incident will be limited to what was forwarded (SIEM/ledger).
MERGEN_GATE_DISABLE_EVALUATE_CATEGORIES
type: csv — default: unset
Comma-separated Gate A rule categories (POLICY_RULE_CATEGORIES, enterprise-policy-engine.ts) excluded from evaluation entirely — the "Evaluate" dimension (docs/internal/CAPTURE_POLICY_DESIGN.md). Only rules with action: "warn" can ever carry a category, so this can never disable a hard BLOCK, sequence-threat/injection/self-protection detection, or the 5 IMMUTABLE_RULE_IDS. Unknown category tokens are ignored, never treated as "disabled."
⚠️ When active: one or more Gate A rule categories have Evaluate disabled — their WARN/HOLD rules are never checked. No BLOCK-tier rule, sequence-threat/injection/self-protection detection, or immutable hard-safety rule is ever affected by this setting. Unset for production use.
MERGEN_GATE_ENFORCEMENT_OVERRIDES
type: csv — default: unset
Comma-separated ruleId:target pairs downgrading an eligible rule's effective enforcement action — the "Enforce" dimension (docs/internal/CAPTURE_POLICY_DESIGN.md). target is "observe" (never affects verdict, still recorded in the audit trail) or "advise" (inform, execution continues, never a HOLD). Only ever settable for a rule whose authored action is "warn" — a rule id whose action is "block" is silently ignored, never downgraded, by construction (the override map is never even consulted for it). Unknown rule ids are ignored, never treated as a match.
⚠️ When active: one or more Gate A rules have their enforcement downgraded to Observe or Advise instead of Hold. No block-tier or immutable rule is ever affected by this setting. Unset for production use.
Infrastructure
Settings an infrastructure operator decides — ports, paths, URLs, deployment context, and credential material. Changing these describes a different deployment; it does not loosen the gate.
MERGEN_GATE_HOOK_TIMEOUT_MS
type: int — default: 10000
How long gate-check (the PreToolUse hook) waits for a decision before applying the availability mode.
MERGEN_GATE_HEARTBEAT_INTERVAL_MS
type: int — default: unset
Interval for the gate liveness heartbeat.
MERGEN_GATE_HEARTBEAT_MAX_AGE_MS
type: int — default: unset
Maximum heartbeat age before the gate is considered stale.
MERGEN_MAX_BLUNDERS
type: int — default: unset
Cap on stored agent-blunder records.
MERGEN_MAX_GATE_HISTORY
type: int — default: unset
Cap on stored gate decision history entries.
MERGEN_PORT
type: int — default: 3000
HTTP listen port.
MERGEN_BIND
type: string — default: 127.0.0.1
Bind address. Non-loopback enables team mode and requires MERGEN_SECRET + MERGEN_PUBLIC_URL.
MERGEN_HOST
type: string — default: unset
Server host override used by CLI clients to reach the server.
MERGEN_DATA_DIR
type: string — default: ~/.mergen
Data directory for all on-disk stores: license, the enrolled runtime credential, the durable action ledger, HITL hold state, approved-script trust, override corpus. Set this to a path on a volume that survives a rebuild in Docker, Dev Containers, Codespaces, or Gitpod — the default (home directory) is normally INSIDE the container and is wiped on rebuild, which also re-enrolls the workspace as a new Fleet identity and (see onboarding-window.ts) skips the first-install grace period rather than risk silently disabling an existing team's HOLD approvals.
MERGEN_BUFFER_SIZE
type: int — default: unset
Ring buffer capacity (events).
MERGEN_OTLP_BODY_LIMIT
type: string — default: 16mb
Max request body on /v1/* OTLP routes.
MERGEN_TLS_CERT
type: string — default: unset
TLS certificate path (cloud/team mode).
MERGEN_TLS_KEY
type: string — default: unset
TLS private key path (cloud/team mode).
MERGEN_ALLOWED_ORIGINS
type: csv — default: unset
CORS allow-list in team/cloud mode.
MERGEN_PUBLIC_URL
type: url — default: unset
Externally reachable base URL — HITL approve/deny links, Slack OAuth redirect, OIDC issuer. Required in team/cloud mode.
MERGEN_TRUSTED_PROXY
type: string — default: unset
Express trust-proxy setting for deployments behind a reverse proxy.
MERGEN_CLOUD_MODE
type: boolean — default: false
Multi-tenant SaaS deployment mode: Postgres+Redis required, API-key auth, tenant isolation.
MERGEN_PG_URL
type: secret — default: unset
Postgres connection string (cloud mode). May embed credentials.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_REDIS_URL
type: secret — default: unset
Redis connection string (ring-buffer persistence / cloud mode). May embed credentials.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_BULLMQ
type: boolean — default: unset
Use BullMQ (Redis) for background job queues.
MERGEN_WASM_PATH
type: string — default: unset
Path override for bundled WASM artifacts.
MERGEN_MODEL
type: string — default: unset
Model id for the optional LLM spokesperson (advisory summaries only — never in the enforcement path).
MERGEN_API_URL
type: url — default: unset
Activation/licensing backend base URL. On a paid plan this is also the destination for periodic background sync: machine identity/heartbeat, usage counts, resolved approval decisions (including the held command argument), and Agent Blunder Log entries (including blocked command text and reason). None of this is required for local enforcement, and none of it is sent on Free.
MERGEN_BASE_URL
type: url — default: unset
Base URL override for self-referential links.
MERGEN_DASHBOARD_URL
type: url — default: unset
Dashboard base URL override used in notification links.
MERGEN_TELEMETRY
type: boolean — default: unset
Product telemetry opt-in/out.
MERGEN_TELEMETRY_URL
type: url — default: unset
Product telemetry endpoint override.
MERGEN_LS_VARIANT_MAP
type: string — default: unset
LemonSqueezy variant→plan mapping override (billing metadata only — billing never enforces).
MERGEN_MEMBER_ID
type: string — default: unset
Pin this install's identity in usage reports.
MERGEN_SECRET
type: secret — default: unset
Shared secret for the /ingest endpoint (x-mergen-secret). Other admin routes are guarded by ~/.mergen/secret or MERGEN_ADMIN_SECRET.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_ADMIN_SECRET
type: secret — default: unset
Dedicated env-only secret for the admin-mutation guard and sensitive-GET guard. Recommended for production so agents with filesystem access cannot forge admin actions.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_AUDIT_SECRET
type: secret — default: unset
HMAC key for audit evidence-pack signing.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_POLICY_SIGNING_SECRET
type: secret — default: unset
HMAC key for local enterprise-policy.json tamper evidence. Falls back to ~/.mergen/secret when unset (weaker: on-disk).
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_POLICY_HMAC_SECRET
type: secret — default: unset
HMAC key verifying REMOTE policy-sync responses (X-Mergen-Policy-Signature). Distinct from MERGEN_POLICY_SIGNING_SECRET (local file signing).
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_POLICY_SYNC_TOKEN
type: secret — default: unset
Bearer token for the self-hosted policy sync plane (/policies/sync).
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_OIDC_SIGNING_KEY
type: secret — default: unset
PEM/PKCS8 RSA private key for the OIDC issuer (GCP/Azure credential federation). Falls back to a key persisted on disk when unset (weaker).
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_AGENT_TOKEN
type: secret — default: unset
Verified agent identity token presented by a registered agent process.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_TOKEN
type: secret — default: unset
CI/CD and ephemeral non-interactive environment machine token.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_PLAN_ID
type: string — default: unset
CI/CD license plan override (used with MERGEN_TOKEN).
MERGEN_AGENT_TOKEN_SECRET
type: secret — default: unset
HMAC key for signing/verifying agent identity tokens.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SSO_TOKEN
type: secret — default: unset
Bearer token required on mutating requests when MERGEN_SSO_REQUIRED=true.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_USER_ID
type: string — default: unset
FALLBACK human principal on ledger rows. A verified agent token's SSO-federated userId always wins over this unauthenticated value.
MERGEN_ENVIRONMENT
type: string — default: unset
Deployment environment label (production/staging/dev) matched by policy rule conditions.
MERGEN_REPO
type: string — default: unset
Repository label (org/name) matched by policy rule conditions.
MERGEN_GIT_BRANCH
type: string — default: unset
Current git branch matched by policy rule branch conditions.
MERGEN_AGENT_ID
type: string — default: unset
Registered agent id for this process, matched by policy agentIds conditions.
MERGEN_MCP_ACTOR
type: string — default: unset
Actor label recorded on MCP-originated gate decisions.
MERGEN_CLIENT
type: string — default: unset
Client surface label (claude-code/cursor/cli-hook/…) recorded on gate decisions.
MERGEN_TRACE_ID
type: string — default: unset
Trace id propagated onto ledger rows for cross-tool correlation.
MERGEN_SERVICES
type: csv — default: unset
Known service names for attribution.
MERGEN_TENANT_ID
type: string — default: unset
Tenant id for cloud-mode client calls.
MERGEN_DEFAULT_TENANT_ID
type: string — default: unset
Default tenant id assigned to unattributed events (cloud mode).
MERGEN_SYSTEM_TENANT_ID
type: string — default: unset
Reserved tenant id for system-generated events (cloud mode).
MERGEN_WATCH_INTERVAL_MS
type: int — default: unset — module: process-watch
Process watcher poll interval.
MERGEN_POLICY_URL
type: url — default: unset — module: policy-sync
Central policy server URL for team policy sync. HTTPS enforced at startup.
MERGEN_CLOUD_POLICY_SYNC
type: boolean — default: true — module: cloud-policy-sync
Automatically pull and activate Mergen Cloud org policy on an interval, for signed-in paid-plan installs. false = cloud policy sync only via the manual policy pull --cloud command.
MERGEN_CLOUD_POLICY_POLL_MS
type: int — default: 120000 — module: cloud-policy-sync
Interval between automatic Mergen Cloud policy sync attempts, in ms.
MERGEN_AUTH_STUB
type: boolean — default: false
DEV ONLY: serve a local device-authorization stub standing in for api.mergen.app so activation runs offline. Affects licensing/plan metadata only — never enforcement.
MERGEN_AUTH_STUB_PLAN
type: string — default: unset
DEV ONLY: plan the auth stub grants.
MERGEN_AUTH_STUB_EMAIL
type: string — default: unset
DEV ONLY: account email the auth stub reports.
Integrations
Connections to external systems (Slack, PagerDuty, SIEM, email, …). Integrations deliver notifications and reports — the security decision itself never depends on one being configured.
MERGEN_OKTA_DOMAIN
type: string — default: unset — module: idp
Okta domain for IDP identity enrichment.
MERGEN_ENTRA_TENANT_ID
type: string — default: unset — module: idp
Microsoft Entra tenant for IDP identity enrichment / Azure federation.
MERGEN_OIDC_CLIENT_ID
type: string — default: unset — module: idp
OIDC client id for IDP identity enrichment.
MERGEN_OIDC_ISSUER_URL
type: url — default: unset — module: idp
External OIDC issuer URL for verifying operator identities.
MERGEN_OIDC_JWKS_URL
type: url — default: unset — module: idp
JWKS endpoint override for the external OIDC issuer.
MERGEN_SLACK_BOT_TOKEN
type: secret — default: unset — module: slack
Slack Web API token (threads, replies, HITL delivery fallback). Optional once the OAuth install flow has persisted a token.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SLACK_CHANNEL
type: string — default: unset — module: slack
Default incident channel.
MERGEN_SLACK_SIGNING_SECRET
type: secret — default: unset — module: slack
HMAC secret verifying inbound Slack interactions — without it every interactive button click is rejected with 401.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SLACK_WEBHOOK
type: secret — default: unset — module: slack
Simple-mode incoming webhook for alerts with link buttons.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SLACK_CLIENT_ID
type: string — default: unset — module: slack
Slack app OAuth client id — enables /slack/install.
MERGEN_SLACK_CLIENT_SECRET
type: secret — default: unset — module: slack
Slack app OAuth client secret for the install flow.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SLACK_DIGEST
type: boolean — default: unset — module: slack
Post the daily operational digest at 09:00 UTC.
MERGEN_SLACK_DIGEST_CHANNEL
type: string — default: unset — module: slack
Channel override for the daily digest.
MERGEN_TEAM_DIGEST
type: boolean — default: unset — module: slack
Post the weekly team digest Mondays 09:15 UTC (reports only, never HITL).
MERGEN_HITL_WEBHOOK_URL
type: secret — default: unset — module: hitl
Explicit HITL delivery webhook (first in preference order). The HOLD itself always runs on every plan; delivery is the convenience.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_HITL_SECONDARY_WEBHOOK
type: secret — default: unset — module: hitl
Delegation chain: fired at the 5-min mark if the primary channel produced no response.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_PAGERDUTY_SECRET
type: secret — default: unset — module: pagerduty
INBOUND webhook HMAC signing secret. Required in cloud mode and under autopilot.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_PAGERDUTY_ROUTING_KEY
type: secret — default: unset — module: pagerduty
OUTBOUND Events API v2 key — pages when HITL approvals go unanswered for 10 min. Distinct from the inbound signing secret.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_PR_COMMENTS
type: boolean — default: unset — module: github
Post AI code review comments on PRs (enables habituation tracking).
MERGEN_GITHUB_CLIENT_ID
type: string — default: unset — module: github
GitHub App/OAuth App client id — enables /github/install.
MERGEN_GITHUB_CLIENT_SECRET
type: secret — default: unset — module: github
GitHub App/OAuth App client secret for the install flow.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SENTRY_SECRET
type: secret — default: unset — module: sentry
HMAC secret verifying inbound Sentry webhooks. When unset, Sentry events are accepted only in local diagnosis-only mode.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SIEM_WEBHOOK_URL
type: url — default: unset — module: siem
Generic SIEM webhook — blunders + forwarded ledger rows POSTed as JSON.
MERGEN_SIEM_WEBHOOK_TOKEN
type: secret — default: unset — module: siem
Bearer token for the generic SIEM webhook.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SPLUNK_HEC_URL
type: url — default: unset — module: siem
Splunk HTTP Event Collector endpoint.
MERGEN_SPLUNK_HEC_TOKEN
type: secret — default: unset — module: siem
Splunk HEC token.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_ELASTIC_URL
type: url — default: unset — module: siem
Elasticsearch endpoint for audit forwarding.
MERGEN_ELASTIC_API_KEY
type: secret — default: unset — module: siem
Elasticsearch API key.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_EMAIL_DIGEST
type: boolean — default: unset — module: email
Enable the daily digest email.
MERGEN_SMTP_URL
type: secret — default: unset — module: email
Single-URL SMTP config (may embed credentials).
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SMTP_HOST
type: string — default: unset — module: email
SMTP host (discrete form).
MERGEN_SMTP_PORT
type: int — default: 587 — module: email
SMTP port.
MERGEN_SMTP_USER
type: string — default: unset — module: email
SMTP username.
MERGEN_SMTP_PASS
type: secret — default: unset — module: email
SMTP password.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_SMTP_SECURE
type: boolean — default: unset — module: email
Explicit TLS override (default true only on port 465).
MERGEN_EMAIL_FROM
type: string — default: unset — module: email
Digest sender address.
MERGEN_EMAIL_TO
type: csv — default: unset — module: email
Digest recipients.
MERGEN_NTFY_TOPIC
type: string — default: unset — module: notifications
ntfy.sh topic name.
MERGEN_NTFY_URL
type: url — default: https://ntfy.sh — module: notifications
ntfy server.
MERGEN_NTFY_TOKEN
type: secret — default: unset — module: notifications
ntfy access token.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_DISCORD_WEBHOOK_URL
type: secret — default: unset — module: notifications
Discord alert webhook.
Secret: set via an env-only mechanism (secrets manager, systemd EnvironmentFile). The value is never rendered by any Mergen surface and is rejected from the signed config file.
MERGEN_DOCKER_MONITOR
type: boolean — default: unset — module: docker
Docker container health monitoring.
MERGEN_DOCKER_LOGS
type: boolean — default: unset — module: docker
Stream stdout/stderr from running containers.
MERGEN_K8S_NAMESPACE
type: string — default: unset — module: k8s
Enable the K8s events poller for this namespace.
MERGEN_FLEET_SYNC_URL
type: url — default: unset — module: fleet-audit
Self-hosted sync plane URL member installs report audit rows to (single-team, own-infra).
Experimental flags
MERGEN_EXPERIMENTAL_* flags are undocumented, unstable, and bound by monotonic strictness: they may only add capability or escalate PASS→HOLD, never weaken a verdict.
Modules & tiers
The capability manifest (server/src/config/modules.ts) — inspect live state on any install with mergen-server config modules or GET /config/modules.
Trusted Core — no off switch exists in code
- Execution Gateway — MCP tool-call interception + the Claude Code Bash PreToolUse hook +
mergen-server exec. Every covered call passes the gate before its handler runs. - Policy Engine — Deterministic <1ms rule evaluation → PASS / HOLD / BLOCK. Immutable hard-safety rules cannot be edited or bypassed by any setting.
- Verdicts & Guided Alternatives — Every BLOCK/HOLD carries why it happened and what to do instead, so agents reformulate instead of stopping.
- Audit Recording — Action ledger (every PASS/HOLD/BLOCK), hash-chained Agent Blunder Log, usage meter. Recording is core; forwarding is an integration; retention is config.
- Human-in-the-Loop Holds — HOLD suspends the call for human decision and fails closed (15-min auto-deny). The hold is core on every plan; delivery channels are integrations.
- Admin Auth Guards — Mutation + sensitive-GET guards over every admin surface, including the signed org-policy settings file.
- PII Shield — Always-on redaction patterns (emails, keys, JWTs, cards) on stored/streamed content; extendable, never disableable.
Modules — toggleable; disabling can only make the gate same-or-stricter
- Incident Autopilot (Gate B) — Autonomous diagnose→fix→validate loop on incidents. Off by default; shadow mode is its staging tier.
- Override Corpus — Human overrides encoded as enforcement policy; feeds Gate B always and Gate A via the four explicit opt-in paths.
- Policy Suggester — Stages repeatedly-overridden patterns as HOLD-only proposals for one-click human approval. Never auto-activates, never proposes a BLOCK.
- Change Authorization Gate (Gate C) — POST /ci/gate diff-content review: deterministic detectors (secret introduction, test deletion, auth-bypass, CI-check removal, permission/config weakening) plus a heuristic task-to-diff scope match. Governs what code a PR is allowed to leave behind, distinct from Gate A (tool-call execution) and Gate B (autopilot fixes). MERGEN_CHANGE_GATE_MODE=shadow runs the same evaluation for measurement without affecting the verdict, CI build, or review label — the rollout ramp before MODE=enforce.
- Script Trust — Opaque-script escalation: untracked/fresh scripts hold for approval; approval vouches for exact content (HMAC-signed store). Window=0 disables only the freshness check; git-tracking and workspace checks stay on.
- Exec Sandbox — Runs
mergen-server execcommands in Docker or macOS Seatbelt isolation instead of directly on the host. - Cloud Credential Broker — Ephemeral task-scoped AWS/GCP/Azure credentials instead of long-lived secrets in agent config. Active when credential scopes are configured.
- Agent & Human Identity — Verified agent tokens with SSO-federated human principals bound in; RBAC roles for approvals.
- Incident Memory & Diagnosis — Causal analysis, incident similarity, postmortem retrieval — the context brief that cuts MTTR.
- Process Watchers — Local process/port auto-watch feeding runtime telemetry into the buffer.
- Degradation Watcher — Background watcher that flags sustained error-rate degradation.
- Confidence Calibration — Platt-scaled confidence from engineer verdict tags — governs Gate B autonomy thresholds only.
Integrations — delivery & ingest channels
- Slack — Incident threads, HITL approve/deny buttons, daily + weekly digests.
- HITL Delivery Webhooks — Explicit webhook chain for hold notifications (primary + 5-min secondary escalation).
- PagerDuty — Inbound incident webhooks (signed) + outbound paging on unanswered HITL approvals.
- GitHub — PR review comments (habituation), webhook-fed commit context, CI gate reporting.
- Sentry — Error events into the diagnosis buffer (signed webhooks).
- Datadog — Trace fetch + blame attribution during triage.
- SIEM Forwarding — Blunders + selected ledger verdicts streamed to webhook / Splunk HEC / Elastic.
- Email Digest — Daily/weekly digest sink. Deliberately NEVER a HITL channel (pinned by test).
- Push Notifications — ntfy.sh and Discord alert channels.
- Docker Monitoring — Container health + log streaming into the buffer.
- Kubernetes — Namespace events poller.
- IDP Enrichment (Okta / Entra) — Operator identity enrichment from the org IDP.
- Policy Sync Plane — Pulls the team's shared policy from a central instance (HTTPS + HMAC verified).
- Cloud Policy Sync — Automatically pulls and activates Mergen Cloud org policy for signed-in paid-plan installs (distinct from the self-hosted Policy Sync Plane above).
- Fleet Audit Sync — Member installs report ledger rollups to a self-hosted sync plane (single-team, own infra).
- Redis Persistence — Ring-buffer persistence across restarts.