Reference

Environment variables

Every environment variable DefenseClaw reads, grouped by category, with defaults, accepted values, and the file:line that consumes each one.

This is the canonical list of every environment variable DefenseClaw reads. The list is generated from internal/envvars/registry.json; CI fails if any callsite references a DEFENSECLAW_* var not declared in the registry.

See live what's active

defenseclaw doctor surfaces any active security override in real time. Operators with no overrides set see a single "none active" pass row; if you've left a debug toggle on, doctor flags it loudly.

Security opt-outs

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_ALLOW_CGNATHIGHunset (CGNAT blocked)1, unsetAllow RFC 6598 carrier-grade NAT addresses (100.64.0.0/10, used by Tailscale and similar overlays) through the SSRF / private-IP guards.CGNAT egress guard — prevents SSRF into shared carrier-grade NAT / overlay-network address space (e.g. another tenant's Tailscale node).internal/netguard/netguard.go:94 — cgnatAllowed() omits 100.64.0.0/10 from the reserved-CIDR list when set
cli/defenseclaw/webhooks/writer.py:415 — _cgnat_allowed() gates webhook URL validation for CGNAT IPs
cli/defenseclaw/registries/ssrf.py:52 — _cgnat_allowed() gates registry/manifest SSRF resolution for CGNAT
DEFENSECLAW_ALLOW_HOOK_CONTRACT_DRIFTHIGHunset (fail-closed in action mode)1, unsetBypass the action-mode fail-closed checks for unverified hook contracts and hook-contract lock drift during connector setup, allowing enforcing hooks to be installed against agent versions outside the verified contract matrix.Hook contract verification — prevents installing an enforcing hook whose request/response contract has drifted from the verified matrix (a silent guardrail bypass).internal/gateway/sidecar.go:1417 — Blocks connector setup on an unverified hook contract in action mode unless set
internal/gateway/sidecar.go:1422 — Blocks connector setup on hook-contract lock drift in action mode unless set
cli/defenseclaw/commands/cmd_setup.py:2499 — Python setup path mirrors the gateway drift/contract enforcement
DEFENSECLAW_ALLOW_LOCAL_MCP_TARGETSHIGHunset (SSRF guard enforced)1, unsetSkip SSRF validation for MCP scan target URLs, permitting loopback, private, link-local, and cloud-metadata destinations.MCP scan-target SSRF guard — prevents a scan request from reaching IMDS / loopback / private hosts.internal/scanner/mcp.go:56 — validateMCPScanTargetURL() returns early without SSRF checks when set
DEFENSECLAW_CODEX_LOOPBACK_TRUSTHIGHunset (fail-closed)1, unsetRestore legacy loopback-trusts-any-bearer behavior for the Codex connector.Per-bearer Codex authentication on loopback — prevents same-host user-to-user impersonation when multiple users share an OS account.internal/gateway/connector/codex.go:310 — Authenticate() falls back to legacy behavior when set; emits a [SECURITY] log line
DEFENSECLAW_DEVlowunset1, true, unsetMark the process as a developer build.internal/redaction/credentials.go:173 — isCredentialScrubDevMode reads this var
DEFENSECLAW_DISABLE_AWS_HTTP1_SHIMmediumunset (shim active for Bedrock)1, unsetDisable the AWS Bedrock HTTP/1 monkey-patch the OpenClaw plugin installs to make Bedrock traffic visible to the guardrail proxy.extensions/defenseclaw/src/aws-sdk-http1-for-guardrail.ts:265 — JS shim bails out when set
DEFENSECLAW_DISABLE_REDACTIONHIGHunset (redaction enabled)1, true, unsetDisable all PII / credential redaction across every sink (audit DB, JSONL, OTel, Splunk, webhooks).internal/redaction/redaction.go:111 — DisableAll() reads this env var
cli/defenseclaw/commands/redaction_status.py:42 — Python status reporter
cli/defenseclaw/commands/cmd_setup.py:3158 — Setup flow surfaces this in onboarding
DEFENSECLAW_DUMP_RAW_SECRETSHIGHunset1, unsetE2E test toggle ONLY.scripts/test-e2e-full-stack.sh:1038 — Dumps raw secrets in diagnostic output for test debugging
DEFENSECLAW_FAIL_MODEmedium(value from guardrail.hook_fail_mode in config.yaml)open, closed, unsetPer-shell override of guardrail.hook_fail_mode for malformed, unauthorized, or incomplete gateway responses.internal/gateway/connector/hooks/inspect-tool.sh:83 — Representative shared template; every generated hook reads the same override
DEFENSECLAW_FORCE_AWS_HTTP1_SHIMlowunset (shim only on Bedrock)1, unsetForce the AWS HTTP/1 shim to install even on non-Bedrock setups.extensions/defenseclaw/src/aws-sdk-http1-for-guardrail.ts:272 — JS shim forces install when set
DEFENSECLAW_JSONL_DISABLElowunset (JSONL enabled)1, true, unsetDisable the gateway.jsonl audit tier.internal/gateway/sidecar.go:226 — Gateway boot reads this kill switch
internal/gateway/jsonl_kill_switch.go — Definition site
DEFENSECLAW_OPENSHELL_ALLOW_UNPINNEDmediumunset (fail-closed)1, unsetAccept a mutable OCI tag (e.g. 'latest') when installing openshell-sandbox instead of requiring a content-addressed digest or sha256 pin.
Fix: Pin via DEFENSECLAW_OPENSHELL_ARCH_DIGEST or DEFENSECLAW_OPENSHELL_BINARY_SHA256.
Pinned-digest sandbox install — prevents tag-mutation supply-chain attacks where an upstream tag is silently re-pointed at a malicious image.scripts/install-openshell-sandbox.sh:159 — Skips integrity verification when set
DEFENSECLAW_OPENSHELL_ARCH_DIGESTunsetsha256:<hex>, unsetPin the openshell-sandbox install to a specific platform manifest digest (sha256:...).Pinned-digest sandbox install — content-addressed verification of the OCI manifest before extraction.scripts/install-openshell-sandbox.sh:151 — Verifies OCI manifest digest against this pin
DEFENSECLAW_OPENSHELL_BINARY_SHA256unset64-char hex sha256, unsetPin the final extracted openshell-sandbox binary to a specific sha256.Pinned-digest sandbox install — sha256 verification of the extracted binary.scripts/install-openshell-sandbox.sh:157 — Marker check (presence enables sha256 verification path)
scripts/install-openshell-sandbox.sh:250 — Verifies extracted binary sha256 against this pin
DEFENSECLAW_OTEL_TLS_INSECUREHIGHunsettrue, false, 1, 0, unsetLegacy flat OTLP TLS toggle consumed only for upgrade compatibility.Enabling this variable disables OTLP server-certificate verification after legacy configuration is migrated into a named destination.internal/config/config.go:2769 — Migrates legacy env-backed flat OTel TLS policy into a named destination
cli/defenseclaw/observability/writer.py:742 — Preserves legacy env-backed TLS policy when setup adds a named destination
DEFENSECLAW_POLICY_VALIDATE_ALLOW_NO_OPAmediumunset (validation requires OPA)1, unsetAccept a policy file as 'validated' even when OPA / Rego is not installed.cli/defenseclaw/commands/cmd_policy.py:1135 — Policy validate command bypass
DEFENSECLAW_PREPAIR_TRUST_DEVICE_KEYHIGHunset (fail-closed)1, unsetBypass the provenance-sentinel check during 'defenseclaw sandbox setup' pre-pairing.
Fix: Restart the gateway once after upgrading; LoadOrCreateIdentity auto-writes the .provenance sentinel and the env var is no longer needed.
Provenance-sentinel verification — prevents acceptance of an unauthenticated device.key file (e.g. a copy left on disk by a prior install or attacker).cli/defenseclaw/commands/cmd_setup_sandbox.py:1759 — _pre_pair_device gates the provenance fail-closed branch on this var
DEFENSECLAW_REVEAL_PIImediumunset (PII redacted everywhere)1, true, unsetReveal PII in operator-facing logs only (CLI stdout, TUI).internal/redaction/redaction.go:90 — Reveal() reads this env var
DEFENSECLAW_SANDBOX_FORCE_REGEX_CLEANUPmedium0 (no regex sweep)1, 0, unsetOpt into the legacy broad regex cleanup of sandbox/openshell network namespaces when no saved namespace file exists.Namespace cleanup scope — a broad regex sweep can delete unrelated network namespaces on a shared host.cli/defenseclaw/commands/cmd_setup_sandbox.py:1258 — Embedded pre-sandbox script reads it before namespace cleanup
cli/defenseclaw/commands/cmd_setup_sandbox.py:1481 — Embedded cleanup-sandbox script reads it
DEFENSECLAW_SCHEMA_VALIDATIONmediumonoff, unsetDisable the runtime JSON-schema gate that validates event payloads before they hit sinks.internal/gateway/sidecar.go:243 — Gateway boot reads and toggles the schema gate
DEFENSECLAW_STRICT_AVAILABILITYunset (transport failures fail-open)1, unsetOpt-IN to fail-closed on transport errors during hook execution.internal/gateway/connector/hooks/_hardening.sh:250 — Hook hardening sourced by every *-hook.sh
DEFENSECLAW_TESTlowunset1, true, unsetMark the process as running under tests.internal/redaction/credentials.go:176 — isCredentialScrubDevMode reads this var
DEFENSECLAW_TOOL_INSPECT_FAIL_OPENHIGHunset (fail-closed)1, true, unsetMake the plugin-side tool-inspect hook fail-open (allow tool) when the gateway is unreachable.extensions/defenseclaw/src/index.ts:98 — OpenClaw plugin tool-inspect handler
DEFENSECLAW_TRUSTED_PROXY_CIDRSmediumunset (X-Forwarded-For ignored)comma-separated CIDRs or IPs, unsetComma-separated CIDRs (or bare IPs) of reverse-proxy peers whose X-Forwarded-For header is trusted for client-IP attribution in logs.Client-IP attribution — trusting forwarded headers from an untrusted peer lets a caller spoof the source IP recorded in auth-failure and audit logs.internal/gateway/requestctx.go:369 — isTrustedProxyPeer() trusts X-Forwarded-For only from these peers
DEFENSECLAW_UPGRADE_ALLOW_UNVERIFIEDHIGHunset (fail-closed)1, unsetSkip checksum / signature verification during 'defenseclaw upgrade' or scripts/upgrade.sh.Upgrade-artifact integrity — prevents installing a tampered tarball/wheel pulled from a hijacked release CDN or MITM.cli/defenseclaw/commands/cmd_upgrade.py:318 — Python upgrade path checks this before downloading without a checksum
scripts/upgrade.sh:263 — Shell upgrade path checks this before proceeding without verification
DEFENSECLAW_UPGRADE_TARBALL_SHA256unset64-char hex sha256, unsetOperator-provided sha256 pin for the gateway tarball downloaded by defenseclaw upgrade.Operator-supplied checksum pin for upgrade artifacts — defense-in-depth alongside the sidecar .sha256 file.cli/defenseclaw/commands/cmd_upgrade.py:341 — Python upgrade verifier
scripts/upgrade.sh:225 — Shell upgrade verifier
DEFENSECLAW_UPGRADE_WHL_SHA256unset64-char hex sha256, unsetOperator-provided sha256 pin for the Python CLI wheel downloaded by defenseclaw upgrade.Operator-supplied checksum pin for upgrade artifacts — defense-in-depth alongside the sidecar .sha256 file.cli/defenseclaw/commands/cmd_upgrade.py:358 — Python upgrade verifier
scripts/upgrade.sh:226 — Shell upgrade verifier
DEFENSECLAW_WEBHOOK_ALLOW_LOCALHOSTmediumunset (SSRF guard blocks private IPs)1, unsetRelax the webhook SSRF guard to permit RFC1918 / loopback / link-local destinations.internal/gateway/webhook.go:139 — Webhook sender SSRF gate
internal/gateway/webhook.go:563 — Webhook validate-on-add SSRF gate
cli/defenseclaw/webhooks/writer.py:412 — Python writer validate-on-add

Credentials & secrets

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_GATEWAY_TOKENHIGHunsetbearer-token, unsetBearer token hooks present to the gateway API.internal/gateway/connector/hooks/inspect-tool.sh:30 — Hooks present this header
internal/cli/sidecar.go:43 — Sidecar references in setup messages
DEFENSECLAW_LLM_KEYHIGHunsetLLM API key string, unsetCanonical env-var name for the unified LLM key.cli/defenseclaw/credentials.py — Credentials registry default for llm.api_key_env
DEFENSECLAW_LLM_KEY_ENVlowDEFENSECLAW_LLM_KEYany env-var nameIndirection: name of the env var to read the LLM key from.cli/defenseclaw/credentials.py — Credentials registry indirection
DEFENSECLAW_LLM_MODELlow(value from llm.model in config.yaml)provider/model-id, unsetOverride the configured LLM model id at runtime.cli/tests/test_config.py:667 — Tested override path
DEFENSECLAW_LLM_MODEL_ENVlowDEFENSECLAW_LLM_MODELany env-var nameIndirection: name of the env var to read the LLM model from.cli/defenseclaw/credentials.py — Credentials registry indirection
DEFENSECLAW_LOCAL_PASSWORDHIGHunsetany-string, unsetPassword for the local Splunk daemon basic-auth surface.internal/cli/daemon.go:212 — Daemon reads from .env
DEFENSECLAW_LOCAL_USERNAMEmediumunsetany-string, unsetUsername for the local Splunk daemon basic-auth surface.internal/cli/daemon.go:211 — Daemon reads from .env
DEFENSECLAW_MASTER_KEYHIGH(derived at boot from device.key)sk-dc-<hex>Bearer derived from device.key (PBKDF2).internal/gateway/proxy.go:3338 — deriveMasterKey
DEFENSECLAW_PD_KEYmediumunsetpagerduty-key, unsetAlias for DEFENSECLAW_PD_ROUTING_KEY.cli/defenseclaw/commands/cmd_setup_webhook.py:166 — Alternative PD key var
DEFENSECLAW_PD_ROUTING_KEYmediumunsetpagerduty-routing-key, unsetPagerDuty routing key default for webhook entries.cli/defenseclaw/commands/cmd_setup_webhook.py:166 — Webhook setup default
DEFENSECLAW_PROXY_TOKENlowunsetany-string, unsetTest-harness proxy bearer.scripts/test-proxy-sandbox.py:940 — Test proxy bearer
DEFENSECLAW_REGISTRY_TOKENmediumunsetregistry-token, unsetDefault registry auth env var (e.g.cli/defenseclaw/commands/cmd_registry.py:133 — Registry default auth_env
DEFENSECLAW_SIEM_SECRETmediumunsetany-string, unsetSIEM webhook secret default.cli/defenseclaw/commands/cmd_setup_webhook.py:166 — Webhook setup default
DEFENSECLAW_SKILLSSH_TOKENmediumunsetregistry-token, unsetExample registry-specific token env var.cli/defenseclaw/commands/cmd_registry.py:334 — Registry example token
DEFENSECLAW_SKILL_SCANNER_LLM_KEYHIGHunsetLLM API key string, unsetOverride the LLM key used by the skill scanner only.cli/defenseclaw/credentials.py — Credentials registry
DEFENSECLAW_SPLUNK_HEC_TOKENHIGHunsetHEC token, unsetAlternative HEC token consulted by the Python sink wiring when the canonical splunk_hec.token_env points to a different var.cli/defenseclaw/commands/cmd_setup.py:4911 — Python Splunk wiring fallback
DEFENSECLAW_WEBEX_TOKENmediumunsetwebex-bot-token, unsetWebex bot token default for webhook entries.cli/defenseclaw/commands/cmd_setup_webhook.py:166 — Webhook setup default
DEFENSECLAW_WEBHOOK_SECRETmediumunsetany-string, unsetGeneric webhook HMAC secret default.cli/defenseclaw/commands/cmd_setup_webhook.py:166 — Webhook setup default

Paths & runtime layout

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_API_ADDRlow(templated value from gateway.api_port at hook install time)host:port, unsetSidecar API address that hooks dial.internal/gateway/connector/hooks/inspect-tool.sh:42 — Hooks dial this
DEFENSECLAW_BINlow(discovered via PATH lookup)any-absolute-pathOverride path to the defenseclaw CLI binary.internal/scanner/plugin_test.go:177 — Plugin test harness
scripts/setup-llm.sh:51 — LLM setup script
DEFENSECLAW_CONFIGmedium${DEFENSECLAW_HOME}/config.yamlany-absolute-path, unsetOverride the config.yaml path independently from DEFENSECLAW_HOME.Managed config path separation — lets system services read admin-owned policy without making the runtime data directory admin-writable.internal/config/defaults.go:78 — Go config path resolver
cli/defenseclaw/config.py:187 — Python config path resolver
cli/defenseclaw/migrations.py:145 — Migration config path resolver
DEFENSECLAW_CUSTOM_PROVIDERS_PATHlowunsetany-absolute-path, unsetPath to a custom providers YAML file consulted before the embedded catalog.internal/configs/embed.go:71 — Go embedded-providers loader
DEFENSECLAW_DEPLOYMENT_MODEHIGHunset (use config.yaml deployment_mode)managed_enterprise, unmanaged_byod, unsetPin the process deployment mode independently from config.yaml.Immutable managed-mode boundary — prevents config replacement from disabling administrator-owned path and ownership checks.internal/config/config.go — Pins deployment mode before parsing or trusting config.yaml
packaging/systemd/defenseclaw-gateway.service — Managed Linux service pin
packaging/launchd/com.defenseclaw.gateway.plist — Managed macOS service pin
DEFENSECLAW_DIRlow(templated at install time)any-absolute-pathUsed in generated openshell-sandbox shell wrappers to locate the DefenseClaw install dir from inside the sandbox.cli/defenseclaw/commands/cmd_setup_sandbox.py:1202 — Sandbox shell wrappers reference this
DEFENSECLAW_GATEWAY_BINlow(discovered via PATH lookup)any-absolute-pathOverride path to the defenseclaw-gateway binary.cli/defenseclaw/gateway.py:315 — Python gateway-process spawner
DEFENSECLAW_GUARDIAN_AGENT_VERSIONmediumunset (falls back to cached discovery version when available)agent version string, unsetSystemd template override supplying the local agent version used for enterprise hook-contract validation.Action-mode hook contract validation — lets managed deployments pin the agent version the guardian validates before writing blocking hooks.docs-site/content/docs/setup/enterprise-deployment.mdx:124 — Documented systemd template override for action-mode hook contract validation
DEFENSECLAW_GUARDIAN_CONNECTORlowunsetregistered hook-native connector nameSystemd template override naming the connector reconciled by an enterprise hook guardian instance.Template-scoped connector selection — avoids broad home scanning by keeping each privileged guardian instance bound to an explicit connector target.docs-site/content/docs/setup/enterprise-deployment.mdx:123 — Documented systemd template override for per-user hook guardian instances
DEFENSECLAW_HOME~/.defenseclawany-absolute-pathOverride the canonical data dir (default ~/.defenseclaw).internal/config/defaults.go:62 — Go default-resolver
cli/defenseclaw/config.py:98 — Python config loader
cli/defenseclaw/connector_paths.py:1305 — Connector path resolver
scripts/install.sh:50 — Installer reads this
scripts/upgrade.sh:49 — Upgrader reads this
internal/gateway/connector/hooks/inspect-tool.sh:9 — Hooks read this
DEFENSECLAW_HOOK_GUARDIAN_AUTH_DIRHIGH${DEFENSECLAW_HOME}-hook-guardianany-absolute-admin-owned-path, unsetSelect the administrator-owned directory containing the hook guardian protected-target authorization ledger.Privileged repair authorization — must remain root/admin-owned and non-writable by the DefenseClaw service account.internal/managed/managed.go — Resolves the protected-target authorization path
internal/cli/enterprise_hooks.go — Privileged guardian writes successful protected targets
internal/gateway/sidecar.go — Managed health verifies connector coverage before advertising enforcement
DEFENSECLAW_INSTALL_DIRlow$HOME/.local/binany-absolute-pathDirectory where CLI symlinks are placed by install.sh / setup-llm.sh.scripts/setup-llm.sh:59 — Install location for setup-llm
DEFENSECLAW_OVERLAY_ROOTlowunsetany-absolute-path, unsetExtra provider-catalog overlay dir merged on top of the built-in catalog.cli/defenseclaw/commands/cmd_setup_provider.py:115 — Provider setup overlay loader
DEFENSECLAW_SIDECAR_URLlowhttp://127.0.0.1:18790any-http-urlTarget URL for the bundled CodeGuard skill (skills/codeguard/main.py) to call into the sidecar.skills/codeguard/main.py:35 — Skill sidecar URL
DEFENSECLAW_VENV${DEFENSECLAW_HOME}/.venvany-absolute-pathPath to the DefenseClaw uv venv.scripts/install.sh:51 — Installer venv path
scripts/upgrade.sh:50 — Upgrader venv path
MIGRATION_DEFENSECLAW_HOME(set by upgrade.sh)any-absolute-pathPassed by scripts/upgrade.sh to the migration step.scripts/upgrade.sh:376 — Upgrade-time migration runner

Telemetry (OTel)

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_JUDGE_PERSIST_QUEUE_SIZEunset (config guardrail.judge_persist_queue_depth, default 1024)positive integer, unsetEmergency boot-time override for the async judge-persistence queue depth.internal/gateway/sidecar.go:364 — Overrides cfg.Guardrail.JudgePersistQueueDepth at sidecar boot
DEFENSECLAW_OTEL_ENABLED(value from otel.enabled in config.yaml)true, false, 1, 0, unsetMaster toggle for the OTel exporter.internal/config/config.go:2297 — viper.BindEnv otel.enabled
DEFENSECLAW_OTEL_ENDPOINTunsetany-otlp-endpoint, unsetLegacy flat OTLP exporter endpoint consumed only for upgrade compatibility.internal/config/config.go:2684 — Migrates legacy env-backed flat OTel export into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:634 — Preserves legacy env-backed flat OTel export when setup adds a named destination
DEFENSECLAW_OTEL_LOGS_ENDPOINTunsetany-otlp-endpoint, unsetLegacy log-specific flat OTLP endpoint consumed only for upgrade compatibility.internal/config/config.go:2724 — Migrates a legacy logs-only env-backed exporter into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:655 — Preserves a legacy logs-only route when setup adds a named destination
DEFENSECLAW_OTEL_LOGS_PROTOCOLunsetgrpc, grpc/protobuf, http, http/protobuf, http/json, unsetLegacy log-specific flat OTLP protocol consumed only for upgrade compatibility.internal/config/config.go:2740 — Migrates a legacy logs-only env-backed exporter into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:664 — Preserves a legacy logs-only route when setup adds a named destination
DEFENSECLAW_OTEL_METRICS_ENDPOINTunsetany-otlp-endpoint, unsetLegacy metric-specific flat OTLP endpoint consumed only for upgrade compatibility.internal/config/config.go:2723 — Migrates a legacy metrics-only env-backed exporter into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:655 — Preserves a legacy metrics-only route when setup adds a named destination
DEFENSECLAW_OTEL_METRICS_PROTOCOLunsetgrpc, grpc/protobuf, http, http/protobuf, http/json, unsetLegacy metric-specific flat OTLP protocol consumed only for upgrade compatibility.internal/config/config.go:2739 — Migrates a legacy metrics-only env-backed exporter into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:664 — Preserves a legacy metrics-only route when setup adds a named destination
DEFENSECLAW_OTEL_PROTOCOLunsetgrpc, grpc/protobuf, http, http/protobuf, http/json, unsetLegacy flat OTLP exporter protocol consumed only for upgrade compatibility.internal/config/config.go:2695 — Migrates legacy env-backed flat OTel export into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:699 — Preserves legacy env-backed flat OTel export when setup adds a named destination
DEFENSECLAW_OTEL_TRACES_ENDPOINTunsetany-otlp-endpoint, unsetLegacy trace-specific flat OTLP endpoint consumed only for upgrade compatibility.internal/config/config.go:2683 — Migrates legacy env-backed flat OTel export into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:633 — Preserves legacy env-backed flat OTel export when setup adds a named destination
DEFENSECLAW_OTEL_TRACES_PROTOCOLunsetgrpc, grpc/protobuf, http, http/protobuf, http/json, unsetLegacy trace-specific flat OTLP protocol consumed only for upgrade compatibility.internal/config/config.go:2694 — Migrates legacy env-backed flat OTel export into a generic-otlp named destination
cli/defenseclaw/observability/writer.py:698 — Preserves legacy env-backed flat OTel export when setup adds a named destination
DEFENSECLAW_RUN_IDauto-generated UUID at gateway bootany-string, unsetCorrelation ID stamped on every event for cross-sink joins.internal/gatewaylog/runid.go:58 — Go reader
internal/audit/store.go:2390 — Audit store reader
internal/gateway/sidecar.go:114 — Sidecar boot
cli/defenseclaw/logger.py:172 — Python logger reader
cli/defenseclaw/db.py:739 — Python DB reader
scripts/test-e2e-full-stack.sh:54 — E2E test runner default
DEFENSECLAW_TELEMETRY_ENABLEDunset1, 0, unsetLocal-observability-stack-only toggle.bundles/local_observability_stack/docker-compose.yml:17 — Compose-file env reference
DEFENSECLAW_TRACEPARENTunset (no traceparent forwarded)W3C traceparent string, unsetW3C traceparent header value propagated from the agent/hook environment into outbound hook HTTP requests and the Codex telemetry bridge, enabling distributed-trace correlation.internal/cli/hook.go:137 — Native hook reads it (precedence over TRACEPARENT / OTEL_TRACEPARENT)
internal/gateway/connector/hooks/_hardening.sh:661 — Bash hook trace-context extraction
internal/gateway/connector/codex.go:975 — Codex telemetry bridge forwards it on outbound curls
DEFENSECLAW_TRACESTATEunset (no tracestate forwarded)W3C tracestate string, unsetW3C tracestate header value propagated alongside traceparent for vendor-specific trace baggage on hook and Codex telemetry outbound requests.internal/cli/hook.go:142 — Native hook reads it alongside traceparent
internal/gateway/connector/hooks/_hardening.sh:674 — Bash hook trace-context extraction
internal/gateway/connector/codex.go:976 — Codex telemetry bridge forwards it on outbound curls

Debug / verbose logging

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_DEBUGlowunset1, unsetGateway client logs every request/response frame to stderr.internal/gateway/client.go:80 — Client struct gates verbose logging on this var
DEFENSECLAW_JUDGE_TRACEmediumunset1, true, unsetLLM judge logs every prompt + response.internal/gateway/llm_judge.go:62 — Judge debug toggle
DEFENSECLAW_LLM_DEBUGmediumunset1, true, unsetPython LLM bridge logs per-request prompt + response bodies.cli/defenseclaw/llm.py:110 — LLM bridge _DEBUG flag
DEFENSECLAW_PERSIST_JUDGEmediumunset1, true, unsetPersist every judge prompt + response to disk under data_dir.internal/gateway/sidecar.go:134 — Gateway boot enables judge persistence
DEFENSECLAW_SIDECAR_DIAGlowunset1, true, unsetExtra sidecar boot-time diagnostics (config dump, env presence).internal/cli/sidecar.go:212 — sidecarDiagEnabled helper
DEFENSECLAW_TUI_SKIP_FIRST_RUN_PROMPTunset (prompt shown on a TTY)1, true, yes, unsetSkip the interactive first-run setup wizard prompt when launching the TUI, proceeding directly without asking whether to run setup.cli/defenseclaw/tui/__init__.py:53 — Gates the interactive first-run setup prompt
DEFENSECLAW_WEBHOOK_DEBUGmediumunset1, unsetWebhook dispatcher dumps full request bodies (including secrets) to stderr.internal/gateway/webhook.go:146 — Webhook sender debug field

Discovery & probes

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_ANTHROPIC_PROBE_MODELclaude-3-5-haiku-latestany-anthropic-model-idOverride the model used by 'defenseclaw doctor' to probe Anthropic API key validity.cli/defenseclaw/commands/cmd_doctor.py:659 — Doctor's Anthropic probe
DEFENSECLAW_TRUSTED_BIN_PREFIXESmediumunset (built-in defaults only)os.pathsep-separated absolute paths (':' POSIX, ';' Windows), unsetExtra trusted binary prefixes for AI Discovery's binary probing, separated by os.pathsep (':' on POSIX, ';' on Windows).Tight binary-discovery trust list — prevents PATH-shadow elevation where a malicious binary in a user-writable dir gets probed and treated as a real agent runtime. 'trusted-paths add' refuses world-writable and non-absolute directories unless --force.cli/defenseclaw/inventory/agent_discovery.py:289 — Agent discovery binary probe
cli/defenseclaw/commands/cmd_setup.py:1587 — setup trusted-paths CLI and inline trust prompt persistence

Hook-internal (do not override)

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_AGENT_ID(set by plugin / hooks)any-stringAgent identity propagated through correlation headers and OTel attributes.internal/cli/scan_v7.go:69 — Go reader
extensions/defenseclaw/src/__tests__/agent_identity.test.ts:61 — JS plugin reader (tested)
DEFENSECLAW_AGENT_INSTANCE_ID(set by plugin / hooks)any-stringPer-instance agent identifier; used to disambiguate concurrent runs of the same agent.internal/cli/scan_v7.go:70 — Go reader
DEFENSECLAW_AGENT_NAME(set by plugin / hooks)any-stringHuman-readable agent name propagated via correlation headers.extensions/defenseclaw/src/index.ts:315 — JS plugin header emit
DEFENSECLAW_BAKED_HOOK_PATHmediumempty (default PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin)colon-separated absolute paths, unsetBaked into the installed _hardening.sh helper at hook-generation time.Hook PATH lockdown — a mis-baked value that widens PATH could re-admit attacker-writable directories to hook execution.internal/gateway/connector/hooks/_hardening.sh:149 — defenseclaw_harden_env() uses it to set the locked-down hook PATH
DEFENSECLAW_CLIENT(set by plugin)any-stringClient name (e.g. openclaw-plugin) stamped on the X-DefenseClaw-Client correlation header.extensions/defenseclaw/src/policy/enforcer.ts:156 — Enforcer header
DEFENSECLAW_DAEMON(set by daemon launcher; child only)1Sentinel set by the daemon launcher in the child process so it knows it's the daemon.internal/daemon/daemon.go:35 — EnvDaemon constant
DEFENSECLAW_DATA_DIRunset (set by the daemon on child processes)absolute data-directory pathMarker injected by the daemon launcher into the spawned gateway child process environment, recording which data directory that child belongs to.internal/daemon/daemon.go:307 — Written into the gateway child env to tag the owning data directory
DEFENSECLAW_GATEWAY_ADDR127.0.0.1:<api_port>loopback host:port, unsetGateway API address for the Windows native Go hook entrypoint.Loopback-only enforcement — a non-loopback gateway address is rejected so a hook cannot be redirected to an off-box collector.internal/cli/hook.go:94 — Primary env resolution of the hook's gateway API address
internal/cli/hook.go:97 — Sidecar .hookcfg fallback for the same key
DEFENSECLAW_HOOK_CONNECTOR(set by hooks)claudecode, codex, openclaw, zeptoclaw, inspect, ...Internal label identifying which connector's hook is executing.internal/gateway/connector/hooks/inspect-tool.sh:22 — Each hook exports this
DEFENSECLAW_HOOK_CWD(set by hooks)absolute-pathResolved CWD exported by hooks; used by sanitizeHookCWD to bound git operations.internal/gateway/connector/hooks/_hardening.sh:99 — Hook hardening
DEFENSECLAW_HOOK_HOME(set by hooks)absolute-pathHardened HOME exported by hooks to insulate them from operator HOME.internal/gateway/connector/hooks/_hardening.sh:76 — Hook hardening
DEFENSECLAW_HOOK_MAX_BODYlow1048576positive integerRequest-body cap (in bytes) for hooks.internal/gateway/connector/hooks/_hardening.sh:346 — Body-cap enforcement
DEFENSECLAW_HOOK_NAME(set by hooks)inspect-tool, inspect-request, ...Internal label identifying which hook is executing.internal/gateway/connector/hooks/inspect-tool.sh:23 — Each hook exports this
DEFENSECLAW_HOOK_PATH(set by hooks)colon-separated pathsHardened PATH exported by hooks (system-only) so a hostile workspace can't shadow git/curl/etc.internal/gateway/connector/hooks/_hardening.sh:88 — Hook hardening
DEFENSECLAW_HOOK_PATH_TRUSTEDunset (always stripped before PATH lockdown)unsetCompanion name to DEFENSECLAW_HOOK_PATH that an agent process might set.Hook PATH lockdown — stripped so an agent-supplied 'trusted' flag cannot re-enable an attacker-controlled PATH.internal/gateway/connector/hooks/_hardening.sh:148 — unset DEFENSECLAW_HOOK_PATH_TRUSTED during env hardening (anti-consumed)
DEFENSECLAW_MANAGED_HOOKHIGHunset (set to 1 only by generated managed hooks)1, unsetImmutable sentinel baked into managed-enterprise hook scripts so missing authentication material and unavailable enforcement fail closed even when an inherited environment requests permissive availability behavior.Managed enforcement fail-closed boundary — the value is generated by the privileged hook installer and is not an operator security opt-out.internal/gateway/connector/hooks/*-hook.sh — Managed hook templates set and export the sentinel from trusted generated script content
internal/gateway/connector/hooks/_hardening.sh — Missing-token and transport-failure handling forces fail-closed behavior when the sentinel is set
DEFENSECLAW_OPENCLAW_MAINlow(set by plugin bootstrap)absolute-pathSentinel read by the OpenClaw plugin bootstrapper to locate its main module.extensions/defenseclaw/src/aws-sdk-http1-for-guardrail.ts:163 — Plugin bootstrap sentinel
DEFENSECLAW_PLUGIN_AGENT_ID(set by plugin)any-stringPlugin-side agent ID.extensions/defenseclaw/src/__tests__/agent_identity.test.ts:71 — JS plugin reader (tested)
DEFENSECLAW_SIDECAR_INSTANCE_ID(auto-generated by gateway)uuid-or-similarSidecar instance ID; auto-generated by the gateway at boot, propagated via headers.internal/cli/scan_v7.go:71 — Go reader

Splunk-bridge bundle

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_HEC_TOKENHIGH(set in .env.example)hec-tokenSplunk-bridge HEC token.bundles/splunk_local_bridge/env/.env.example:12 — Bridge .env
DEFENSECLAW_HEC_URL(set in .env.example)any-hec-urlSplunk-bridge bundle: HEC endpoint URL.bundles/splunk_local_bridge/env/.env.example:11 — Bridge .env
DEFENSECLAW_INDEXdefenseclaw_localsplunk-index-nameSplunk-bridge target index.bundles/splunk_local_bridge/env/.env.example:13 — Bridge .env
DEFENSECLAW_INTEGRATION_ENABLEDfalsetrue, falseSplunk-bridge integration toggle.bundles/splunk_local_bridge/env/.env.example:16 — Bridge .env
DEFENSECLAW_O11Y_DASHBOARD_NAME_PREFIXempty (no prefix)string, unsetPrefix label applied to the Splunk Observability dashboard groups, dashboards, and detectors created by the Terraform setup command.cli/defenseclaw/commands/cmd_setup_splunk_o11y_dashboards.py:137 — --name-prefix Click option bound to this env var
DEFENSECLAW_REFunknownany-stringSplunk-bridge bundle git ref label.bundles/splunk_local_bridge/env/.env.example:17 — Bridge .env
DEFENSECLAW_SOURCEdefenseclawany-source-stringSplunk-bridge source label.bundles/splunk_local_bridge/env/.env.example:15 — Bridge .env
DEFENSECLAW_SOURCETYPEdefenseclaw:jsonsplunk-sourcetypeSplunk-bridge sourcetype.bundles/splunk_local_bridge/env/.env.example:14 — Bridge .env
DEFENSECLAW_SPLUNK_O11Y_DASHBOARDS_WORK_DIR<data_dir>/splunk_o11y_dashboards/terraformabsolute directory path, unsetTerraform working directory for Splunk Observability dashboard provisioning.cli/defenseclaw/commands/cmd_setup_splunk_o11y_dashboards.py:113 — --work-dir Click option bound to this env var
DEFENSECLAW_TERRAFORM_PLUGIN_DIRunset (no -plugin-dir passed to terraform init)absolute directory path, unsetOptional Terraform provider plugin directory for offline / cached provider installs when running 'defenseclaw setup splunk-o11y-dashboards'.cli/defenseclaw/commands/cmd_setup_splunk_o11y_dashboards.py:92 — --plugin-dir Click option bound to this env var

Test fixtures (test-only)

Env varImpactDefaultAccepted valuesPurposeSecurity concernConsumers
DEFENSECLAW_FAKE_CLAUDE_LISTunsetcomma-separated mock responses, unsetTest-only stub: comma-separated list of responses the fake claude CLI returns.internal/gateway/connector/codeguard_native_test.go:90 — Test stub
DEFENSECLAW_FAKE_CLAUDE_LOGunsetabsolute-path, unsetTest-only stub: path the fake claude CLI logs invocations to.internal/gateway/connector/codeguard_native_test.go:116 — Test stub
DEFENSECLAW_GATEWAY_URLunset (in-process e2e server)http(s) base URL e.g. http://127.0.0.1:18970, unsetBase URL of an external gateway for the security-suite e2e tier (TestSecuritySuiteE2E).internal/gateway/security_suite_test.go:307 — TestSecuritySuiteE2E reads this to locate the gateway; uses an in-process server when unset
DEFENSECLAW_TEST_KEYunsetany-string, unsetPlaceholder LLM key used in test fixtures only.cli/tests/test_llm_env.py — Test fixture
DEFENSECLAW_TEST_KEY_NOTSET_12345unsetunsetPlaceholder env var name used to assert 'unset' behavior in tests.cli/tests/test_llm_env.py — Test fixture for unset assertions
DEFENSECLAW_TEST_LLM_KEYunsetany-string, unsetPlaceholder LLM key used in some test setups when DEFENSECLAW_LLM_KEY needs an alternate target.cli/tests/test_llm_env.py — Test fixture

When in doubt

Run defenseclaw doctor. The doctor walks the same env-var resolution code paths as the running gateway and surfaces effective values plus any active opt-outs.

defenseclaw doctor
defenseclaw keys list

Reference