What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

No. A Claude Code deny rule or a policy hook is an application-level control: it decides whether an action the agent proposes is allowed to run. It does not stop a process the agent has already started from reading a file, opening a network connection, or using a credential that sits in its environment. A policy hook is worth building, but it belongs in a layered design where the operating system, the network, and the credentials enforce limits that do not depend on the model or on the hook logic.

The behavior described here reflects the linked Claude Code and Codex documentation as checked on 7 October 2026. Both products change quickly, so confirm exact field names, event lists, and version support on those pages before you deploy anything.

Application controls and operating-system boundaries do different jobs

An application-level control runs inside the product that calls the model. Claude Code’s permission rules, its PreToolUse hooks, and Codex’s lifecycle hooks all sit here. They receive a structured description of an attempted action, such as a tool name and its arguments, and they return a decision. Their strength is precision and context. Their weakness is that they only see what the product passes them, and they only run when the product invokes them with a loaded definition.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An operating-system boundary sits below the agent. The kernel or the container runtime refuses an operation no matter what the process asks for. That is the property you need when the question is “can this process read my SSH keys?” rather than “did this tool call look safe?”

Layer Where it runs What it can see Main limit
Permission deny and ask rules Inside Claude Code’s permission evaluation The tool name and the rule’s pattern Matches the form of a call, not every route to the same effect
PreToolUse or PermissionRequest hook Inside the agent’s lifecycle, before execution The event and tool context the product passes in Runs only when the product invokes it with a loaded, trusted definition
OS-level sandbox Around the agent’s process tree File and network operations attempted by the agent’s processes Only as broad as its configured paths, network rules, and writable locations, and only when enabled
Isolated workload and separate credentials Outside the agent entirely Nothing the agent process cannot reach Requires infrastructure you control; not a per-command decision

Are Claude Code deny rules a security boundary?

Not on their own. The Claude Code permissions reference distinguishes two forms of deny. A bare tool deny removes the tool from Claude’s available context. A scoped rule such as Bash(rm *) leaves the tool available and blocks calls that match the pattern. The first is a strong narrowing step for tools you never want used. The second is a filter on the shape of a call.

The filter is where the weakness lies. The same page gives concrete examples of commands and paths that certain checks do not match, and it states that some arbitrary subprocess file access and some command forms are not covered by Read and Edit rules. For OS-level enforcement across processes, it points to sandboxing. A pattern on the text rm * says nothing about a file removed by a script the command launches, or by an interpreter invoked with different wording. Read the examples on that page before you treat any scoped rule as protection.

What a PreToolUse hook can and cannot decide

  • It runs before the tool executes and receives the tool context. It can return a blocking decision, which stops the call.
  • If the handler exits successfully without a decision, the normal permission flow continues. Silence does not approve the call, and the permission rules still decide.
  • A hook that returns allow does not override a deny or ask rule. A hook can add restriction; it cannot grant what the permission configuration withholds.
  • A handler starts only when both its matcher and its narrower if condition match. A Bash matcher never sees Read, Edit, or other tool calls, so each tool class you care about needs its own coverage.

Build a Claude Code policy hook

The example below blocks Bash commands that match a short list of patterns. It is deliberately simple. Like a deny rule, it matches command text, so treat it as one layer and keep the outer controls described later in this article.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wire it up

  1. Save the script below as ~/.claude/hooks/policy-check.py, then run chmod +x ~/.claude/hooks/policy-check.py.
  2. For personal use, add the hook block to ~/.claude/settings.json. For a shared team policy, add it to .claude/settings.json at the repository root and review it in version control like any other code.
  3. Start Claude Code in the workspace. In an interactive session, accept the workspace trust prompt only for repositories whose hook definitions you have read.
  4. Test a blocked command by asking Claude to run echo policy-test-blocked. The call should be stopped and the stderr message should appear. Then remove the test pattern from the script.
  5. Test the script’s own failure path from a shell with echo '{' | python3 ~/.claude/hooks/policy-check.py; echo $?. The expected output is exit status 2, because the script refuses input it cannot parse.

The hook block, in the settings.json file from step 2:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 $HOME/.claude/hooks/policy-check.py"
          }
        ]
      }
    ]
  }
}

The script, saved as policy-check.py:

#!/usr/bin/env python3
import json
import re
import sys

# Temporary test pattern: remove it after the block test passes.
DENY_PATTERNS = [
    r"bpolicy-test-blockedb",
    r"brms+-rfs+/",
    r"bcurlb[^|]*|s*(sh|bash)b",
    r"bgits+pushb.*--force",
]

def main() -> int:
    try:
        event = json.load(sys.stdin)
        if event.get("tool_name") != "Bash":
            return 0
        command = event["tool_input"]["command"]
    except Exception as exc:
        print(f"policy hook could not read the event: {exc}", file=sys.stderr)
        return 2
    for pattern in DENY_PATTERNS:
        if re.search(pattern, command):
            print(f"blocked by policy (pattern: {pattern})", file=sys.stderr)
            return 2
    return 0

if __name__ == "__main__":
    sys.exit(main())

The script can express logic a static rule cannot, such as checking arguments or parsing paths. But it receives only the command text that Claude Code passes it. It does not see what the command’s child processes do after the command starts. That is the same boundary a deny rule has, with more code behind it.

