Agent gateway route
A hook route for gateways that run agents through their own tool interface and call DefenseClaw for each step. Off by default.
Some gateways run agents for many people through their own tool interface. Instead of posing as one agent (for example as Claude Code), such a gateway can call the agent-gateway route with a small event contract. DefenseClaw evaluates each event on the same path as every connector hook: the same rules, chains, correlation and lineage. Audit and telemetry record the connector as agent-gateway.
The route installs nothing into the gateway. The gateway calls it and enforces the answer.
Turn it on
The route is off by default. While it is off, /api/v1/agent-gateway/hook does not exist.
connectors:
agent_gateway:
enabled: true
instance_name: gas # optional label for audit on a per-user installThe setting takes effect at the next gateway restart.
- Per-user install. The route is served on the gateway's TCP API and takes the gateway token, like every hook route.
acting_forandroot_session_idare ignored and recorded asacting_for_ignored=untrusted_callerandroot_session_ignored=untrusted_callerin the local audit. They never change a verdict. - Managed device. Only the lifecycle or your administrator's managed policy sets the key. The route is served only on the managed hook socket (
/run/defenseclaw-hook/hook.sockon Linux), where the kernel names the caller. The caller must be an enrolled user calling for themselves, or the service account of a trusted connector. Any other caller, root included, is refused withenterprise_managed_connector_unknown. - Windows managed devices have no hook socket, so the route is not served there in 1.0.6.
Builds before 1.0.6 refuse connectors.agent_gateway as unknown, so a managed policy that sets it must require release 1.0.6 or later.
Event contract
POST /api/v1/agent-gateway/hook with a JSON body, Content-Type: application/json and an X-DefenseClaw-Client header naming the caller (any value; the gateway refuses a POST without it). The schema is schemas/connectors/agent-gateway-hook.json. Unknown fields, duplicate keys and fields an event does not take are refused with HTTP 400 and a code.
| Field | Events | Notes |
|---|---|---|
event | all | session_start, session_end, user_prompt, pre_tool, post_tool, subagent_start, subagent_stop |
session_id | all | required |
tool_use_id | pre_tool, post_tool | required; pairs a call with its result |
tool | pre_tool, post_tool | {name, kind, input}; kind is shell, file_read, file_write, fetch, mcp or other |
tool_response | post_tool | required; any JSON |
status | post_tool | success, error, denied or cancelled; only success completes a chain step |
prompt | user_prompt | required; seeds the tool judge's view of the user's intent |
parent_session_id | subagent_start, subagent_stop | required |
cwd | any | absolute working directory of the call |
traceparent | any | W3C trace context |
acting_for | any | {user}; honoured only for a trusted connector |
root_session_id | any | for a trusted connector: recorded in the local audit and kept with one person. Chains are evaluated per session; with guardrail.chains.root_scope on they also follow the root id across sessions |
tool.kind picks the tool the rules already know: shell is judged by the shell rules (input is the command, or {"command": ...}), file_read and file_write by the path rules (input names path), fetch by the network rules (input is the URL, or {"url": ...}). mcp and other keep the tool name and get every content scan that applies to a tool DefenseClaw does not know. Path rules and ~ resolve against the account that runs the tools.
{"event":"pre_tool","session_id":"s-41","tool_use_id":"t-7","cwd":"/work",
"tool":{"name":"bash","kind":"shell","input":"git status"}}The answer is the generic hook answer: action (allow, alert, block), reason, rule_ids and the decision ids.
Fail mode
The calling gateway enforces the answer; DefenseClaw cannot enforce it inside another process. On managed and strict devices, treat a call that gets no answer as a deny. On a per-user install it is the caller's choice; deny is recommended.
Moving from a posed connector
A gateway that sends PreToolUse events to /api/v1/claude-code/hook keeps working. To move, map PreToolUse to pre_tool, PostToolUse to post_tool (add status), UserPromptSubmit to user_prompt, and the Bash tool to kind: shell.
Kiro
Guard Kiro IDE and Kiro CLI with DefenseClaw hooks under one Kiro connector, and optionally with the ACP guard. Per-surface veto, Windows hook commands, the enterprise profile and the OpenShell sandbox image.
ZeptoClaw
Guard ZeptoClaw by pointing its providers at the DefenseClaw guardrail proxy, which checks every request and response.