Back to BlogSecurity

Claude Code Security: What Hooks Can and Cannot Enforce

Review Claude Code hook coverage, policy ownership, warn mode and network limits before relying on a tool-call guardrail across a team.

5 min read
by APort

Summary: A security team needs evidence that Claude Code cannot bypass a restriction through an unguarded tool or an editable policy. Installing a hook is only the first check. APort's decision-versus-enforcement contract separates a policy denial from what the host actually does, while the tested PreToolUse walkthrough demonstrates a narrow allowed command and denied fixture read.

This article is the deployment review after that walkthrough. It asks who controls the hook, which actions reach it, and which controls must sit elsewhere. A local smoke test cannot answer those questions for every developer device or session.

Follow an action past the hook

Claude Code's hook reference documents a structured permission denial before execution. The proposed tool name and input arrive at a registered hook; the host interprets its response. That makes the host part of the enforcement boundary.

Check the active configuration and restart the host after installation as described in the setup guide. Then submit a harmless fixture read through the actual session. Calling a hook script directly proves the script's behavior, but it does not prove the session has registered it or that the relevant matcher fires.

For a shell tool, distinguish the visible command from every action the command might launch. A permitted interpreter can invoke a subprocess or make a network request. Do not describe command approval as inspection of every later syscall.

Who can edit the restriction?

A local passport and hook configuration live on the developer's machine. If the agent or another process can rewrite them, the restriction can change without the intended policy review. Protect policy files and hook configuration with controls outside the agent's own authority.

Hosted verification moves policy decisions to a service, but it still depends on the runtime calling that service and honoring its response. Review local fallback, offline behavior and permitted configuration changes. Decide who may put a team into report-only mode; the agent's tool input must not select that mode.

The Cursor guide covers another runtime boundary. A shared passport model does not mean Claude Code's registration or coverage test also proves Cursor's enforcement.

What a denial does, and what it leaves unknown

Observation Supported conclusion Remaining check
Local test returns a structured deny The installed hook rejected that fixture input The active host must load it and block the call
Hosted decision has allow: false Policy denied the submitted context Confirm enforce mode and the actual runtime outcome
Report-only record contains a denial Policy found a violation The action may have continued
URL passes a domain policy Submitted metadata met the URL policy DNS, redirects and actual egress still need controls

The final row follows the web-fetch SSRF model. The hosted verifier does not resolve DNS or pin the outbound connection. Network isolation remains a separate requirement where private-network access must be prevented.

A review matrix for the actual session

Use fixture files and a tool whose only effect is recording a test invocation. The expected outcome must be declared before the test; an empty log is useful only if an allowed control first proves the tool can run.

Exercise Evidence to collect A failure means
Allowed read through Claude Code Tool invocation and fixture output Registration or policy may prevent legitimate work
Denied read through the same session Hook denial and no tool invocation Policy or host enforcement is missing if the tool runs
Verifier unavailable Error plus the configured runtime behavior An undocumented fallback needs an operator decision
Same operation through an alternate tool Coverage result at that tool's boundary The original test did not establish complete coverage
Attempted edit to policy configuration External filesystem or administration control result An editable local rule cannot be treated as immutable authority

These are deployment acceptance exercises, not benchmark results. Record the host version, active hook configuration, selected passport and mode with each run. Repeat after a relevant runtime or adapter update. This identifies what changed when a previously denied fixture begins to execute.

For an allowed shell command that launches a second process, collect evidence at the subprocess or network boundary too. A hook that inspected the original command string cannot retrospectively establish every action performed by that process.

Evidence to require before expanding access

Use a disposable workspace to test an allowed operation, a denied operation and a verifier outage. Verify that the denied operation leaves no tool-side effect in enforce mode. Record the operator's mode separately from the policy decision, and preserve decision_id when hosted verification supplies one.

Keep built-in permissions, least-privilege credentials, filesystem controls and branch protection. The review is complete only when each sensitive action has an identified enforcement point and an owner for its configuration.

Plan your Team Pilot around one developer group, its tool inventory and these deployment checks.