Skip to content
BHIM KVH / Developers / v0.4.0

API documentation

The supported integration surface: CLI commands, JSONL exports, health status, event fields, and the local privileged-helper boundary.

Verified against the local 0.4.0 source. Examples target Linux with systemd; inspect your installed version with --help.

CLI and JSON, not a REST API

Agent operations use the local CLI and JSONL/CSV exports. The licensed 0.4.1 release adds an HTTPS licensing API for activation and renewal only; there is no public HTTP API for incidents, remote shell execution, or a monitoring dashboard.

Operational commands require a valid signed local lease. Licensing commands, config-show, blocks, and emergency unblocking remain available when protection is inactive.

bhim-protection --help
bhim-protection --config /etc/bhim-protection/config.toml health --help

Licensing API endpoints

The compiled agent signs activation and renewal requests using its private device key. Use the shipped license CLI rather than embedding private device keys into a browser.

License command reference

License commands run before configuration loading. Activation and renewal require root; check and status can validate the locally readable signed lease. A missing or expired license returns nonzero.

sudo bhimkvh license activate
sudo bhimkvh license status
sudo bhimkvh license check
sudo bhimkvh license renew
sudo bhimkvh license fingerprint

Complete command reference

CommandArguments / optionsPurpose
--help / --versionGlobal flagsShow usage/version without daemon execution.
runNo command-specific flagsStart the Linux daemon; normally systemd-managed.
response-serveNo command-specific flagsPrivileged local helper; managed by systemd.
health--strictJSON health; strict fails on degraded checks.
metricsNoneJSONL name/value counters plus spool depth.
incidents--limit N (default 100)JSONL incident summaries, newest last_seen first.
timelineINCIDENT_IDEvent JSONL for the incident, chronological.
export--format json|csv; --limit N (default 100)Newest events first; JSON output is newline-delimited.
config-showNoneParse/validate then print the TOML file.
config-setKEY VALUEChange an allowlisted scalar, validate, write atomically.
baseline--replaceCapture trusted integrity hashes; replace explicitly resets existing entries.
verifyNonePrint integrity findings as event JSONL.
blocksNoneList recorded block state.
blockIP --scope ssh|http --reason TEXTRequest a scoped block; scope defaults ssh, reason defaults operator.
unblockIP --scope ssh|httpRemove a reviewed scope; scope defaults ssh.
snapshotABSOLUTE_PATHCapture an explicit recovery snapshot.
snapshot-showIDPrint snapshot manifest JSON.
restoreID --expected-current-sha256 HASH|absentRestore only against reviewed current state.
quarantineABSOLUTE_PATH --expected-sha256 HASHIsolate a reviewed non-critical file.
graphPROCESS_KEYQuery observed process provenance.
evidence-verifyNoneVerify the local retained-payload evidence chain.
update--version VERSION; --yesDisabled; use the signed binary installer.

Health output and exit status

Successful health checks print one JSON object. A degraded report may still exit successfully without --strict. With --strict, degraded checks return a nonzero status after the JSON report. Other parse, permission, configuration, or storage failures can also return nonzero; do not assume every error includes health JSON.

sudo -u bhim bhim-protection health --strict

Example health response

Illustrative healthy output; the heartbeat timestamp changes on your host.

{
  "status": "healthy",
  "database": "ok",
  "reasons": [],
  "heartbeat": "2026-11-14T10:30:00+00:00"
}

JSONL and CSV exports

The json export format produces one event object per line, not a JSON array. Use a JSONL consumer or jq -s to gather an array. CSV includes event_id, incident_id, timestamp, event_type, severity, source, and description; it omits nested evidence.

sudo -u bhim bhim-protection export --format json --limit 100 > events.jsonl
sudo -u bhim bhim-protection export --format csv --limit 100 > events.csv

# jq is an optional integration dependency, not part of BHIM.
jq -s . events.jsonl > events.json
jq -c 'select(.severity == "high" or .severity == "critical")' events.jsonl

Event schema

FieldTypeMeaning
event_idstringevt_ followed by UUID for generated events.
incident_idstring | nullCorrelation ID when assigned.
timestampRFC3339 UTC stringEvent timestamp.
event_typestringDetector or operation-specific event name.
severitystringFor example info, medium, high, critical.
sourcestringCollector or operator source.
confidencestringObserved evidence classification.
descriptionstringHuman-readable finding.
evidenceJSON valueEvent-specific fields; not a fixed universal object schema.

Example event

This sample illustrates the event shape. A recorded observation is not proof that the system was compromised.

{
  "event_id": "evt_example",
  "incident_id": null,
  "timestamp": "2026-11-14T10:30:00Z",
  "event_type": "network_new_listener",
  "severity": "medium",
  "source": "proc_net_poll",
  "confidence": "observed",
  "description": "New socket observed",
  "evidence": {
    "state_hex": "0A",
    "limitation": "Polling may miss transient sockets"
  }
}

Metrics, incidents, and timelines

Metrics output is JSONL with name/value fields. It includes spool_pending_batches and spool_pending_bytes alongside stored counters. Incidents are JSONL with incident_id, opened_at, last_seen, event_count, and correlation_key. Use a returned incident_id with timeline.

sudo -u bhim bhim-protection metrics
sudo -u bhim bhim-protection incidents --limit 20
sudo -u bhim bhim-protection timeline INCIDENT_ID
sudo -u bhim bhim-protection graph BOOT_ID:PID:START_NS

Example local automation

This Python example consumes a local JSONL export without depending on a network API. Run it as a user authorised to read the BHIM state and configuration.

import json
import subprocess

result = subprocess.run(
    ["bhim-protection", "export", "--format", "json", "--limit", "100"],
    check=True, capture_output=True, text=True, timeout=30,
)
for line in result.stdout.splitlines():
    if line.strip():
        event = json.loads(line)
        print(event["event_type"], event["severity"])

Local helper authentication

The split executor listens on a Unix-domain socket, validates Linux peer UID/GID, and reads root-owned protected configuration. It accepts constrained firewall operations and digests for configured critical files. It has no general shell-command or file-content endpoint. Use the supported CLI rather than depending on an internal wire protocol.

Updater behaviour

The unsigned legacy updater is disabled in licensed 0.4.1. Use the Ed25519-verified installer to obtain an updated binary-only archive.

Next guideConfiguration reference
Need help with your environment? Contact BHIM ↗