Hammerhead docs
What you need to judge Hammerhead before you talk to us: how it installs, a five-minute run, all 76 commands, the Python SDK, the REST API and CI. The output on this page is real, from hammerhead 0.1.0 on the labs that ship with it.
Hammerhead 0.1.0 · page updated September 2026
Access
Hammerhead is private. There is no public download, package, container or self-serve trial. We send binaries to teams we have given access. These docs are public so you can decide whether it is worth asking.
Install
Hammerhead is one executable, hammerhead. It needs no JVM, Python runtime, database or server. Each release archive also carries hammerhead-api, the optional REST server.
| Platform | Target | Live collection built in |
| Linux x86_64 (glibc 2.35+: Ubuntu 22.04+, Debian 12+) | x86_64-unknown-linux-gnu | SSH, SNMP, ICMP, gNMI state polling, REST connectors, cloud fetch |
| Linux arm64 (glibc 2.35+) | aarch64-unknown-linux-gnu | SNMP, REST connectors |
| macOS, Apple silicon | aarch64-apple-darwin | SSH, SNMP, ICMP, gNMI state polling, REST connectors, cloud fetch |
| macOS, Intel | x86_64-apple-darwin | SSH, SNMP, ICMP, gNMI state polling, REST connectors, cloud fetch |
| Windows x86_64 | x86_64-pc-windows-msvc (zip) | SNMP, REST connectors |
Analysis of a directory of config files works the same on every platform. The last column only matters if you want Hammerhead to fetch configs itself (see how configs get in). A linux/amd64 container image is also available to teams with access.
# after download: check, unpack, run
shasum -a 256 -c hammerhead-<version>-x86_64-unknown-linux-gnu.tar.gz.sha256
tar xzf hammerhead-<version>-x86_64-unknown-linux-gnu.tar.gz
./hammerhead --version
hammerhead 0.1.0
Signing. Each archive comes with a SHA-256 checksum file. The archives are not code-signed yet.
Quickstart
Five steps. The first four use a three-router OSPF lab that the binary can write for you; the fifth checks a change on a four-router spine-leaf.
1. Point it at a config directory
init scans a directory of configs (one file per device), says what it found and suggests next commands. --example seeds the lab first.
$ hammerhead init ./configs --example
✓ Seeded ./configs with R1/R2/R3 OSPF triangle (2196 bytes)
✓ Found 3 config files (3 cisco_ios)
✓ Discovered 3 devices, 9 interfaces, 3 L3 links
✓ Simulated 18 FIB entries across all devices
✓ Protocols: OSPF (area 0)
✓ Completed in 3ms
On your own configs, read the vendor counts init prints. A file it cannot identify is parsed as Cisco IOS, so a surprising count usually means a file it did not recognize.
2. Build the model
$ hammerhead simulate ./configs
== R1 ==
RIB: 6 entries (3 connected, 0 static, 3 ospf, 0 bgp, 0 eigrp, 0 isis)
FIB: 6 entries
OSPF: 2 adjacencies, 3 LSAs across area(s) 0
… R2 and R3 follow
3. Ask a reachability question
$ hammerhead reachability ./configs --from R1 --src 1.1.1.1 --dst 3.3.3.3
Reachable: yes
4. Trace the packet
$ hammerhead traceroute ./configs --from R1 --src 1.1.1.1 --dst 3.3.3.3
Traceroute from R1 (1.1.1.1) to 3.3.3.3 [tcp dst-port 80]
1 R1 - -> GigabitEthernet0/1 (R3 GigabitEthernet0/0) forwarded
Disposition: Delivered
5. Check a change before you push it
preflight compares a before and an after directory. Here the candidate moves LEAF-2 into OSPF area 2. Output trimmed.
$ hammerhead preflight ./before ./after
routes changed: 15 (20.0% of FIB entries)
devices impacted: 4 (100.0% of estate) — LEAF-1, LEAF-2, SPINE-1, SPINE-2
flows lost: 6 (of 4 of 4 endpoint(s) probed, 0 gained)
probed per pair: tcp/80 http, tcp/22 ssh, tcp/179 bgp, udp/53 dns, icmp echo
✗ LEAF-1(10.255.1.1) → LEAF-2(10.255.1.2)
…
VERDICT: FAIL
✗ blast radius 100.0% of devices exceeds --max-blast-radius 5%
✗ routing adjacencies: 2 lost between devices that are both still present — OSPF LEAF-2 <-> SPINE-1, OSPF LEAF-2 <-> SPINE-2
✗ reachability regression: 6 endpoint pair(s) delivered before are not delivered after
$ echo $?
2
A candidate that changes no routes and loses no flows returns VERDICT: PASS and exit 0. The exit code is the contract CI relies on:
| Exit | Verdict | Meaning |
0 | pass or advisory | No gate failed. Advisory findings are printed but do not fail. |
2 | fail | A gate failed. Each failure is listed with the flows, routes or rules behind it. |
3 | unknown | The change touches something the model does not cover. The blockers are named; it never reports a pass it cannot back. |
1 | error | An operational error, such as a missing directory. |
CLI reference
All 76 subcommands, grouped by job. Each summary is the command's own --help text, with internal references removed. hammerhead help <command> prints every flag.
Global options: --format text|json|csv|dot (JSON is stable for scripting; CSV suits tabular output such as fib, rib, reachability; DOT suits traceroute) and -v/-vv/-vvv for logging.
Start here2 commands
| Command | What it does, and usage |
init | Scan a config directory and show what Hammerhead found — vendors, devices, protocols, and suggested next commands. The fastest way to get started hammerhead init [OPTIONS] <CONFIG_DIR>
|
connect | Guided onboarding wizard: point Hammerhead at a system you already run (SolarWinds, ManageEngine, an Ansible repo — or a built-in demo), validate the connection, write a ready-to-use inventory.yaml + secrets env file, and optionally run the first collect + simulate immediately. Interactive on a TTY; fully drivable by flags (secret via HH_CONNECT_SECRET) in CIhammerhead connect [OPTIONS]
|
Parse & simulate14 commands
| Command | What it does, and usage |
parse | Parse all configs in a directory and report parse coverage hammerhead parse [OPTIONS] <CONFIG_DIR>
|
parse-coverage | Per-device parse coverage histogram (lines parsed vs unparsed) hammerhead parse-coverage [OPTIONS] <CONFIG_DIR>
|
topo | Discover topology from a config directory hammerhead topo [OPTIONS] <CONFIG_DIR>
|
simulate | Run the full simulation pipeline (parse → topo → OSPF → FIB) hammerhead simulate [OPTIONS] <CONFIG_DIR>
|
rib | Show the per-device RIB hammerhead rib [OPTIONS] --device <DEVICE> <CONFIG_DIR>
|
fib | Show the per-device FIB hammerhead fib [OPTIONS] --device <DEVICE> <CONFIG_DIR>
|
init-issues | Pybatfish-parity init report: severity-tagged init issues plus defined / referenced named structures hammerhead init-issues [OPTIONS] <CONFIG_DIR>
|
sessions | Report BGP / OSPF session compatibility and adjacency edges hammerhead sessions [OPTIONS] --protocol <PROTOCOL> <CONFIG_DIR>
|
snapshot | Emit static snapshot-input reports (ip-owners, subnets, FHRP, L1/L2 edges) or multipath consistency reports hammerhead snapshot [OPTIONS] --report <REPORT> <CONFIG_DIR>
|
ipsec-status | Report IPSec crypto-map session compatibility per Batfish ipsecSessionStatushammerhead ipsec-status [OPTIONS] <CONFIG_DIR>
|
vxlan-vnis | Emit VXLAN VNI properties per Batfish vxlanVniPropertieshammerhead vxlan-vnis [OPTIONS] <CONFIG_DIR>
|
vxlan-edges | Emit overlay VTEP→VTEP edges per Batfish vxlanEdgeshammerhead vxlan-edges [OPTIONS] <CONFIG_DIR>
|
profile | Per-phase wall-clock profile of the simulation pipeline hammerhead profile [OPTIONS] <CONFIG_DIR>
|
reconverge | Incrementally reconverge a snapshot after a single-file config edit. hammerhead reconverge [OPTIONS] <CONFIG_DIR>
|
Query19 commands
| Command | What it does, and usage |
traceroute | Trace a packet through the simulated network hammerhead traceroute [OPTIONS] --from <FROM> --src <SRC> --dst <DST> <CONFIG_DIR>
|
reachability | Yes/no reachability check between two IPs hammerhead reachability [OPTIONS] --from <FROM> --src <SRC> --dst <DST> [CONFIG_DIR]
|
loops | Scan the forwarding plane for packets that would circulate indefinitely. Also available under the alias detect-loops [aliases: detect-loops]hammerhead loops [OPTIONS] <CONFIG_DIR>
|
symbolic-reach | BDD-based symbolic reachability between two devices, with an optional differential mode against a second snapshot. CAVEAT: the BDD engine does not yet model NAT header rewrites — on estates with NAT rules, prefer nat-aware-traceroute for flows that cross a translating device; the command warns when it detects NAT in the snapshothammerhead symbolic-reach [OPTIONS] --from <FROM> --to <TO> <CONFIG_DIR>
|
bidirectional-reach | BDD-based bidirectional reachability (A→B ∩ B→A) hammerhead bidirectional-reach [OPTIONS] --from <FROM> --to <TO> <CONFIG_DIR>
|
bidirectional-trace | Forward + reverse traceroute with an asymmetry flag hammerhead bidirectional-trace [OPTIONS] --from <FROM> --src <SRC> --to <TO> --dst <DST> <CONFIG_DIR>
|
search-filters | Find every ACL line overlapping a symbolic packet constraint hammerhead search-filters [OPTIONS] <CONFIG_DIR>
|
test-filters | Evaluate every ACL against one concrete packet hammerhead test-filters [OPTIONS] --src <SRC> --dst <DST> <CONFIG_DIR>
|
nqe-routes | Ad-hoc route query with protocol / prefix / ECMP / device filters, optionally aggregated via --group-byhammerhead nqe-routes [OPTIONS] --config-dir <CONFIG_DIR>
|
nqe-devices | Ad-hoc device query with protocol / route-count filters, sortable by name / routes / links hammerhead nqe-devices [OPTIONS] --config-dir <CONFIG_DIR>
|
nqe-paths | Ad-hoc path-traversal query. Returns all (src, dst) pairs matching the filter with their hop-by-hop paths hammerhead nqe-paths [OPTIONS] --config-dir <CONFIG_DIR>
|
nql | Cypher-subset ad-hoc graph query over the simulated topology. Speaks a read-only subset of Cypher (MATCH / WHERE / RETURN with aggregation, ORDER BY, LIMIT, DISTINCT, variable-length paths) hammerhead nql [OPTIONS] <CONFIG_DIR> <QUERY>
|
search | Global free-text search across the simulated snapshot. One box resolves any IP, MAC, hostname, prefix, ACL line, VLAN, BGP / OSPF neighbour, NAT rule, VRF, EVPN VNI, MPLS label, or FIB next-hop into a ranked hit list hammerhead search [OPTIONS] --query <QUERY> <CONFIG_DIR>
|
mpls-trace | MPLS LFIB / LDP label-stack walker. Synthesises an LDP-DU distribution from loopback /32 prefixes and walks the label stack. RSVP-TE is a follow-up hammerhead mpls-trace [OPTIONS] --from <FROM> --to <TO> <CONFIG_DIR>
|
sr-trace | Segment Routing path / policy walker. Without --policy, dumps every device's prefix-SID label table. With --policy <headend>:<color>:<endpoint>, prints the policy's candidate paths and which one would be activehammerhead sr-trace [OPTIONS] <CONFIG_DIR>
|
all-paths | Enumerate every forwarding path from a source device to a destination IP, including every ECMP branch. hammerhead all-paths [OPTIONS] --from <FROM> --src <SRC> --dst <DST> [CONFIG_DIR]
|
ask | Ask a question in plain English, offline. The question is matched against a fixed grammar and resolved to ONE existing command, whose exact command line is printed before it runs in-process. A question that is not understood, is ambiguous, or names a device, interface or address that is not in the snapshot is REFUSED (exit 1) with the supported forms listed; it is never guessed at hammerhead ask [OPTIONS] <CONFIG_DIR> <QUESTION>
|
nat-aware-traceroute | Traceroute that follows NAT translations hop by hop. hammerhead nat-aware-traceroute [OPTIONS] --from <FROM> --src <SRC> --dst <DST> [CONFIG_DIR]
|
reachability-matrix | All-pairs reachability across the estate. Probes every ordered endpoint pair with a TCP/80 packet and renders the result as a matrix. Endpoints default to one address per device (loopback first); constrain them with --endpoints / --endpoints-filehammerhead reachability-matrix [OPTIONS] [CONFIG_DIR]
|
Change validation5 commands
| Command | What it does, and usage |
diff | Diff FIBs between two config directories hammerhead diff [OPTIONS] <BEFORE_DIR> <AFTER_DIR>
|
diff-routes | Per-(device, prefix) RIB delta between two snapshots hammerhead diff-routes [OPTIONS] <BEFORE_DIR> <AFTER_DIR>
|
diff-acls | ACL line-level delta between two snapshots hammerhead diff-acls [OPTIONS] <BEFORE_DIR> <AFTER_DIR>
|
failure-analysis | Simulate a device/interface failure (or scan every device) and report pre-convergence blast radius hammerhead failure-analysis [OPTIONS] --config-dir <CONFIG_DIR>
|
preflight | Pre-change blast-radius gate: diff a before/after config pair, score blast radius against thresholds (and optionally a policy file), and exit non-zero on gate failure so CI / Ansible pre_tasks can halt a rollout before it touches deviceshammerhead preflight [OPTIONS] <BEFORE_DIR> <AFTER_DIR>
|
Audit & compliance15 commands
| Command | What it does, and usage |
acl-audit | Find shadowed and unused ACL entries hammerhead acl-audit [OPTIONS] <CONFIG_DIR>
|
audit-config | Audit named-structure references: undefined refs, unused structures, parse warnings hammerhead audit-config [OPTIONS] <CONFIG_DIR>
|
policy-check | Verify a YAML policy file against the simulated network and report per-policy pass/fail with severity hammerhead policy-check [OPTIONS] --config-dir <CONFIG_DIR> --policies <POLICIES>
|
nqe-library | Run the bundled NQE library of intent checks (or list its catalog). hammerhead nqe-library [OPTIONS]
|
pbr-audit | Walk every interface bound to ip policy route-map ..., list the route-map clauses (match + set), and flag every clause whose set ip next-hop may bypass an inbound ACL bound on the same device.hammerhead pbr-audit [OPTIONS] <CONFIG_DIR>
|
wccp-audit | List WCCPv2 service groups and per-interface redirect bindings recovered from lines the parser did not model. hammerhead wccp-audit [OPTIONS] <CONFIG_DIR>
|
qos-audit | Surface Cisco MQC class-map / policy-map / service-policy declarations from lines the parser did not model. MVP scope: classification + marking only — scheduler, queue depth, and starvation analysis are not modeled hammerhead qos-audit [OPTIONS] <CONFIG_DIR>
|
ip-sla-audit | List per-device IP SLA probes (recovered from lines the parser did not model) and track <id> objects (parsed). Cross-references each track id against any static route that names it via track <id>hammerhead ip-sla-audit [OPTIONS] <CONFIG_DIR>
|
drift | Config-vs-golden semantic drift detector. Runs across a paired set of golden + observed config directories and emits one row per finding hammerhead drift [OPTIONS] --golden <GOLDEN> --observed <OBSERVED>
|
rpki-audit | Audit a network's ROAs against what it announces: a ROA whose maxLength authorises more-specifics the AS does not announce lets a forged-origin announcement validate Valid (RFC 9319). Exit 2 on a loose ROA, 3 when a ROA for this snapshot's ASes could not be judged or none was hammerhead rpki-audit [OPTIONS] --roas <FILE> <CONFIG_DIR>
|
fhrp-audit | HSRP / VRRP / GLBP standby-group consistency audit. Discovers every speaker, runs the FHRP election engine, and reports per-group active/standby roles plus structural warnings hammerhead fhrp-audit [OPTIONS] <CONFIG_DIR>
|
cve-audit | Join a NIST NVD JSON or Tenable .nessus XML vulnerability feed against the parsed device inventory and report every (CVE, device) pair that fires. Exits non-zero when any finding's severity meets --severity-floor (default medium)hammerhead cve-audit [OPTIONS] --feed <FEED> <CONFIG_DIR>
|
mlag-audit | Audit MLAG / vPC / CLAG configuration consistency across the snapshot. Surfaces five finding kinds (missing peer, keepalive subnet mismatch, member port mismatch, orphan member, peer-link missing). Exits non-zero when any finding ≥ --severity-floor (default high) fires, so the command is wirable as a CI gate ahead of a vPC / MLAG rollhammerhead mlag-audit [OPTIONS] <CONFIG_DIR>
|
convergence-audit | Pre-event correctness checks for fast-reroute, uRPF, and CoPP. hammerhead convergence-audit [OPTIONS] --config-dir <CONFIG_DIR>
|
exec-report | Produce a self-contained executive HTML exposure report — headline RAG verdict, SPOF chokepoints, segmentation exposure, compliance rollup, and a remediation appendix — from a single config directory hammerhead exec-report [OPTIONS] <CONFIG_DIR>
|
Segmentation4 commands
| Command | What it does, and usage |
segmentation-audit | Audit a YAML segmentation intent against the simulated network and classify each cross-zone flow as allowed, isolated, leaked, or missing connectivity hammerhead segmentation-audit [OPTIONS] --config-dir <CONFIG_DIR> --intent <INTENT>
|
segmentation-infer | Auto-derive a YAML segmentation intent from a set of observed 5-tuple flows plus the live topology. Output is the same YAML shape segmentation-audit consumes, so the observation → derive → audit loop closes in one hophammerhead segmentation-infer [OPTIONS] --flows <FLOWS> --config-dir <CONFIG_DIR>
|
segmentation-recommend | Generate vendor-neutral ACL rule recommendations from a segmentation audit (or zero-trust baseline from intent alone) hammerhead segmentation-recommend [OPTIONS] --config-dir <CONFIG_DIR> --intent <INTENT>
|
segments | Per-segment rollup: devices, policy violations, segmentation leaks, unparsed forwarding-relevant lines and a red / unknown / yellow / green status for each segment (intent zones, or derived zones) hammerhead segments [OPTIONS] <CONFIG_DIR>
|
Cloud & Kubernetes3 commands
| Command | What it does, and usage |
k8s-reach | Kubernetes pod-to-pod reachability verdict against the snapshot's NetworkPolicies (v1, Calico GlobalNetworkPolicy, Cilium CiliumNetworkPolicy) hammerhead k8s-reach [OPTIONS] --config-dir <CONFIG_DIR> --src-pod <SRC_POD> --dst-pod <DST_POD> --port <PORT>
|
cloud-fetch | Fetch a live cloud snapshot (AWS / K8s via their SDKs; Azure ARM and GCP Compute over REST, all or nothing) and write the JSON files that simulate already consumeshammerhead cloud-fetch [OPTIONS] --provider <PROVIDER> --output <OUTPUT>
|
cloud-cost | Annotate an AWS pseudo-topology path with per-GB egress-cost estimates at every billing boundary (internet egress, NAT GW, TGW, inter-AZ) plus a monthly projection. Rates are documented defaults, overridable via --pricing-filehammerhead cloud-cost [OPTIONS] --config-dir <CONFIG_DIR> --src <SRC> --dst <DST>
|
Collection & operations8 commands
| Command | What it does, and usage |
watch | Watch a config directory and emit a JSON-Lines event stream hammerhead watch [OPTIONS] [CONFIG_DIR]
|
collect | Collect running-configs from a YAML inventory of devices and write them into an on-disk snapshot directory that simulate can ingest. SSH (--features ssh) and SNMP (--features snmp) reach real devices; a build without them refuses those rows by name, and gNMI / NETCONF config collection is not implemented. An SSH row's vendor: picks its driver: nxos, eos, junos, fortios, panos and frr / cumulus (or their parser labels and Ansible ansible_network_os names) take their own transcript; ios, iosxr, asa, a10 or no vendor: get the generic show running-config; any other value is refused by namehammerhead collect [OPTIONS] --inventory <INVENTORY> --out <OUT>
|
endpoints | Endpoint attribution: merge ARP / CAM / LLDP JSON dumps and emit one (mac, ips, switch, port, vlan, is_lldp?) row per endpointhammerhead endpoints [OPTIONS] --arp <ARP> --cam <CAM>
|
snapshot-prune | Apply a YAML TTL policy to a snapshot store. --dry-run computes the same plan without mutating the storehammerhead snapshot-prune [OPTIONS] --root <ROOT> --ttl-policy <TTL_POLICY>
|
alerts | Operator surface for the alert lifecycle engine: list / show / ack / silence / resolve / watch (SSE) / history over the API (--api-url or HAMMERHEAD_API_URL, bearer via HAMMERHEAD_API_TOKEN). list --fail-on-firing exits 2 when any alert is firing — the CI contracthammerhead alerts [OPTIONS] <COMMAND>
|
monitor | Long-running scheduler daemon: fires cron jobs (collect / snapshot / policy / drift / observe / runbook) from a schedule YAML with a crash-safe journal, and POSTs job outcomes to the API's /ingest/observations when --api-url is set. --once evaluates a single tick; --dry-run prints the plan without executinghammerhead monitor [OPTIONS] --schedule <SCHEDULE>
|
observe | One operational-state poll cycle over the inventory (per-row observe: transports: TCP/ICMP/SNMP/gNMI/controller REST), emitting observation events locally (--format json is the ingest wire format) or pushing them via --push-urlhammerhead observe [OPTIONS] --inventory <INVENTORY>
|
remediate | Air-gapped manual remediation loop: emit-request builds a Config Studio request from an event, gate runs the strict preflight + gate-under-failure on a candidate (exit 2 on fail), verify checks drift-clean + alert-cleared (exit 2 when not verified)hammerhead remediate [OPTIONS] <COMMAND>
|
Integrations & automation6 commands
| Command | What it does, and usage |
mcp-serve | Serve the simulated network as a Model Context Protocol (MCP) endpoint over stdio so an AI agent (Claude, Cursor, …) can answer questions grounded in the digital twin hammerhead mcp-serve [OPTIONS] --config-dir <CONFIG_DIR>
|
hooks-validate | Validate a hooks YAML file: warns on missing endpoints, missing secret_ref where required, or bad regex in trigger conditions hammerhead hooks-validate [OPTIONS] --hooks <HOOKS>
|
hooks-plan | Compute the dispatch plan for a set of canned events without firing any HTTP/SMTP traffic. Useful for previewing what would be sent to ServiceNow / PagerDuty / Slack on a real failure hammerhead hooks-plan [OPTIONS] --hooks <HOOKS>
|
hooks-fire | Fire a dispatch plan against live endpoints. Defaults to dry-run unless the binary was built with --features hooks-live (HTTP) or --features hooks-live-smtp (SMTP) on hammerhead-clihammerhead hooks-fire [OPTIONS] --hooks <HOOKS>
|
runbook-run | Execute an event-driven runbook YAML. Walks the steps in order, shells out to hammerhead for each verb, captures stdout, substitutes $VAR references, and emits a single RunbookExecution record. MVP: sequential only, no parallel fan-out / no retries / no state persistencehammerhead runbook-run [OPTIONS] --runbook <RUNBOOK_PATH>
|
runbook-validate | Validate a runbook YAML — checks step kinds, duplicate names, and $VAR resolution. Exits non-zero on issues so the command is wirable as a CI gatehammerhead runbook-validate [OPTIONS] --runbook <RUNBOOK_PATH>
|
Python SDK
The hammerhead Python package (Python 3.9+, uses pandas) comes with access as a source distribution. It is not on PyPI.
pip install ./hammerhead-python
The SDK drives the hammerhead binary and reads its JSON output, so a notebook and the CLI always give the same answer. It finds the binary on your PATH, or you pass Hammerhead(binary="/path/to/hammerhead").
from hammerhead import Hammerhead
hh = Hammerhead().load_snapshot("configs/")
hh.reachability("R1", "1.1.1.1", "3.3.3.3") # True
hh.traceroute("R1", "1.1.1.1", "3.3.3.3") # TracerouteResult: Delivered, 1 hop
hh.routes(device="R1") # DataFrame: device, prefix, protocol, next_hop_ip, egress_interface
Methods: load_snapshot, simulate, routes, traceroute, reachability, diff, diff_routes, loops, failure_analysis, spof_scan, policy_check, nqe_routes, nqe_devices, nqe_paths, acl_audit.
Jupyter tutorials
Nine notebooks come with the SDK: Getting started · Pandas essentials for network analysis · Route analysis · BGP analysis · Traceroute and reachability · Change validation · Detecting configuration drift · ACL and firewall analysis · SDK cookbook.
REST API
hammerhead-api serves the same engine over HTTP. It binds to 127.0.0.1:8080 by default and will not start until you name the config directories it may read (HAMMERHEAD_API_ALLOWED_ROOTS). Request bodies are capped at 2 MB.
Authentication
Protected routes take a bearer JWT from your identity provider. Configure the issuer and audience (HAMMERHEAD_AUTH_JWT_ISSUER, HAMMERHEAD_AUTH_JWT_AUDIENCE) and exactly one key source: an HS256 secret, an RS256 public key file, or a JWKS URL. Tokens map to three roles, viewer < operator < admin. With no JWT settings, every protected route returns 401. There is no OIDC discovery and no native SAML or SCIM; use an identity bridge such as Keycloak or Auth0 for those.
Routes
56 routes. Analysis routes are rate-limited.
| Needs | Routes |
| viewer · analysis | POST /parse POST /topo POST /topo/l2 POST /device POST /endpoints POST /traceroute POST /traceroute/explain POST /reachability POST /rib POST /fib POST /loops POST /acl-audit POST /audits GET /segments |
| operator · analysis | POST /simulate POST /diff POST /preflight POST /search POST /snapshots/route-diff |
| viewer | POST /stream/ticket GET /estates GET /alerts GET /alerts/history GET /alerts/:fingerprint GET /observations GET /remediation/cases GET /remediation/cases/:id GET /snapshots GET /snapshots/:id GET /snapshots/:id/devices/:hostname GET /health |
| operator | POST /alerts/:fingerprint/ack POST /alerts/:fingerprint/silence POST /alerts/:fingerprint/resolve POST /ingest/alertmanager POST /ingest/observations POST /remediation/cases/:id/approve POST /remediation/cases/:id/verify POST /status POST /snapshots POST /snapshots/diff |
| admin | GET /audit GET /audit/verify POST /snapshots/prune |
| no token: UI and health | GET / GET /ui GET /ui/assets/:name GET /classic GET /health/live GET /health/ready GET /health/summary GET /status |
| stream ticket or token | GET /stream GET /stream-diff GET /alerts/stream |
| Config Studio service token | POST /remediation/cases/:id/candidate |
The UI routes serve the built-in operator console. The streaming routes check a single-use ticket (from POST /stream/ticket) or a bearer token themselves.
CI integration
Hammerhead gates a pipeline through exit codes, so it works in any CI that can run a binary. Keep the base branch's configs in one directory and the proposed ones in another, run preflight, and let a non-zero exit fail the job.
# any CI: fail the job unless the change passes
git worktree add ../base "$BASE_SHA"
hammerhead preflight ../base/configs ./configs --format json > preflight.json
# optional: your own rules, YAML; --strict exits 2 on a high or critical failure
hammerhead policy-check --config-dir ./configs --policies network-policy.yaml --strict
Teams with access also get:
- GitHub Action. A composite action that runs
preflight on a pull request and posts the verdict as a comment. Inputs include config-dir, base-config-dir, max-blast-radius (default 5%) and policy; outputs include gate-verdict, gate-exit-code, gate-blockers, changed-routes and lost-flow-count. It needs a token that can read the private release.
- GitLab CI template. Fails the pipeline unless the verdict is exactly
pass, and can post the result to a ServiceNow change record.
- Ansible. A role for
pre_tasks gating, and an Event-Driven Ansible source.
We have no Jenkins example yet; the plain-CLI pattern above works there.
Environment
| Variable | Used by | Purpose |
HAMMERHEAD_API_BIND | hammerhead-api | Listen address; default 127.0.0.1:8080 |
HAMMERHEAD_API_ALLOWED_ROOTS | hammerhead-api | Config directories the server may read; required |
HAMMERHEAD_AUTH_JWT_* | hammerhead-api | Issuer, audience and key source for bearer tokens |
HAMMERHEAD_AUDIT_DIR | hammerhead-api | Turns on the hash-chained audit trail (see Security) |
HAMMERHEAD_API_URL, HAMMERHEAD_API_TOKEN | CLI alerts, observe | Where the CLI reaches your API server, and its token |
HH_CONNECT_SECRET | CLI connect | Secret for the onboarding wizard when run non-interactively in CI |
Questions these docs don't answer: ask us, and we will add the answer here.