Connectors

Claude Code

Claude Code connector wires the documented lifecycle hook set plus native OTel. Thirteen current events can return block decisions, and PreToolUse supports native HITL ask.

The Claude Code connector wires DefenseClaw into Anthropic's documented hook surfaces without inserting a proxy in the data path. Claude Code talks directly to its native upstream; DefenseClaw inspects via hooks + native OTel.

The Claude Code connector is hook-only. There is no LLM-proxy data path — Claude Code talks directly to api.anthropic.com and DefenseClaw observes via hooks + native OTel.

mode=action is supported on Claude Code's declared blocking hook events. PreToolUse can return deny or native ask before the tool. Post-result events are advisory: they preserve findings and shadow would_block telemetry without stopping Claude's next turn. No proxy listener is involved.

Platform support

PlatformStatusConnector path
macOS and LinuxSupportedPortable command hooks plus Claude Code's native OTel exporter.
Native Windows x64SupportedShell-free native executable hooks using Claude Code's command plus args exec form. Official-client validation metadata remains empty and live=false; support availability is not a certification claim.

Setup

defenseclaw setup claude-code                # observe (default) — record only
defenseclaw setup claude-code --mode action  # block on policy hits via PreToolUse deny

DefenseClaw installs the portable Claude Code hook and configures the native OTel exporter in the user settings.

defenseclaw setup claude-code                # observe (default) — record only
defenseclaw setup claude-code --mode action  # block on policy hits via PreToolUse deny

Install and run Claude Code directly from PowerShell or CMD using Anthropic's native setup. DefenseClaw registers the protected defenseclaw-hook.exe through Claude Code's shell-free command plus args exec form. Git for Windows is recommended upstream when Claude should use its Bash tool, but it is optional; without it Claude uses its native PowerShell tool. Git for Windows is not part of the DefenseClaw hook contract. WSL, Git Bash, Cygwin, MSYS, containers, and virtual machines are outside this native connector path.

setup claude-code is the dedicated Claude Code setup alias. It uses the same setup backend as setup guardrail, adds or reconfigures claudecode, wires hooks + native OTel, and can join an existing hook-connector roster when you choose Add. No proxy listener binds in either mode.

Native OTLP uses managed loopback exporter settings with a Claude-scoped Authorization bearer. Logs and metrics are enabled; traces are explicitly disabled. Prompt and assistant-response content logging are independent vendor opt-ins and DefenseClaw explicitly defaults both off; downstream redaction settings do not silently authorize source capture. The scoped credential cannot authenticate management or another connector and must never be printed or copied.

Redaction is configured through the v8 bucket/profile policy: edit observability.destinations[].routes[].selector.buckets and observability.redaction_profiles, then follow Redaction → Verify policy.

The alias defaults to observe mode and accepts the common hook-connector options, including --mode, --workspace, --rule-pack, --human-approval, --hilt-min-severity, --fail-mode, --block-message, --replace, --with-local-stack, and restart controls. Use the quick-alias reference for that surface. Use the full guardrail setup when you also need scanner, detection-strategy, or judge-provider configuration. Defaults are documented once on the Defaults page.

Files DefenseClaw will modify

DefenseClaw manages marked hooks and OTLP environment entries in %CLAUDE_CONFIG_DIR%\settings.json; the default directory is %USERPROFILE%\.claude. Generated runtime and protected connector credentials live below %USERPROFILE%\.defenseclaw\hooks. See the Windows path reference.

settings.json (hooks block + managed native OTel environment entries)

DefenseClaw stores a hash-checked backup of settings.json before edits. Teardown restores it byte-for-byte when the identity still matches; if the file drifted, only DefenseClaw-owned entries are removed.

Claude Code keeps user/local MCP registration state in ~/.claude.json (%CLAUDE_CONFIG_DIR%\.claude.json when that override is set) and project MCP state in <workspace>/.mcp.json; these are inventory surfaces, not hook setup files. See Anthropic's MCP scope reference. The current connector inventories those local, project, and user manual scopes. Plugin-provided MCP and claude.ai connector MCP are not attributed from these files. Marketplace plugin cache artifacts honor CLAUDE_CODE_PLUGIN_CACHE_DIR; retained versions are not presented as active without semantic client evidence. Managed enabledPlugins takes precedence over user, project, and local preferences; a dynamic policyHelper is reported as unverified instead of guessed. Skill inventory covers the launch directory, every parent through the repository root, and existing nested .claude/skills roots that Claude can lazily activate after file activity. Nested skills remain discoverable-unverified until session activity proves activation; true skills take precedence over legacy commands, and documented skill-directory symlinks are canonicalized and de-duplicated. Recursive user/project agents use required frontmatter identity and closest-project precedence. Managed/plugin agents and session --agents remain unverified. Auto-memory resolves file-based autoMemoryDirectory precedence or the shared repository/worktree default under ~/.claude/projects/<project>/memory; it is marked unverified when session --settings, remote settings, or native policy could change the active path. Runtime /add-dir roots remain outside persistent passive inventory. Claude Code 2.1.219+ emits DirectoryAdded, so DefenseClaw records the added path and source without treating the observation as durable discovery authority.

