Configure a PreToolUse hook to prevent AI agents
Block no verify hook

Configure a PreToolUse hook to prevent AI agents from skipping git pre-commit hooks with --no-verify and other bypass flags. Use when setting up Claude Code projects that enforce commit quality gates.
--- name: block-no-verify-hook description: Configure a PreToolUse hook to prevent AI agents from skipping git pre-commit hooks with --no-verify and other bypass flags. Use when setting up Claude Code projects that enforce commit quality gates. --- # Block No-Verify Hook PreToolUse hook configuration that intercepts and blocks bypass-flag usage before execution, ensuring AI agents cannot skip pre-commit hooks, GPG signing, or other git safety mechanisms. ## Overview AI coding agents (Claude Code, Codex, etc.) can run shell commands with flags like `--no-verify` that bypass pre-commit hooks. This defeats the purpose of linting, formatting, testing, and security checks configured in pre-commit hooks. The block-no-verify hook adds a PreToolUse guard that rejects any tool call containing bypass flags before execution. ## Problem When AI agents commit code, they may use bypass flags to avoid hook failures: ```bash
Overview
PreToolUse hook configuration that intercepts and blocks bypass-flag usage before execution, ensuring AI agents cannot skip pre-commit hooks, GPG signing, or other git safety mechanisms.
Manual install (npx, ZIP)
npx skills add wshobson/agents --skill block-no-verify-hook -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/wshobson/agents/tar.gz/4236bb91f839 \
| tar -xz -C ~/.claude/skills --strip-components=4 agents-4236bb91f839/plugins/block-no-verify/skills/block-no-verify-hookNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/c99c4ed311898c1dcd7c/block-no-verify-hook.zip" -OutFile "$env:TEMP\block-no-verify-hook.zip"; Expand-Archive "$env:TEMP\block-no-verify-hook.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md6.2 KB
Read the files here
wshobson/
Show the full text194 lines
Block No-Verify Hook
PreToolUse hook configuration that intercepts and blocks bypass-flag usage before execution, ensuring AI agents cannot skip pre-commit hooks, GPG signing, or other git safety mechanisms.
Overview
AI coding agents (Claude Code, Codex, etc.) can run shell commands with flags like --no-verify that bypass pre-commit hooks. This defeats the purpose of linting, formatting, testing, and security checks configured in pre-commit hooks. The block-no-verify hook adds a PreToolUse guard that rejects any tool call containing bypass flags before execution.
Problem
When AI agents commit code, they may use bypass flags to avoid hook failures:
# These commands skip pre-commit hooks entirely
git commit --no-verify -m "quick fix"
git push --no-verify
git commit --no-gpg-sign -m "unsigned commit"
git merge --no-verify feature-branch
This allows:
- Unformatted code to enter the repository
- Linting errors to bypass checks
- Security scanning to be skipped
- Unsigned commits to bypass signing policies
- Test suites to be circumvented
Solution
Add a PreToolUse hook to .claude/settings.json that inspects every Bash tool call and blocks commands containing bypass flags.
Configuration
Add the following to your project's .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
How It Works
- Matcher: The hook targets only
Bashtool calls, so it does not interfere with other tools (Read, Edit, Grep, etc.). - Inspection: The
$TOOL_INPUTenvironment variable contains the full command the agent is about to execute. The hook usesprintfto safely pass input (avoidingechopitfalls with special characters) and checks for--no-verifyor--no-gpg-signflags only when preceded by agitcommand. - Blocking: If a bypass flag is found in a git command, the hook exits with code 2 and prints an error message. Exit code 2 signals Claude Code to reject the tool call entirely.
- Pass-through: If no bypass flag is found, the hook exits with code 0 and the command executes normally.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Allow the tool call to proceed |
| 1 | Error (tool call still proceeds, warning shown) |
| 2 | Block the tool call entirely |
Blocked Flags
| Flag | Purpose | Why Blocked |
|---|---|---|
--no-verify |
Skips pre-commit and commit-msg hooks | Bypasses linting, formatting, testing, security checks |
--no-gpg-sign |
Skips GPG commit signing | Bypasses commit signing policy |
Installation
Per-Project Setup
Create or update .claude/settings.json in your project root:
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
EOF
Global Setup
To enforce across all projects, add to ~/.claude/settings.json:
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi"
}
}
]
}
}
EOF
Verification
Test that the hook blocks bypass flags:
# This should be blocked by the hook:
git commit --no-verify -m "test"
# This should succeed normally:
git commit -m "test"
Extending the Hook
Adding More Blocked Flags
To block additional flags (e.g., --force), extend the grep pattern:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign|force-with-lease|force)'; then echo 'BLOCKED: Bypass flags are not allowed.' >&2; exit 2; fi"
}
}
]
}
}
Combining with Other Hooks
The block-no-verify hook works alongside other PreToolUse hooks:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: Bypass flags not allowed.' >&2; exit 2; fi"
}
},
{
"matcher": "Bash",
"hook": {
"type": "command",
"command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE 'rm\\s+-rf\\s+/'; then echo 'BLOCKED: Dangerous rm command.' >&2; exit 2; fi"
}
}
]
}
}
Best Practices
- Commit the settings file -- Add
.claude/settings.jsonto version control so all team members benefit from the hook. - Document in onboarding -- Mention the hook in your project's contributing guide so developers understand why bypass flags are blocked.
- Pair with pre-commit hooks -- The block-no-verify hook ensures pre-commit hooks run; make sure you have meaningful pre-commit hooks configured.
- Test after setup -- Verify the hook works by intentionally triggering it in a test commit.
| 1 | |
| 2 | name block-no-verify-hook |
| 3 | description Configure a PreToolUse hook to prevent AI agents from skipping git pre-commit hooks with --no-verify and other bypass flags. Use when setting up Claude Code projects that enforce commit quality gates. |
| 4 | |
| 5 | |
| 6 | # Block No-Verify Hook |
| 7 | |
| 8 | PreToolUse hook configuration that intercepts and blocks bypass-flag usage before execution, ensuring AI agents cannot skip pre-commit hooks, GPG signing, or other git safety mechanisms. |
| 9 | |
| 10 | ## Overview |
| 11 | |
| 12 | AI coding agents (Claude Code, Codex, etc.) can run shell commands with flags like `--no-verify` that bypass pre-commit hooks. This defeats the purpose of linting, formatting, testing, and security checks configured in pre-commit hooks. The block-no-verify hook adds a PreToolUse guard that rejects any tool call containing bypass flags before execution. |
| 13 | |
| 14 | ## Problem |
| 15 | |
| 16 | When AI agents commit code, they may use bypass flags to avoid hook failures: |
| 17 | |
| 18 | |
| 19 | # These commands skip pre-commit hooks entirely |
| 20 | git commit --no-verify -m "quick fix" |
| 21 | git push --no-verify |
| 22 | git commit --no-gpg-sign -m "unsigned commit" |
| 23 | git merge --no-verify feature-branch |
| 24 | |
| 25 | |
| 26 | This allows: |
| 27 | Unformatted code to enter the repository |
| 28 | Linting errors to bypass checks |
| 29 | Security scanning to be skipped |
| 30 | Unsigned commits to bypass signing policies |
| 31 | Test suites to be circumvented |
| 32 | |
| 33 | ## Solution |
| 34 | |
| 35 | Add a `PreToolUse` hook to `.claude/settings.json` that inspects every Bash tool call and blocks commands containing bypass flags. |
| 36 | |
| 37 | ### Configuration |
| 38 | |
| 39 | Add the following to your project's `.claude/settings.json`: |
| 40 | |
| 41 | |
| 42 | { |
| 43 | "hooks": { |
| 44 | "PreToolUse": [ |
| 45 | { |
| 46 | "matcher": "Bash", |
| 47 | "hook": { |
| 48 | "type": "command", |
| 49 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi" |
| 50 | } |
| 51 | } |
| 52 | ] |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | |
| 57 | ### How It Works |
| 58 | |
| 59 | **Matcher**: The hook targets only `Bash` tool calls, so it does not interfere with other tools (Read, Edit, Grep, etc.). |
| 60 | **Inspection**: The `$TOOL_INPUT` environment variable contains the full command the agent is about to execute. The hook uses `printf` to safely pass input (avoiding `echo` pitfalls with special characters) and checks for `--no-verify` or `--no-gpg-sign` flags only when preceded by a `git` command. |
| 61 | **Blocking**: If a bypass flag is found in a git command, the hook exits with code 2 and prints an error message. Exit code 2 signals Claude Code to reject the tool call entirely. |
| 62 | **Pass-through**: If no bypass flag is found, the hook exits with code 0 and the command executes normally. |
| 63 | |
| 64 | ### Exit Codes |
| 65 | |
| 66 | | Code | Meaning | |
| 67 | |------|---------| |
| 68 | | 0 | Allow the tool call to proceed | |
| 69 | | 1 | Error (tool call still proceeds, warning shown) | |
| 70 | | 2 | Block the tool call entirely | |
| 71 | |
| 72 | ## Blocked Flags |
| 73 | |
| 74 | | Flag | Purpose | Why Blocked | |
| 75 | |------|---------|-------------| |
| 76 | | `--no-verify` | Skips pre-commit and commit-msg hooks | Bypasses linting, formatting, testing, security checks | |
| 77 | | `--no-gpg-sign` | Skips GPG commit signing | Bypasses commit signing policy | |
| 78 | |
| 79 | ## Installation |
| 80 | |
| 81 | ### Per-Project Setup |
| 82 | |
| 83 | Create or update `.claude/settings.json` in your project root: |
| 84 | |
| 85 | |
| 86 | mkdir -p .claude |
| 87 | cat > .claude/settings.json << 'EOF' |
| 88 | { |
| 89 | "hooks": { |
| 90 | "PreToolUse": [ |
| 91 | { |
| 92 | "matcher": "Bash", |
| 93 | "hook": { |
| 94 | "type": "command", |
| 95 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi" |
| 96 | } |
| 97 | } |
| 98 | ] |
| 99 | } |
| 100 | } |
| 101 | EOF |
| 102 | |
| 103 | |
| 104 | ### Global Setup |
| 105 | |
| 106 | To enforce across all projects, add to `~/.claude/settings.json`: |
| 107 | |
| 108 | |
| 109 | mkdir -p ~/.claude |
| 110 | cat > ~/.claude/settings.json << 'EOF' |
| 111 | { |
| 112 | "hooks": { |
| 113 | "PreToolUse": [ |
| 114 | { |
| 115 | "matcher": "Bash", |
| 116 | "hook": { |
| 117 | "type": "command", |
| 118 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: --no-verify and --no-gpg-sign flags are not allowed. Run the commit without bypass flags so that pre-commit hooks execute properly.' >&2; exit 2; fi" |
| 119 | } |
| 120 | } |
| 121 | ] |
| 122 | } |
| 123 | } |
| 124 | EOF |
| 125 | |
| 126 | |
| 127 | ## Verification |
| 128 | |
| 129 | Test that the hook blocks bypass flags: |
| 130 | |
| 131 | |
| 132 | # This should be blocked by the hook: |
| 133 | git commit --no-verify -m "test" |
| 134 | |
| 135 | # This should succeed normally: |
| 136 | git commit -m "test" |
| 137 | |
| 138 | |
| 139 | ## Extending the Hook |
| 140 | |
| 141 | ### Adding More Blocked Flags |
| 142 | |
| 143 | To block additional flags (e.g., `--force`), extend the grep pattern: |
| 144 | |
| 145 | |
| 146 | { |
| 147 | "hooks": { |
| 148 | "PreToolUse": [ |
| 149 | { |
| 150 | "matcher": "Bash", |
| 151 | "hook": { |
| 152 | "type": "command", |
| 153 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign|force-with-lease|force)'; then echo 'BLOCKED: Bypass flags are not allowed.' >&2; exit 2; fi" |
| 154 | } |
| 155 | } |
| 156 | ] |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | |
| 161 | ### Combining with Other Hooks |
| 162 | |
| 163 | The block-no-verify hook works alongside other PreToolUse hooks: |
| 164 | |
| 165 | |
| 166 | { |
| 167 | "hooks": { |
| 168 | "PreToolUse": [ |
| 169 | { |
| 170 | "matcher": "Bash", |
| 171 | "hook": { |
| 172 | "type": "command", |
| 173 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE '(^|&&|;|\\|)\\s*git\\s+.*--(no-verify|no-gpg-sign)'; then echo 'BLOCKED: Bypass flags not allowed.' >&2; exit 2; fi" |
| 174 | } |
| 175 | }, |
| 176 | { |
| 177 | "matcher": "Bash", |
| 178 | "hook": { |
| 179 | "type": "command", |
| 180 | "command": "if printf '%s' \"$TOOL_INPUT\" | grep -qE 'rm\\s+-rf\\s+/'; then echo 'BLOCKED: Dangerous rm command.' >&2; exit 2; fi" |
| 181 | } |
| 182 | } |
| 183 | ] |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | |
| 188 | ## Best Practices |
| 189 | |
| 190 | **Commit the settings file** -- Add `.claude/settings.json` to version control so all team members benefit from the hook. |
| 191 | **Document in onboarding** -- Mention the hook in your project's contributing guide so developers understand why bypass flags are blocked. |
| 192 | **Pair with pre-commit hooks** -- The block-no-verify hook ensures pre-commit hooks run; make sure you have meaningful pre-commit hooks configured. |
| 193 | **Test after setup** -- Verify the hook works by intentionally triggering it in a test commit. |
| 194 |
Details
- Updated
- Sep 21, 2026
- License
- MIT
- Stars on the repo
- ★ 39,857
- Checked
- Source
- wshobson/agents ↗
- Creator
- wshobson · 179 listings
Similar skills
See all →
SkillAutomates CI/CD pipeline setupCI/CD and Automation
SkillAutomated semantic versioning and release workflowVersion Bump & Release Workflow
SkillOperate Orca-managed worktrees, folder contexts, terminalsOrca CLI
SkillThreaded messages, blocking ask/reply, task dispatchOrca Orchestration
SkillDeploy applications and websites to VercelVercel deploy
SkillOpen or update a pull request on pascalorg/editorOpen PRMore from wshobson
SkillMaster C/.NET backend development patterns for building
SkillImplement WCAG 2.2 compliant interfaces with mobileAccessibility compliance
SkillMaster Material Design 3 and Jetpack Compose patternsAndroid Mobile Design
SkillMigrate from AngularJS to Angular using hybrid modeAngular migration
SkillUnderstand anti-reversing, obfuscationAnti reversing techniques
SkillBuild production Apache Airflow DAGs with best practicesApache Airflow DAG Patterns