Engine flags & environment
Configuration live
The security-engine binary is configured by command-line flags. Every flag with
an env default reads that environment variable first, so you can drive it from
flags, environment, or both.
Command-line flags
| Flag | Default | Env | Controls |
|---|---|---|---|
-listen |
:8080 |
HS_LISTEN |
Listen address |
-origin |
127.0.0.1:9000 |
HS_ORIGIN |
Upstream origin |
-max-conns |
4096 |
— | Max concurrent connections |
-dial-timeout |
5s |
— | Origin dial timeout |
-origin-timeout |
30s |
— | Origin read inactivity timeout — a slow/hung origin that sends nothing for this long aborts the request (0 = off). Refreshed as bytes flow, so large legitimate responses are never cut off |
-head-timeout |
10s |
— | Request-head read timeout |
-body-inspect |
16384 |
— | Bytes of request body buffered for inspection before the decision. Without it, a body that arrives in a later TCP segment is invisible to every engine (0 = head-only) |
-body-timeout |
2s |
— | How long to wait for that window before deciding on what has arrived |
| — | — | — | gzip/deflate request bodies are inflated for inspection, bounded by the body window and a 64:1 ratio cap; the compressed bytes are what reach the origin |
-idle-timeout |
75s |
— | Client read inactivity timeout — an idle keep-alive connection, a stalled request body, or an idle HTTP/2 connection that sends nothing for this long is closed and its slot freed (0 = off; HAProxy timeout client stays the first line of defence) |
-inspect |
true |
— | Run the analysis pipeline on every request |
-enforce |
false |
— | Enforce decisions (off = monitor/shadow, never blocks) |
-capture-evidence |
true |
— | Capture a bounded attacker-payload snippet for flagged requests |
-scan-headers |
true |
— | Scan allowlisted header + cookie values |
-proxy-protocol |
false |
— | Read the HAProxy PROXY v2 header for the real client IP + TLS TLVs |
-http2 |
true |
— | Detect / serve HTTP/2 (h2c + ALPN) |
-plugins |
— | HS_PLUGINS |
Comma-separated out-of-process plugin executables |
-policy-file |
— | HS_POLICY_FILE |
Policy JSON to load and hot-reload |
-sites-file |
— | HS_SITES_FILE |
Multi-site routing JSON (overrides -origin / -policy-file) |
-telemetry-file |
— | HS_TELEMETRY_FILE |
Write anonymized telemetry JSONL (stdout or empty = off) |
-geoip |
— | HS_GEOIP_FILE |
GeoIP range file for country tagging (ISO-2 only) |
-real-ip-header |
— | HS_REAL_IP_HEADER |
Resolve real client IP from this header (trusted edge only) |
-challenge-difficulty |
0 |
— | PoW difficulty in leading zero bits; 0 = disabled (~18 ≈ 1s) |
-challenge-ttl |
30m |
— | How long a solved PoW pass is honored |
-throttle-delay |
0 |
— | Tarpit delay for the Throttle tier (0 = off) |
-stats-every |
0 |
— | Periodic stats logging interval (0 = off) |
Secrets (environment only)
Two keys are read from the environment and never exposed as flags:
| Variable | Purpose |
|---|---|
HS_TELEMETRY_KEY |
HMAC key used to pseudonymize client IPs in telemetry |
HS_POW_KEY |
HMAC key for signing proof-of-work challenge / pass tokens |
Set both in production
HS_TELEMETRY_KEY makes the client hash stable and unlinkable across restarts;
HS_POW_KEY makes challenge tokens unforgeable. Treat both as secrets.
A minimal run
security-engine \
-listen 0.0.0.0:8080 \
-origin 10.0.0.10:3000 \
-proxy-protocol \
-sites-file /etc/heimdall/sites.json \
-geoip /etc/heimdall/geoip.csv \
-telemetry-file /var/log/heimdall/events.jsonl \
-plugins /browser-plugin,/endpoint-plugin
# monitor mode: -enforce is off by default
Turn a site to enforce by setting enforce: true in its policy (see
Policy & sites) — you do not need to restart the engine.