Claude Code Hooks Examples: Enforce Rules Before and After Actions

Claude Code Hooks Examples: Enforce Rules Before and After Actions

Claude Code hooks examples to block risky actions, validate results and log everything, without relying on the agent's memory. A practical guide.

••

Want to apply this in your company?

Book a call with Juan →

Claude Code Hooks Examples: Enforce Rules Before and After Actions

Claude Code hooks are commands you configure to run automatically at defined points in the agent's cycle, such as before a tool is used or after a file is edited. Instead of asking in the prompt that the agent remember to validate, block or log something, you move the rule into code that always runs. The result is a deterministic layer around an agent that, by nature, decides probabilistically. This article walks through practical Claude Code hooks examples for blocking, validating and logging.

Key takeaways

  • A prompt instruction is a request; a hook is a rule. The agent can forget a request, but it cannot skip a command that Claude Code itself triggers.
  • The before-action hook (PreToolUse) is for blocking. The after-action hook (PostToolUse) is for validating and logging.
  • Start with few rules: restrictive for anything irreversible, observation-only for the rest.
  • Hooks are code that runs with your user's permissions. They need review, version control and limits, like any production script.
  • A hook does not replace isolation, minimal permissions or human approval. It is one more layer, not the only one.

Why is a rule in the prompt not enough?

When you write in the project instructions file that the agent must never touch credential files, you are counting on the model's attention at every step of a long session. Most of the time it works. The problem is that a company does not decide based on most of the time. It decides based on the worst case: a destructive command, a sensitive file changed, a skipped test step.

Anthropic's article Building effective agents separates workflows (paths defined in code) from agents (which direct their own process). Hooks are a way to place a piece of workflow inside an agent: the model still chooses what to do, but certain checks always happen, in the same order, without depending on interpretation.

There is also an audit reason. If someone asks what the agent executed yesterday, the answer should not depend on what the agent remembers or summarizes. A record written by a hook is a fact; a summary from the model is a narrative.

At which points in the cycle can you intercept?

Claude Code exposes events where you can attach commands. Names and fields can change between versions, so always confirm in the official Claude Code documentation before copying a configuration. The events most useful for governance are usually these:

  • PreToolUse: runs before a tool is executed (reading, editing, a terminal command). This is the point to block.
  • PostToolUse: runs after the tool has finished. This is the point to format, test and log.
  • UserPromptSubmit: runs when a person sends a message. Useful for validating the request or adding context.
  • Stop: runs when the agent believes it is done. Useful for requiring that tests pass before accepting the end of the task.
  • SessionStart and SessionEnd: mark the beginning and end of the session, useful for loading context and closing the log.
  • Notification: fires when the agent needs attention, for example to ask for permission. Useful for alerting someone.

Hooks are declared in Claude Code configuration files, at the user or project level. Each entry ties an event to a filter (the matcher, which can point to a specific tool) and to a command. The command receives the event data as JSON on standard input, including the tool name and the parameters it is about to use.

How do you block a dangerous action before it happens?

The pattern is simple. You register a PreToolUse hook for the tools that matter, for example the terminal command tool and the file editing tools. The script reads the incoming JSON, inspects the command or file path, and decides. According to the Claude Code documentation, an exit code that signals a block (code two) stops the tool from running and returns to the agent the text the script wrote to the error channel. This matters: the block message becomes information the model can use to adjust its plan, not just a bare failure.

Good blocking rules have three traits:

  • They think in allowlists, not only denylists. Blocking only the dangerous commands you know about lets through the dangerous ones you did not foresee. Allowing only a known set of commands for certain folders is safer.
  • They give a useful message. Instead of denied, write something like: editing environment files is not allowed in this session; ask a person for approval.
  • They protect what is irreversible first: deleting data, publishing to the main branch, touching the production environment, sending messages to customers, changing credentials.

This reasoning is the principle of least privilege described in the OWASP authorization cheat sheet: grant only the access the task needs and deny the rest by default. The hook is the practical implementation of that idea inside the agent's session.

One engineering caution: the blocking script must be fast, predictable and tested on its own. If it crashes, the behavior depends on how it was written and on how your Claude Code version treats failures that are not blocks. Test both paths, allow and deny, with sample inputs before turning the hook on.

How do you validate and log after the agent acts?

The PostToolUse hook runs once the action has already happened, so it does not undo anything by itself. Its value is in closing the verification loop. Common uses:

  • Run the formatter and static analyzer on the files that were just changed and return the errors to the agent for immediate correction.
  • Run the tests most related to the change and report failures in plain text.
  • Write one log line per action, with date and time, session identifier, tool used and a summary of the target (file path or command).
  • Flag changes outside the expected scope, such as configuration files touched during a task that should only change one screen.

The Stop hook completes the design. It can refuse to let the task end until an objective condition is met, for example passing tests or an updated changelog file. That way the definition of done stops being the agent's opinion.

