Environment variables

Every environment variable the framework reads at runtime, harvested directly from lib/ and the example app. The canonical reader is b.safeEnv.readVar(name, schema) — it coerces the raw string into the declared type, applies the declared default when unset, and (for secrets) strips the value from process.env after the first read so a later process.env dump cannot leak it.

Total variables harvested: 49 across 3 categories. Generated 2026-08-08T16:39:15.550Z.

Core framework (BLAMEJS_*) #

Operator knobs read by the framework's lib/ modules during boot and on first use. All optional unless marked required in the schema column.

NameTypeDefaultEffectWhere read
BLAMEJS_BOOT_LOG_LEVELstringallow:raw-process-env-bootstrap — see header comment abovelib/log.js:595
BLAMEJS_DEPRECATIONSstring(no prose; consult source)lib/deprecate.js:69
BLAMEJS_DNS_TRANSPORTstring(no prose; consult source)lib/network-dns.js:174
BLAMEJS_NTP_DRIFT_FATAL_MSstring""schema: { default: "" }lib/db.js:2881
BLAMEJS_NTP_DRIFT_WARN_MSstring""schema: { default: "" }lib/db.js:2880
BLAMEJS_NTP_SERVERSstring""schema: { default: "" }lib/db.js:2878
BLAMEJS_NTP_STRICTstring"1"schema: { default: "1" }lib/db.js:2923
lib/security-assert.js:152
BLAMEJS_NTP_TIMEOUT_MSstring""schema: { default: "" }lib/db.js:2879
BLAMEJS_SKIP_NTP_CHECKstring""schema: { default: "" }lib/db.js:2870
BLAMEJS_TMPDIRstring(no prose; consult source)lib/db.js:722
BLAMEJS_VALIDATE_RESPONSESstringResponse validation (dev/opt-in via env or per-route opt).lib/router.js:191
lib/router.js:587
BLAMEJS_VENDOR_DATA_DEFER_BOOT_VERIFYstring""Eager verification at module-load. The first time anything require()s b.vendorData (e.g. lib/public-suffix.js, lib/auth/ password.js, lib/mail-bimi.js — all of which load early in any framework consumer's import graph), every registered vendor data file is dual-hash + signature + canary-verified before any caller gets the chance to call get(). Tamper = fail-fast at boot, not at first-request-touches-PSL surprise. Operators wanting to defer verification (test rigs that mock require() resolution, install-pipeline contexts that intentionally run before the trust roots are populated) must opt in via TWO env vars: BLAMEJS_VENDOR_DATA_DEFER_BOOT_VERIFY=1 PLUS a non-empty BLAMEJS_VENDOR_DATA_DEFER_BOOT_VERIFY_REASON explaining WHY. Setting the flag alone is refused so a misconfigured CI / Docker image can't silently bypass tamper detection. SSDF PW.4 — every security-default-disable lives in the audit log with an operator- attributed reason.lib/vendor-data.js:487
BLAMEJS_VENDOR_DATA_DEFER_BOOT_VERIFY_REASONstring""schema: { default: "" }lib/vendor-data.js:489
BLAMEJS_VENDOR_DATA_PUBKEY_FINGERPRINTstring""schema: { default: "" }lib/vendor-data.js:253
LOG_LEVELstringallow:raw-process-env-bootstrap — see header comment abovelib/log.js:595
NODE_ENVstringdev.create() is intended for development-mode use only — restarting subprocesses on file change is a feature operators run on their laptop, never in production. Refusing here means a mis-configured production deployment that accidentally wires the dev primitive crashes loudly at boot rather than spawning shells on every save. Operators with a legitimate cross-cutting need (e.g. a CI runner that uses dev() to drive end-to-end tests) explicitly opt in via opts.allowProduction with an audited reason.lib/deprecate.js:74
lib/dev.js:190
lib/error-page.js:292
lib/security-assert.js:277
NOTIFY_SOCKETstring(no prose; consult source)lib/sd-notify.js:61
PATHstring""Windows env vars are case-insensitive; Node populates both PATH and Path. safeEnv.readVar gates each by name with the standard size cap.lib/keychain.js:121
TZstring(no prose; consult source)lib/compliance.js:448

Security & secrets #

Passphrases and signing-mode selectors. The framework reads these once at vault / audit init and then strips them from process.env. Set them via the operator's secret manager — never bake into a Dockerfile or shell history.

NameTypeDefaultEffectWhere read
BLAMEJS_AUDIT_SIGNING_MODEstring"wrapped"schema: { default: "wrapped", enum: ["wrapped", "plaintext"], }lib/db.js:1585
BLAMEJS_AUDIT_SIGNING_PASSPHRASEstring(no prose; consult source)examples/wiki/lib/build-app.js:357
BLAMEJS_KEYCHAIN_PASSPHRASEstring(no prose; consult source)lib/keychain.js:618
lib/keychain.js:700
lib/keychain.js:796
BLAMEJS_VAULT_PASSPHRASEstring---- Posture auto-detect ---- The wiki ships in plaintext defaults so a quick local boot just works. When the operator sets BLAMEJS_VAULT_PASSPHRASE in the env, the wiki takes that as the production-posture signal and flips to wrapped vault + encrypted DB at rest. Same for BLAMEJS_AUDIT_SIGNING_PASSPHRASE → wrapped audit-sign key. WIKI_VAULT_MODE / WIKI_DB_AT_REST / WIKI_AUDIT_SIGNING_MODE override the auto-detect explicitly.examples/wiki/lib/build-app.js:356

Wiki example app (WIKI_*) #

Knobs read only by examples/wiki — the operator's downstream app reads its own equivalents and these will not appear in framework deployments.

NameTypeDefaultEffectWhere read
WIKI_ADMIN_ALLOWED_CIDRSstringNetwork allowlist for /admin paths — when WIKI_ADMIN_ALLOWED_CIDRS is set (comma-separated CIDR list), the wiki mounts b.middleware.networkAllowlist as the in-process CIDR fence above the application-layer auth gate. Operators behind a reverse proxy typically configure this at the proxy / NACL layer instead and leave the env var unset; this is the in-process fallback.examples/wiki/lib/build-app.js:253
WIKI_ADMIN_DENIED_CIDRSstringOptional deny-list for the same paths — "10.0.0.0/8 except 10.0.99.0/24" patterns. Comma-separated CIDR list; empty = no deny rules.examples/wiki/lib/build-app.js:258
WIKI_ADMIN_EMAILstring(no prose; consult source)examples/wiki/server.js:66
WIKI_ADMIN_PASSWORDstring(no prose; consult source)examples/wiki/server.js:67
WIKI_ADMIN_TRUSTED_PROXIESstringReverse-proxy CIDRs for the deployment. X-Forwarded-For / -Proto are honored only when the request's immediate peer is one of these (peer-gating) — without it the framework uses the socket address / real TLS state and ignores the forgeable headers, so a direct caller can't spoof an allowed IP or claim https. Drives both the /admin CIDR gate and the admin Secure-cookie HTTPS detection.examples/wiki/lib/build-app.js:266
WIKI_AUDIT_SIGNING_MODEstring(no prose; consult source)examples/wiki/lib/build-app.js:362
WIKI_BINDstringDefault bind: 0.0.0.0 so a containerized wiki accepts connections from the Docker port-forward and reverse proxies on the same host network. Operators with a stricter posture (e.g. listening only on localhost behind a same-host reverse proxy) set WIKI_BIND=127.0.0.1.examples/wiki/server.js:65
WIKI_DATA_DIRstring(no prose; consult source)examples/wiki/server.js:58
WIKI_DB_AT_RESTstring(no prose; consult source)examples/wiki/lib/build-app.js:360
WIKI_INTEGRATION_MTLS_DIRstring(no prose; consult source)examples/wiki/lib/build-app.js:336
WIKI_INTEGRATION_S3_ACCESS_KEYstring(no prose; consult source)examples/wiki/lib/build-app.js:327
WIKI_INTEGRATION_S3_BUCKETstring(no prose; consult source)examples/wiki/lib/build-app.js:326
WIKI_INTEGRATION_S3_ENDPOINTstring(no prose; consult source)examples/wiki/lib/build-app.js:319
WIKI_INTEGRATION_S3_REGIONstring(no prose; consult source)examples/wiki/lib/build-app.js:325
WIKI_INTEGRATION_S3_SECRET_KEYstring(no prose; consult source)examples/wiki/lib/build-app.js:328
WIKI_INTEGRATION_SMTP_EHLOstring(no prose; consult source)examples/wiki/lib/build-app.js:314
WIKI_INTEGRATION_SMTP_HOSTstring(no prose; consult source)examples/wiki/lib/build-app.js:309
WIKI_INTEGRATION_SMTP_PORTnumber1025schema: { type: "number", default: 1025 }examples/wiki/lib/build-app.js:313
WIKI_INTEGRATION_SMTP_REJECT_UNAUTHORIZEDstring(no prose; consult source)examples/wiki/lib/build-app.js:316
WIKI_INTEGRATION_TESTbooleanfalseIntegration-test mode — mount /test/* routes and wire test-only primitives (alt cache, mail transport, object-store backend) when WIKI_INTEGRATION_TEST=1. Production deploys MUST NOT set this var; the routes are guarded by the mount-gate below and otherwise unreachable.examples/wiki/lib/build-app.js:299
WIKI_PORTnumberschema: { type: "number", default: b.constants.BYTES.bytes(3008) }examples/wiki/server.js:59
WIKI_REQUIRE_PROD_ASSERTSbooleanfalseBoot-time security policy assertions. WIKI_REQUIRE_PROD_ASSERTS=1 makes the wiki refuse to boot when the operator's production posture is incomplete (vault not wrapped, db not encrypted, etc.). Default off so a developer's `npm start` doesn't have to set every production knob; production deploys flip this on in the .env.examples/wiki/lib/build-app.js:347
WIKI_SITE_URLstring(no prose; consult source)examples/wiki/server.js:60
WIKI_VAULT_MODEstring(no prose; consult source)examples/wiki/lib/build-app.js:358
WIKI_WEBHOOK_SECRETstring(no prose; consult source)examples/wiki/server.js:69
WIKI_WEBHOOK_URLstring(no prose; consult source)examples/wiki/server.js:68
Computed names

Variables read via a computed key — process.env[someVar] or safeEnv.readVar(prefix + suffix) — are intentionally not harvested. The catalog only records statically-resolvable names. Operators relying on runtime-computed env keys should document them in their own deploy manifest.

Last updated 2026-08-08T16:39:49.652Z by seeder.