CiscoCiscoDefenseClaw
Reference

Gateway API

defenseclaw-gateway HTTP surface — every route registered in internal/gateway/api.go, the auth + CSRF model, and the verdict shape that inspect/scan endpoints return. Authoritative source is api.go itself.

defenseclaw-gateway exposes an HTTP surface used by hook scripts, the OpenClaw plugin, the CLI, and the TUI. This page lists every route the gateway actually registers, grouped by purpose.

This is not an OpenAPI spec — request/response shapes evolve and the canonical source is the handler code. For exact field names, point at the handler in internal/gateway/api.go (which mux.HandleFunc references the implementing file).

Last audited: every entry on this page was verified against mux.HandleFunc calls in internal/gateway/api.go:Run() (lines 304-393). If you add or rename a route in code, update this page in the same PR — make docs-check will fail otherwise.

Bind address

KnobDefaultWhere set
gateway.api_port18970~/.defenseclaw/config.yaml
gateway.api_bind127.0.0.1~/.defenseclaw/config.yaml (override only when running the sandbox/lan profile)
gateway.port (proxy)18789Separate from the API server — the proxy port the LiteLLM/Bifrost upstream listens on

The gateway binds to localhost by default. To expose the API to the LAN (sandbox/multi-host setups), set gateway.api_bind: "0.0.0.0" in ~/.defenseclaw/config.yaml. defenseclaw setup does this for you when it provisions the sandbox profile.

Auth

Every request — except GET /health — must carry the gateway token. Two header forms are accepted (constant-time compared in tokenAuth):

X-DefenseClaw-Token: <token>
Authorization:        Bearer <token>

The token is resolved from one of, in priority order:

  1. The env var named by gateway.token_env (custom name — operator intent wins)
  2. DEFENSECLAW_GATEWAY_TOKEN (canonical)
  3. OPENCLAW_GATEWAY_TOKEN (legacy fallback for existing installs)
  4. gateway.token directly in ~/.defenseclaw/config.yaml

There is no standalone token file (~/.defenseclaw/gateway-token is sometimes mentioned in older docs but the gateway never reads it). Use defenseclaw keys set DEFENSECLAW_GATEWAY_TOKEN to set the canonical env var; it lands in ~/.defenseclaw/.env.

CSRF protection

Every state-changing request also requires X-DefenseClaw-Client (any non-empty value identifying the caller — cli, openclaw-plugin, inspect-hook/1.0, etc.). The middleware rejects same-origin browser requests that lack it with 403. See apiCSRFProtect in api.go.

X-DefenseClaw-Client: cli

Endpoints

Health & status

MethodPathAuthPurpose
GET/healthexemptLiveness + uptime + version. Used by k8s probes and defenseclaw doctor.
GET/statusrequiredActive connector + enforcement flags + connector_mode + provenance. Used by defenseclaw status and the TUI.
GET/v1/connectorsrequiredLists every connector registered in the gateway (name, description, source, hook capabilities, tool inspection mode).

Connector hooks

Each connector registers exactly one hook endpoint. The path is owned by the connector, declared in its HookAPIPath() method, and registered dynamically in registerConnectorHookRoutes.

MethodPathConnectorSource
POST/api/v1/claude-code/hookClaude Codeinternal/gateway/connector/claudecode.go
POST/api/v1/codex/hookCodexinternal/gateway/connector/codex.go
POST/api/v1/cursor/hookCursorinternal/gateway/connector/hook_only.go
POST/api/v1/windsurf/hookWindsurfsame
POST/api/v1/geminicli/hookGemini CLIsame
POST/api/v1/copilot/hookGitHub Copilot CLIsame
POST/api/v1/hermes/hookHermessame

All hook endpoints share a per-IP rate limiter (20 RPS, burst 40 — see hookLimiter in api.go). Loopback callers (the on-host hook scripts) are exempt; the limit only applies to remote callers.

Inspection (rate-limited)