As for logging, think the way you would about observability: the goal is to reconstruct what happened from data, not from memory. The OpenTelemetry observability primer describes well the idea of having enough signals to understand a system's behavior from the outside. A file of JSON lines with stable fields already does that job at the start; later it can feed a dashboard.

A privacy warning: what passes through a coding session can include personal data, keys and fragments of real databases. Log metadata and paths, not full content. If the workflow touches customer data, align what is stored, for how long and for what purpose, as we discuss in LGPD compliance for AI on WhatsApp: legal basis, consent and records. The reasoning applies well beyond WhatsApp.

What are the steps to deploy your first hook?

A lean sequence, in the order that usually causes the least rework:

  • Step one: list the actions that must not happen without a person deciding (deleting, publishing, changing credentials, sending anything externally). This list becomes your blocking rules.
  • Step two: list the checks someone currently does by hand after the work (formatting, testing, reviewing scope). This list becomes your validation rules.
  • Step three: write the logging hook first, blocking nothing. Run it for a few days of normal use and read what was recorded.
  • Step four: based on the real log, write the first blocking hook for the most critical action. Test it with allowed and forbidden inputs outside Claude Code.
  • Step five: keep the scripts and configuration in the project repository, with code review, so the rule is versioned and discussed by the team.
  • Step six: define who receives the alert when a block happens and what that person does. A block without an owner is just frustration.
  • Step seven: review the log periodically. Rules that never fire can be removed; rules that fire constantly point to a problem in the workflow or the instructions.

What does this look like in practice? Illustrative scenario

Illustrative scenario: a small online store team uses Claude Code to maintain the code that connects orders, inventory and customer messaging. The person in charge wants more speed but fears three things: accidental changes to files with keys, direct changes to the production environment, and code shipped without tests.

She configures four hooks. A PreToolUse hook denies edits to environment files and commands that point to the production database, returning a message asking for human approval. A PostToolUse hook runs the formatter and the tests for the changed module and returns failures to the agent. A second PostToolUse hook writes one line per action to a file, with session, tool and target. The Stop hook refuses to end the task if the module's tests are failing.

In the first week, the log shows the agent tried to read a credentials file to find a variable. Nothing serious happened, but the team decides to supply that variable through a controlled path and adjust the project instructions. The hook did not solve everything; it made visible what would otherwise have gone unnoticed.

What are the limits and risks of hooks?

Hooks are powerful precisely because they execute real commands. That brings responsibilities:

  • They run with the permissions of the user who started the session. A badly written hook, or one altered by a third party, can cause damage. Treat hook configuration in a shared repository as sensitive code, with mandatory review.
  • A text filter does not understand intent. Blocking a word in a command is fragile, since the same effect can be reached in other ways. Combine hooks with Claude Code's own permissions, an isolated environment and credentials with minimal scope.
  • External content can manipulate the agent. Pages, files and messages read during the task may contain malicious instructions. The OWASP Top 10 for LLM applications covers this risk, and blocking hooks help limit the damage, but they do not remove the need to isolate what the agent can reach.
  • Too many rules cause fatigue. If all work runs into confusing blocks, the team tries to work around them. Few rules, clear and with a useful message, work better.
  • Hooks do not decide what is acceptable for the business. A policy does. To define which actions require human approval and who approves, start from an AI agent approval policy.

How to apply the method: map, limit, pilot and hand over

The same path we use for any AI agent works for hooks. Map: describe the current workflow, who does what, where the risk is and what is checked by hand today. Limit: turn the risks into blocking rules, folder and data scope, and choose what requires human approval. Pilot: run a real workflow with logging and an agreed metric, such as useful blocks or rework avoided, following the logic of measuring an AI automation pilot. Hand over: deliver the documented, versioned rules to the team, with a named owner, and decide whether to expand, adjust or stop.

If you are rolling this out across a whole team, the controls around access and review are covered in Claude Code for teams: an adoption guide with controls. And if the agent in question is not only a coding agent but operates tools exposed to other people or channels, the same evidence-before-exposure reasoning appears in the OpenClaw Gateway security checklist.

Frequently asked questions

What are Claude Code hooks and what are they for? They are commands configured to run on specific events in the Claude Code cycle, such as before and after a tool is used. They enforce rules that cannot depend on the model's memory: blocking actions, validating results and recording what happened.

Can a hook stop the agent from running a command? Yes. A PreToolUse hook can block the tool before it runs, and the block message is returned to the agent. Even so, it should be combined with minimal permissions and an isolated environment, because a single filter can have gaps. Confirm the exact exit code behavior in the documentation for your version.

Do hooks replace human review? No. They automate objective checks and create a record, but business decisions, such as publishing, deleting data or contacting customers, still call for a person's approval. The hook can be precisely the mechanism that interrupts the action and brings that person in.

Where do I start without putting the project at risk? Start with a hook that only logs actions, watch real usage, and only then add blocks for irreversible actions. Keep the scripts versioned in the repository, test them outside the agent, and review the log regularly to adjust whatever is excessive or insufficient.

Sources