Audit & monitoring
A tamper-evident record of every decision, with metrics and detections on top.
Where to run this
Every command on this page runs from a clone of the AgentBox repository on the trusted host — never inside the agent workspace. If you haven't cloned it yet, start with the quickstart.
The audit log
Events append to .agentgate/audit.jsonl with runtime identity, request ID, repository, decision, ref updates, and upstream status. Credentials and request headers are never written. If an audit write fails, the request is not forwarded.
Each record is hash-chained with seq, prevHash, and hash:
npm run audit:verify
# OK 4182 records head 4182:4f2d…Verification replays rotated files and the live log, detecting edits, deletions, and reordering. The broker refuses to start if its own tail fails the check.
Logs rotate at AGENTGATE_AUDIT_MAX_MIB (default 64) and keep AGENTGATE_AUDIT_MAX_FILES (default 20).
Forward off-host
A chain proves internal consistency; it can't stop a host that rewrites the whole log. Ship records off-host:
npm run audit:forward- Set
AGENTGATE_AUDIT_SINK_URL(https://) andAGENTGATE_AUDIT_SINK_TOKEN_PATH. - Delivery is at-least-once; dedupe on each record's
hash. Write into WORM/object-lock storage. CHAIN_BROKENmeans local tampering or corruption.AUDIT_GAPmeans records rotated out before shipping. Both are security events; the forwarder keeps retrying.- The Compose forwarder mounts broker state read-only.
Prometheus metrics
Set AGENTGATE_METRICS_PORT to expose /metrics on a separate, unauthenticated listener that never needs the workspace token. Compose pins it to the monitoring network.
| Metric | Meaning |
|---|---|
agentgate_requests_total{route,status} | HTTP traffic |
agentgate_request_duration_seconds{route} | Latency |
agentgate_decisions_total{action,decision} | Policy decisions |
agentgate_upstream_failures_total{action} | GitHub rejected an approved request |
agentgate_approvals_pending | Awaiting review |
agentgate_active_requests | In flight vs AGENTGATE_MAX_CONCURRENT |
agentgate_audit_head_seq | Latest chain sequence |
agentgate_audit_forward_lag_records | Unshipped records (-1 = unknown) |
agentgate_errors_total{code} | Error responses by code |
All labels are bounded enums — never repository or ref names. examples/prometheus-alerts.yml has ready-made alerts.
SIEM detections
scripts/detect.js is a reference implementation of seven stable-ID detections to mirror in Splunk, Sentinel, or Elastic:
| ID | Detection | Indicates |
|---|---|---|
| D1 | denial-burst | Probing the policy surface until something is allowed |
| D2 | content-blocked | A secret leak or committed exfiltration attempt |
| D3 | egress-probing | Scanning for a path off the allowlist |
| D4 | approval-rejections | Repeated requests reviewers keep denying |
| D5 | off-hours-protected-push | Allowed push to a protected branch outside hours |
| D6 | assertion-failures | Expired, forged, or revoked assertions |
| D7 | model-volume | Bulk data sent to a model API |
Windowed detections alert once per burst and re-arm after the window drains.
Logging
Structured JSON lines with time, level, and msg. Any key matching token, authorization, secret, password, private, cookie, or signature is replaced with [REDACTED], recursively. AGENTGATE_LOG_LEVEL controls verbosity.