Installing Community Edition
Installation live
Community Edition is free software (EUPL-1.2) and ships as OCI images from
Tenforward's public registry — no account, no token, no rate-limited hub. Every
tagged release publishes heimdall-engine, heimdall-api, heimdall-ingest
and heimdall-geoip as both the version tag and latest.
| Image | Contents |
|---|---|
zot.solutrix.io/heimdall-shield/heimdall-engine |
The security engine (scratch image, one static binary) |
zot.solutrix.io/heimdall-shield/heimdall-api |
Control plane + Attack Explorer GUI (+ feed tools) |
zot.solutrix.io/heimdall-shield/heimdall-ingest |
Telemetry ingester (JSONL → ClickHouse data lake) |
zot.solutrix.io/heimdall-shield/heimdall-geoip |
IP-to-country range file (db-ip.com Lite, CC-BY-4.0) |
Pin versions in production
latest always tracks the newest release. For reproducible deploys, pin the
version tag (e.g. v0.1.6) — list available tags with:
Kubernetes (Helm)
The chart in deploy/helm/heimdall-shield runs the full edge stack — HAProxy
(TLS + PROXY v2) → engine → control plane — as one Pod with shared volumes, so
live policy reload and the live Attack Explorer work exactly like the
single-host layout.
1. Get the chart
2. TLS certificate
HAProxy terminates TLS from a Secret of PEM bundles (cert + key concatenated).
Self-signed is fine to start — with controlPlane.persistence on (the default),
the GUI takes over certificate management (upload + ACME + auto-renew) after
first boot:
kubectl create namespace heimdall
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
-keyout /tmp/hs.key -out /tmp/hs.crt -days 30 -subj "/CN=example.com"
cat /tmp/hs.crt /tmp/hs.key > /tmp/hs.pem
kubectl -n heimdall create secret generic heimdall-tls --from-file=site.pem=/tmp/hs.pem
3. Point it at your origin
Copy deploy/helm/heimdall-shield/examples/values-ce.yaml and set the origin
your edge protects in config.sitesJson (default_origin, or a full
sites list for multi-site routing — see
Policy & sites).
4. Install
helm install hs deploy/helm/heimdall-shield -n heimdall \
-f deploy/helm/heimdall-shield/examples/values-ce.yaml
kubectl -n heimdall rollout status deploy/hs-heimdall-shield-edge
The chart defaults pull from the public registry — no imagePullSecrets
needed. The post-install notes print the edge address, the GUI port-forward and
where to find the auto-generated admin password:
kubectl -n heimdall port-forward svc/hs-heimdall-shield-controlplane 8082:8082
kubectl -n heimdall get secret hs-heimdall-shield-secrets \
-o jsonpath='{.data.HS_ADMIN_PASSWORD}' | base64 -d; echo
Open http://localhost:8082 — the Attack Explorer starts populating as soon as traffic flows.
The client source IP is load-bearing
Heimdall's whole model is client identity. Make sure the real client IP
survives to HAProxy: hostNetwork: true, hostPort, or an L4/TCP-passthrough
LoadBalancer with externalTrafficPolicy: Local. A SNAT-ed edge sees every
client as the same address.
Monitor-first by default
edge.enforce defaults to false: every request is inspected and scored,
shadow decisions are recorded, nothing is blocked. Validate the
false-positive rate on real traffic in the Explorer before flipping
enforce: true.
Upgrading
Policy is GitOps-seeded from config.sitesJson — live GUI edits apply
immediately but reset on Pod restart, so commit durable policy to your values
file. Users, certificates and GUI settings live on the control-plane PVC and
survive upgrades.
Single host (podman / docker)
The same images run outside Kubernetes — the engine is one static binary in a scratch image:
podman run -d --name hs-engine -p 8080:8080 \
zot.solutrix.io/heimdall-shield/heimdall-engine:latest \
-listen=:8080 -origin=YOUR-ORIGIN:PORT -enforce=false
podman run -d --name hs-api -p 8082:8082 \
zot.solutrix.io/heimdall-shield/heimdall-api:latest \
-listen=:8082
See Engine flags & environment for the full flag
reference, and put HAProxy (transport only — TLS + PROXY v2) in front for
production; dataplane/haproxy/ in the repository has the edge configs.