Enterprise (standalone profile)

In the enterprise standalone profile, Claude Code gets machine policy instead of the per-user files above. The managed-settings.d directory (/etc/claude-code on Linux, /Library/Application Support/ClaudeCode on macOS, C:\Program Files\ClaudeCode on Windows) holds 90-defenseclaw.json with the hooks and 00-defenseclaw-version-floor.json, which sets requiredMinimumVersion to 2.1.154, the lowest Claude Code version with a verified DefenseClaw hook contract. Claude Code reads that setting only from 2.1.163, so builds older than 2.1.163 ignore it and this floor stops no build; use application control to keep older builds off a host. Your own requiredMinimumVersion wins, and a file at that name that DefenseClaw did not write (for example the version-floor export you deploy) is yours: DefenseClaw never rewrites or removes it. A higher-precedence source (HKLM Settings, macOS managed preferences) has to carry the key itself, because Claude Code builds before 2.1.242 read only that source. See Claude Code version floor.

Hook capabilities

Block events

  • UserPromptSubmit
  • UserPromptExpansion
  • PreToolUse
  • PermissionRequest
  • TaskCreated
  • TaskCompleted
  • TeammateIdle
  • Stop
  • SubagentStop
  • ConfigChange
  • PreCompact
  • Elicitation
  • ElicitationResult

Native ask events

  • PreToolUse

Claude Code's post-result surfaces (PostToolUse, PostToolUseFailure, PermissionDenied, and PostToolBatch) carry returned content rather than a new typed action request. DefenseClaw still scans that content for trust, secret, and PII findings, but command, path, cognitive-file, and C2 rules do not block on literals found in the returned bytes. For example, source text that explains rm -rf / can produce telemetry without being mistaken for a request to execute it. If Claude later proposes that command, PreToolUse evaluates the typed tool arguments and can deny it before execution.

A standalone PostToolUse response may also use physically verified local source provenance to lower source-code trust findings to detection-only telemetry. Batch, failure, denial, and mixed outputs remain untrusted content; they are still advisory because they cannot be attributed to one executable request safely.

Subagents and the Agent tool

Claude Code runs subagents through its Agent tool. Measured on 2.1.156, with the hooks outside a sandbox:

  • The Agent call gets its own PreToolUse, and a PostToolUse once the subagent is done. That PostToolUse arrives after the subagent's own hooks and its SubagentStop, and names the subagent it ran in tool_response.agentId. A backgrounded call (run_in_background) gets its PostToolUse at launch, with status async_launched. An Agent call of an unknown subagent type gets a PostToolUseFailure.
  • Every hook the subagent fires (SubagentStart, its PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure and PostToolBatch, and SubagentStop) carries its agent_id and agent_type. The main agent's hooks carry neither. No hook carries the ID of the Agent call that started the subagent.
  • A subagent interrupted with Esc sends nothing more: no PostToolUse for the Agent call, no SubagentStop, PostToolBatch or Stop. A call the user refuses at Claude Code's permission prompt gets no PostToolUse either; only the PostToolBatch of its turn lists it.

DefenseClaw records a subagent's calls under the subagent's agent ID and type, with the main agent as parent at depth 1, also for parallel Agent calls (Claude Code subagents cannot start subagents). Hooks without an agent_id are the main agent's, and it keeps one agent identity while subagents run or after one was interrupted. The correlation ledger records each subagent as caused by the Agent call that ran it (relationship caused_by, rule spawned-agent-tool-result). A PostToolBatch names no tool of its own. It is recorded as a tool_batch tool record that lists its calls by tool_name and tool_use_id, rather than as a second result of one of them.

Protection for active AGENTS.md and MEMORY.md files is similarly context-bound. DefenseClaw accepts an active file only from an authenticated InstructionsLoaded event that names the exact absolute, regular, non-symlinked file. A later PreToolUse mutation is enforcement-eligible only in that same Claude Code session and for that exact path. A file mention, a Read call, a generic payload field, or an event from another session cannot claim this authority. If an authenticated event names a recognized absolute AGENTS.md or MEMORY.md path but native file identity cannot be proved, DefenseClaw records bounded session uncertainty and fails closed only for a statically proven mutation of the corresponding canonical instruction-file name. Relative, malformed, and unrelated instruction loads remain ignored. Distinct lexical same-name mutation aliases remain visible as detection-only unless cached identity or filename-case proof establishes the exact active path.