The /api/v1/inspect/* family is the hot path that connector hooks and the OpenClaw plugin call to score a single tool call, prompt, or completion. Mounted under a sub-mux that wraps the per-IP rate limiter.

MethodPathUsed byPurpose
POST/api/v1/inspect/toolHook scripts, OpenClaw pluginInspect a tool call (name + args). Returns the verdict envelope below.
POST/api/v1/inspect/requestHook scripts, pluginInspect an outbound LLM request (prompt).
POST/api/v1/inspect/responseHook scripts, pluginInspect a model response.
POST/api/v1/inspect/tool-responseHook scripts, pluginInspect a tool's output before it returns to the agent.

Code & network scanning

MethodPathPurpose
POST/api/v1/scan/codeCodeGuard scan of a code blob — used by the codeguard skill and the IDE plugin to lint with the rule pack's code-scanning rules.
POST/api/v1/network-egressEgress decision for an outbound HTTP/DNS lookup (used by the OpenShell sandbox profile).

Asset scanning

MethodPathPurpose
POST/v1/skill/scanRun the skill scanner against a fetched skill bundle.
POST/v1/plugin/scanRun the plugin scanner against a plugin manifest + sources.
POST/v1/mcp/scanRun the MCP scanner against an MCP server's mcpServers.json.
POST/v1/skill/fetchFetch a skill from a registry source so it can be scanned before install.

Asset enable / disable

MethodPathPurpose
POST/skill/disableQuarantine a skill by key.
POST/skill/enableRe-enable a previously disabled / quarantined skill.
POST/plugin/disableQuarantine a plugin by name.
POST/plugin/enableRe-enable a plugin.

Inventory

MethodPathPurpose
GET/skillsList discovered skills with admission state.
GET/mcpsList discovered MCP servers with admission state.
GET/tools/catalogAggregate tool catalogue across the active connector.

Policy

MethodPathPurpose
POST/policy/evaluateEvaluate the OPA admission policy against an arbitrary input. Used internally by the scanners and exposed for debugging.
POST/policy/evaluate/firewallEvaluate the firewall sub-policy in isolation.
POST/policy/evaluate/auditEvaluate the audit sub-policy.
POST/policy/evaluate/skill-actionsEvaluate the skill_actions sub-policy by severity.
POST/policy/reloadReload the OPA policy bundle (policies/<name>.yaml + policies/rego/) without restarting the gateway. Returns 200 + the active policy name.

Guardrail control plane

MethodPathPurpose
POST/v1/guardrail/eventSubmit a guardrail event (used by the LiteLLM bridge for upstream-triggered events).
POST/v1/guardrail/evaluateEvaluate the guardrail rule pack against arbitrary content.
GET/v1/guardrail/configReturn the active guardrail config the gateway resolved at boot — handy for verifying setup guardrail actually wrote what you thought.

Enforcement logging

These endpoints are write-only "I just blocked / allowed something" telemetry endpoints used by the OpenClaw plugin to keep the gateway's audit DB authoritative when the plugin makes the decision out-of-band.

MethodPathPurpose
POST/enforce/blockLog an enforcement-time block.
POST/enforce/allowLog an enforcement-time allow.
POST/enforce/blockedList recent enforcement-time blocks.
POST/enforce/allowedList recent enforcement-time allows.

Audit

MethodPathPurpose
POST/audit/eventAppend a single audit-event JSON to the SQLite store. Used by hook scripts and plugin SDKs.

The gateway has no streaming or query HTTP endpoint — read history through the CLI:

defenseclaw-gateway audit export --output audit.jsonl     # JSONL of audit_events
tail -f ~/.defenseclaw/gateway.jsonl | jq                  # Live tail of the JSONL fallback
defenseclaw alerts                                          # Recent alerts (paginated)
defenseclaw tui                                             # Live dashboard

Config

MethodPathPurpose
POST/config/patchApply a JSON-Patch-style update to a single config key (used by the TUI's quick-edit panel). For full reloads, restart the gateway — see setup guardrail which restarts when needed.

AI usage / discovery (AIBOM)

The continuous AI Discovery surface — see AI Discovery for the operator workflow.

MethodPathPurpose
POST/api/v1/agents/discoveryReceive an agent-discovery report from the on-host scanner.
GET/api/v1/ai-usageSnapshot of detected AI components by ecosystem.
POST/api/v1/ai-usage/scanTrigger an on-demand AI usage scan.
GET/api/v1/ai-usage/discoveryDiscovered agents, models, tools.
GET/api/v1/ai-usage/componentsAggregated components across the active workspace.
GET/api/v1/ai-usage/components/{ecosystem}/{name}/locationsWhere the component was detected.
GET/api/v1/ai-usage/components/{ecosystem}/{name}/historyDetection history for one component.
GET/api/v1/ai-usage/confidence/policyShow the active confidence-scoring policy.
POST/api/v1/ai-usage/confidence/policy/validateDry-run validation of a candidate policy file.

Codex bridge

MethodPathPurpose
POST/api/v1/codex/notifyCodex agent-turn-complete notifier. The Codex notify-bridge.sh shim posts each turn's JSON arg here so the gateway can audit turn counts and completion reasons.

OTLP receiver

The gateway accepts OTLP-HTTP from connectors (Codex, Gemini CLI native OTLP) and from the local-observability stack. Body is OTLP-JSON.

MethodPathPurpose
POST/v1/logsIngest OTLP logs.
POST/v1/metricsIngest OTLP metrics.
POST/v1/tracesIngest OTLP traces.
POST/otlp/{token}/...Same three signals, but the token rides in the URL path instead of a header. Useful for OTLP exporters (Gemini CLI's settings.json) that can't set arbitrary HTTP headers.

See internal/gateway/otel_ingest.go for the parsing details and Local observability for the operator setup.

Verdict envelope

The four /api/v1/inspect/* endpoints return a ToolInspectVerdict (or its near-twin for response-side inspection):

{
  "action":     "block | confirm | alert | allow",
  "raw_action": "block",
  "severity":   "CRITICAL | HIGH | MEDIUM | LOW | INFO",
  "confidence": 0.93,
  "reason":     "matched: shell.dangerous-rm:Recursive delete on root",
  "findings":   ["shell.dangerous-rm"],
  "detailed_findings": [
    {
      "rule_id":    "shell.dangerous-rm",
      "title":      "Recursive delete on root",
      "severity":   "CRITICAL",
      "confidence": 0.93,
      "evidence":   "rm -rf /",
      "tags":       ["destructive", "shell"]
    }
  ],
  "mode":       "action | observe",
  "would_block": true,
  "approval_timeout_ms": 0
}

Notable behaviours:

  • action is the effective verdict, not the raw policy decision. applyMode() downgrades block / confirm / alert to allow when the gateway is in observe mode, but preserves the raw verdict in raw_action and the would-have-blocked signal in would_block. This is how observe-mode dry-runs work without touching the rule pack.
  • confirm is the in-process HITL signal. The gateway resolves the operator approval inline (via the in-process HILTApprovalManager it constructs in SetHILTApprovalManager()) before returning. There is no HTTP HITL surface — every HITL decision happens in-process and the verdict is downgraded to allow or block before the response is written. The TUI reads HITL state from the audit DB, not from a /v1/hilt/* endpoint.

Other endpoints return their own shapes — /v1/skill/scan returns a scanner-specific envelope, /audit/event returns {"status": "stored", "id": "..."}, /skill/disable returns {"status": "disabled", "skillKey": "..."}. Always confirm against the handler code before assuming a shape.

Headers

HeaderDirectionPurpose
X-DefenseClaw-Token (or Authorization: Bearer ...)requestGateway auth. Required on every endpoint except GET /health.
X-DefenseClaw-ClientrequestCSRF marker — any non-empty caller identifier (cli, openclaw-plugin, inspect-hook/1.0). Required on every state-changing endpoint.
X-DefenseClaw-Request-Idrequest (optional)Caller-supplied correlation id. The gateway also accepts the more common X-Request-Id and X-Correlation-Id for compatibility with OpenTelemetry / Envoy / Microsoft / New Relic instrumentation. If unset, the gateway mints one. See requestctx.go.