Multi-connector
One DefenseClaw gateway enforces guardrail policy for N hook connectors at once — each with its own mode, fail mode, HILT, block message, and rule pack — under guardrail.connectors. Add a connector with setup <connector> → "Add", and claw.mode flips to multi.
A single DefenseClaw gateway can enforce guardrail policy for several hook connectors at once — Codex, Claude Code, Antigravity, and the other hook-based agents — each with its own independent posture. This is the multi-connector model. It replaces the older "one active connector at a time" mental model: you no longer have to switch wiring to protect a second agent.
Multi-connector is a hook-connector feature. The proxy-backed connectors (OpenClaw, ZeptoClaw) cannot be multi peers — they bind a proxy listener and own the agent traffic plane, so only one runs at a time. Hook connectors post structured events to the gateway and never contend for a listener, which is what lets the gateway fan out to N of them.
How one gateway enforces N connectors
Each connector you add gets an entry under guardrail.connectors.<name> in ~/.defenseclaw/config.yaml. The gateway resolves policy per connector: when a hook event arrives tagged with its connector source, the gateway looks up that connector's override block and falls back to the global guardrail.* values for anything the block leaves unset.
claw:
mode: multi # set automatically once >1 connector is active
guardrail:
enabled: true
mode: action # global default — inherited by any connector that doesn't override
hook_fail_mode: closed
rule_pack_dir: ~/.defenseclaw/policies/guardrail/default
connectors:
codex:
mode: action # Codex enforces
hook_fail_mode: open # explicit softer override for Codex
claudecode:
mode: observe # Claude Code only logs
hilt:
enabled: true
min_severity: HIGHEvery field under a connector is optional. An unset field inherits the global value, so a connector block only needs to carry what differs.
claw.mode becomes multi
claw.mode records which connector is "active" on a single-connector install. The moment a second connector is active, DefenseClaw sets claw.mode: multi. This sentinel also surfaces in telemetry: the OTel resource attribute defenseclaw.claw.mode reports multi so dashboards and SIEM rules can tell a fan-out gateway apart from a single-connector one. See Configuration → guardrail.connectors for the full schema.
Adding a connector (Add vs Replace)
Run the hook setup for the connector you want to add:
defenseclaw setup codexIf a different connector is already wired, the wizard asks whether to Add or Replace:
Add
Keep the existing connector(s) wired and layer the new one in. The gateway now enforces both; claw.mode flips to multi. This is the multi-connector path.
Replace
Tear down the previous connector's wiring and make the new one the single active connector. Use this only when you no longer want the old connector wired.
Choose Add to build a multi-connector install. Each added connector starts from the global guardrail defaults; tune it afterward with the per-connector CLI (below).
Stand up several at once with defenseclaw init
The Add/Replace flow above is the incremental path — layer in one connector at a time. To stand up a multi-connector install in a single pass, use defenseclaw init: it auto-detects every installed hook connector, configures them all in observe, and asks you to name the action-mode subset in one question. Everything you have lands under guardrail.connectors.<name> in one go; tune individual connectors afterward with the per-connector CLI below.
For scripted or non-interactive setups, the same fan-out is available through two init-only flags — --observe-all (every detected hook connector in observe) and --action-connectors codex,claudecode (the named subset in action, composable with --observe-all):
defenseclaw init --non-interactive --yes --observe-all --action-connectors codexinit only fans out to hook connectors. Proxy connectors (OpenClaw, ZeptoClaw) are detected but excluded from the observe-all set — they can't be multi peers — and init points you at defenseclaw setup <proxy> to configure them on their own.
Per-connector overrides
The five fields you can override per connector mirror the global guardrail knobs:
| Field | Meaning | Inherits when unset |
|---|---|---|
enabled | Per-connector on/off switch (guardrail disable --connector X). Drops it from the active set and removes its hooks; re-enable restores it with no re-prompt. | enabled |
mode | observe (log only) or action (enforce). | global guardrail.mode |
hook_fail_mode | open / closed — what to do on a malformed/4xx hook response for this connector. | global guardrail.hook_fail_mode |
hilt | { enabled, min_severity } — per-connector human-in-the-loop policy. | global guardrail.hilt |
block_message | Custom block text shown to this connector's agent. | global guardrail.block_message |
rule_pack_dir | Path to the rule pack this connector scans against. | global guardrail.rule_pack_dir |
Set any of these with the per-connector CLI:
defenseclaw guardrail fail-mode closed --connector codex
defenseclaw guardrail hilt on --min-severity HIGH --connector claudecode
defenseclaw guardrail block-message "Codex policy blocked this" --connector codex
defenseclaw guardrail disable --connector codex # scoped kill switch
defenseclaw guardrail enable --connector codex # restore it--connector X is the explicit scope selector: it writes only that connector's override. On a multi-connector install, unscoped writes are the broad operator-intent path. guardrail fail-mode, guardrail hilt, and guardrail block-message reconcile the active connector posture so an existing override does not silently keep the old value. block-message also updates the shared guardrail.block_message fallback. On a single-connector install, --connector is rejected because there is only one posture to set.
To read the resolved posture, run bare defenseclaw guardrail status — it prints one per-connector block for every active connector. Pass --connector X to narrow the status view to one active connector:
defenseclaw guardrail status # per-connector blocks for ALL active connectors
defenseclaw guardrail status --connector codexSee Reference → CLI for the full command group.
CLI contract: read vs write
Once a gateway protects more than one connector, the CLI splits cleanly into commands that read across the whole roster, commands that write broad state by default, and commands that write to one connector when you pass --connector:
| Commands | Scope | How to narrow |
|---|---|---|
defenseclaw status, defenseclaw doctor, bare defenseclaw guardrail status, bare guardrail fail-mode / hilt / block-message, skill list, mcp list, plugin list, tool list, tool status, codeguard status | Read — fans out to every active connector. Identical layout whether one or N are wired. | guardrail status --connector X, skill list --connector X, mcp list --connector X, plugin list --connector X, tool list --connector X, and tool status --connector X narrow where supported. |
alerts | Read — recent decisions across connectors by default. | alerts --connector X filters to events attributed to one connector. |
guardrail enable / disable / fail-mode / hilt / block-message (with an argument) | Guardrail write — scoped or broad. --connector X writes one connector override. Omit --connector for the broad path: enable/disable is global; fail-mode, HITL, and block-message update active connector posture. | --connector X to target a specific connector. |
skill, mcp, plugin, and tool policy verbs (block, allow, unblock, plus runtime verbs such as disable / enable where supported) | Asset-policy write — broad fallback by default, connector-scoped when requested. Bare writes apply across matching configured connector copies or the unscoped fallback tier for that asset family. | --connector X writes or clears only that connector's scoped state. |
mcp set / mcp unset, skill install, plugin remove, codeguard install / install-skill | Config/install write — all configured/active connectors by default. | --connector X writes or removes only one connector's source. |
skill scan / mcp scan / plugin scan / aibom scan | Scan — configured/active connectors by default. | Positional target and --connector X narrow where supported. |
defenseclaw doctor and defenseclaw status both render a per-connector block for each active connector when more than one is wired — the same fan-out the rest of the read commands use. There is no single "active connector" summary to misread.
The firewall stays global
Per-connector policy is a guardrail concept. The egress firewall is not per-connector — it is one host-wide OS packet filter (pf/iptables) compiled from a single firewall.yaml, filtering by destination only. Each connector's allowed hosts are merged into that one allowlist at boot; the kernel can't attribute a connection to a connector. See docs/ARCHITECTURE.md → Firewall scope for the rationale.
See also
- Changing connectors — add, reconfigure, remove, or replace connector wiring
- Setup Guardrail — the central setup command and the Add/Replace prompt
- Reference → Configuration — the
guardrail.connectorsschema - Observability — filtering telemetry by the
connectordimension
Quick setup aliases
defenseclaw setup codex, setup claude-code, setup cursor, setup copilot, setup openhands, setup antigravity, setup hermes, setup opencode, setup omnigent, setup geminicli, setup windsurf, setup openclaw, setup zeptoclaw — one command per agent, no questions asked.
Changing connectors
Use defenseclaw setup <connector> to add or reconfigure connector wiring, and setup remove <connector> to retire a connector without deleting audit history.