Trust, hook sources, and who controls what runs

Hooks can come from user settings, project settings, managed policy, plugins, skills, and agents. The source matters as much as the script, because each source determines who wrote the hook and whether you reviewed it.

Command hooks run as you. The Claude Code hooks reference states: “Command hooks execute shell commands with your full user permissions.” A hook can therefore read any file your account can read. A hook committed to a repository you have just cloned deserves the same review as any script you would run by hand.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Trust gating has a headless exception. Interactive sessions hold hooks until the workspace is trusted. Headless runs with -p and SDK sessions treat the folder as trusted, so they can run hooks committed in a project settings file without showing the trust dialog. Test the policy in both modes so you know which path your team actually uses.

How Codex hooks compare

Codex exposes a different event set and a different trust model. The Codex hooks reference documents PreToolUse and PermissionRequest, along with PostToolUse, prompt submission, compaction, subagent, stop, and session lifecycle events. Hooks can sit in user or repository config layers. The table below sets the two products side by side. Where a cell says “Not stated,” the hook documentation this article relies on does not establish that behavior.

Aspect Claude Code Codex
Pre-execution event PreToolUse PreToolUse; PermissionRequest is also available
Explicit deny blocks the call Yes: a PreToolUse handler can return a blocking decision Yes: an explicit, supported denial blocks the action; the reference applies this to supported remote hooks
Hook allow against an existing deny or ask rule Deny and ask rules still apply Not stated
Config sources User settings, project settings, managed policy, plugins, skills, agents User or repository config layers; matching sources load together rather than higher-precedence layers replacing lower ones
Multiple matching hooks for one event Not stated Launched concurrently; one cannot prevent another from starting
Managed hooks Managed policy is a recognized hook source Administrator-controlled hooks are marked managed and cannot be disabled in the user hook browser
Identity a command hook runs as The user, with full user permissions Not stated
OS-level isolation Sandboxing enforces OS-level restrictions across processes Not covered by the hooks reference

Design notes for Codex hooks

  • Do not assume order. Matching command hooks for the same event start at the same time. A hook cannot wait for another hook’s result, so write each policy to decide from its own input.
  • Deploy managed scripts yourself. If your organization uses managed Codex hooks, your team must distribute and update the scripts. Codex does not distribute scripts configured in a managed directory.
  • Do not port the JSON. The Claude Code example above uses Claude Code’s event shape. Codex defines its own payload and response format. Reuse the policy logic, such as the pattern list and path checks, but write the input parsing and output against the Codex reference.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When a hook is skipped, untrusted, or fails

Each product has a different answer to the question of what happens when the policy does not run as intended. The table lists the documented outcomes.

Situation Claude Code Codex
Hook not loaded because the workspace is untrusted or the definition is unreviewed Interactive sessions hold hooks until the workspace is trusted; headless runs can execute committed project hooks without the trust dialog Non-managed hooks must be reviewed and trusted; untrusted hooks are skipped pending review
Hook changed after review Not stated Trust applies to the current definition; a changed hook is skipped pending review
Handler exits with no decision The normal permission flow continues Not stated
Explicit deny The call is blocked An explicit supported denial blocks the action
Callback error, timeout, or malformed response Not stated in the sources for this article; test your installed version The hook fails without blocking the tool
Hook allow against a deny or ask rule Deny and ask rules still apply Not stated
Script missing Not stated Codex does not distribute managed scripts; the organization must deploy them

Two gaps in that table matter most. In Codex, a failed or timed-out hook may not block the tool at all. In Claude Code, the sources for this article do not establish what a crashed or timed-out handler does, so do not assume the policy ran just because the hook is configured.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Design for both. Make your own script fail closed on every internal error path, as the Claude example does for unreadable input. Write a log line at the start of each run, so that a skipped hook is distinguishable from one that ran and allowed the call. Alert when that log goes quiet for an active session.

What enforcement belongs outside the agent

OpenAI’s agent environment security guidance says generated code can reach the files, credentials, and network available to its environment. It recommends isolated compute, network restrictions, and separated credentials. The controls below should hold even when every hook is skipped.

  • Isolated execution. For sensitive work, run the agent in a container or virtual machine that holds only the repository and the mounts it needs. Keep your host home directory, SSH keys, and cloud profiles out of that environment.
  • Restricted writes and network. Mount paths read-only wherever the task allows, limit writable directories, and permit outbound connections only to destinations the task requires.
  • Separate identity. Run the agent under a low-privilege account. Keep broad application keys out of environment variables and configuration files the agent can read; prefer short-lived, narrowly scoped credentials.
  • Human review for side effects. OpenAI’s guardrails and approvals guidance calls for independent filesystem, network, and identity boundaries, plus explicit human review for ambiguous or high-risk side effects.
  • OS-level sandboxing in Claude Code. The permissions reference recommends enabling sandboxing for OS-level enforcement across processes. Anthropic reports, in an October 20, 2025 engineering article, that sandboxing reduced permission prompts by 84% in its own internal usage. That is Anthropic’s measurement, not independent research, and it is not a guaranteed result for your setup.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.