Skip to content
Cisco AI Defense logo
CiscoAI Security

Gateway sidecar — DefenseClaw

Overview

The defenseclaw-gateway binary is the enforcement point. It connects to the OpenClaw gateway over WebSocket (device-key authenticated), inspects every tool_call / tool_result, optionally fronts LLM traffic through the guardrail proxy on port 4000, persists verdicts into the SQLite audit store, and exposes a local REST API on port 18970. The Python CLI manages scanners, policies, and config; the Go daemon does the actual live enforcement.

Lifecycle commands

CommandWhat it doesSource
defenseclaw-gateway startSpawns the gateway as a background daemon, detaches from the terminal, writes PID to ~/.defenseclaw/gateway.pid, starts the watchdog if gateway.watchdog.enableddaemon.go
defenseclaw-gateway stopSends SIGTERM, then SIGKILL after 10s if unresponsive; stops the watchdog firstrunStop
defenseclaw-gateway restartstop then start; preserves the PID file contractrunRestart
defenseclaw-gateway statusPrints subsystem health (gateway, watcher, guardrail, api, telemetry, splunk, sandbox)sidecar.go
defenseclaw-gateway runRuns in the foreground (no detach, no PID file). Useful for debugging.gateway run

On-boot supervision

systemd (Linux)

DefenseClaw does not install a generic systemd unit during init; install it with:

sudo tee /etc/systemd/system/defenseclaw-gateway@.service > /dev/null <<'EOF'
[Unit]
Description=DefenseClaw gateway sidecar
After=network-online.target
Wants=network-online.target

[Service]
Type=exec
User=%i
ExecStart=/usr/local/bin/defenseclaw-gateway run
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now defenseclaw-gateway@$USER.service

For sandbox standalone mode, init --sandbox generates openshell-sandbox.service and defenseclaw-sandbox.target under ~/.defenseclaw/systemd/ and installs them when run as root — see setup-sandbox.

launchd (macOS)

cat > ~/Library/LaunchAgents/ai.defenseclaw.gateway.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>ai.defenseclaw.gateway</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/defenseclaw-gateway</string>
    <string>run</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/tmp/defenseclaw-gateway.out.log</string>
  <key>StandardErrorPath</key><string>/tmp/defenseclaw-gateway.err.log</string>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/ai.defenseclaw.gateway.plist

What the sidecar exposes

SurfaceDefaultPurpose
REST API127.0.0.1:18970Health, status, alerts, policy reload, provider registry — consumed by the Python CLI, TUI, and IDE extensions
Guardrail proxy127.0.0.1:4000OpenAI-compatible / LiteLLM-friendly; only bound when guardrail.enabled=true
WebSocket clientOutbound to cfg.gateway.host:portAttaches to OpenClaw; authenticates with OPENCLAW_GATEWAY_TOKEN + device key

gateway.api_port and guardrail.port are configurable in config.yaml; the pinned values above are the shipped defaults.

Watchdog

The built-in watchdog is separate from systemd and designed for workstations where users don't run services under an init system. Enable it by setting gateway.watchdog.enabled=true in config.yaml; it auto-starts with start and auto-stops on stop. It polls /health, restarts the daemon on repeated failures, and logs to ~/.defenseclaw/watchdog.log.

Verify it worked

defenseclaw-gateway status
curl -s http://127.0.0.1:18970/health | jq .
curl -s http://127.0.0.1:18970/alerts | jq '.alerts | length'
ps -p $(cat ~/.defenseclaw/gateway.pid)

The /health endpoint returns a JSON map keyed by subsystem: gateway, watcher, guardrail, api, telemetry, splunk, sandbox. Each has state: running|healthy|disabled|stopped|<error>. init parses this and prints a summary.

Undo / reset

defenseclaw-gateway stop
rm -f ~/.defenseclaw/gateway.pid ~/.defenseclaw/gateway.log

Stopping the sidecar does not remove the guardrail's openclaw.json patch. Use defenseclaw setup guardrail --disable to revert OpenClaw to direct LLM mode. See setup-guardrail.

Troubleshooting

SymptomCauseFix
Gateway sidecar is already running (PID N)PID file present, process aliveExpected — use restart to reload config
start: FAILED: bind: address already in useAnother process on 18970lsof -i :18970 and kill it, or change gateway.api_port
status shows guardrail: stopped but enabled=trueUpstream LLM path not reachable, or plugin not installeddefenseclaw doctor — probably a missing plugin or bad master_key
PID file present but ps shows nothingCrash without cleanuprm ~/.defenseclaw/gateway.pid then start

Related