Claude Code is one of the few connectors that supports native PreToolUse ask. HITL approvals surface inside the agent UI itself, so the operator never has to leave Claude Code to decide.

Setup is observation-only and is not registered. WorktreeCreate is not registered because a handler replaces Claude Code's default worktree creation and must return the new path. The exact version-selected contract registers 28 events for Claude Code >=2.1.154,<2.1.219 and 29 for >=2.1.219. The added DirectoryAdded hook is synchronous, matcherless, bounded to 30 seconds, and observation-only: it runs after the directory is added and has no block, ask, or decision authority.

Telemetry channels at boot

Agent runtimeClaude Code
ConnectorVersion-selected 28/29-eventhook contract
ConnectorNative OTel exporter(env-driven)
Control planedefenseclaw-gateway
Two telemetry channels: hooks for per-tool-call decisions and native OTel for model/token metrics plus privacy-gated events.

In an OpenShell sandbox

defenseclaw sandbox run claude runs Claude Code in an NVIDIA OpenShell sandbox on Linux, or on a Mac with Apple silicon in a MicroVM of its own that works on a copy of your folder (macOS): the agent sees only your project folder, and DefenseClaw hooks gate every tool call. The sandbox guide covers setup, the session and every flag. The files below exist only in the sandbox image; your own Claude Code configuration does not change.

  • Managed tier. The hooks are in the root-owned managed policy drop-in /etc/claude-code/managed-settings.d/50-defenseclaw.json, with allowManagedHooksOnly set, so user and project settings cannot add hooks or switch DefenseClaw's off. The same drop-in turns off Claude Code's own sandbox (it cannot run inside OpenShell), the auto-updater, the installation checks (the image pins its own Claude Code, so there is nothing to install or update) and non-essential traffic, and sends Claude Code's OTel to DefenseClaw. The hooks fail closed and authenticate with a per-sandbox token, never the host gateway token.
  • Skip-permissions. On by default (the open and balanced packs): Claude Code starts with --dangerously-skip-permissions. --safe, or the strict pack, keeps its permission prompts. The sandbox's managed settings then refuse bypassPermissions from a flag or any settings file, and --dangerously-skip-permissions, --allow-dangerously-skip-permissions and --permission-mode bypassPermissions are dropped from the arguments you pass.
  • Model sign-in. --llm auto (the default) shares ANTHROPIC_API_KEY, or else CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token), from your shell. OpenShell holds the secret, and the sandbox gets a placeholder that works only at api.anthropic.com. --llm bedrock, and auto when neither is set, shares a short-term Amazon Bedrock API key from AWS_BEARER_TOKEN_BEDROCK for the Bedrock Mantle Anthropic endpoint in --bedrock-region (default $AWS_REGION, then $AWS_DEFAULT_REGION, then us-east-1). openshell.llm sets the choice for runs without --llm, such as the claude shell wrapper's. With --llm none, or when no key is found, log in inside the sandbox; that login stays in the sandbox home, where the agent can read it.
  • Bedrock models. Bedrock Mantle serves Claude models only under anthropic.* ids, not Claude Code's own model names, so a Bedrock run starts on anthropic.claude-sonnet-5 and maps the /model choices to Mantle ids: Opus to anthropic.claude-opus-4-8, Sonnet to anthropic.claude-sonnet-5 and Haiku (also used for background tasks) to anthropic.claude-haiku-4-5. Pick another model with -- --model MODEL, for example defenseclaw sandbox run claude --llm bedrock -- --model anthropic.claude-opus-5, or type /model anthropic.claude-opus-5 in the session. The banner's Model line names the model either way.
  • Per-sandbox settings. Each sandbox also gets a read-only drop-in, 60-defenseclaw-run.json, that wins over the image's. It pins the model provider the run chose (and on Bedrock its models), so a repository's .claude/settings.json cannot send the conversation to another endpoint. It admits only the MCP servers DefenseClaw brought along from your Claude Code setup; a read-only /etc/claude-code/managed-mcp.json lists them, so a repository's .mcp.json servers never start unless the sandbox pack sets mcp.project_servers: allow. --no-mcp leaves your servers behind.
  • Image and verification. The image installs Claude Code 2.1.156 by default and refuses a version without a reviewed Linux hook contract. Verified end to end: against a mock model every required hook fired and a blocked tool call did not run, also with hostile user and project settings such as disableAllHooks, and a live sandbox run showed a DefenseClaw-blocked command denied and the egress block list holding.

Disable

defenseclaw guardrail disable --connector claudecode --yes