Back to catalogue
SecurityPermissionRequest
Auto-approve read-only permissions
Stop clicking approve on harmless reads
Automatically approves permission requests for read-only operations (Read, Glob, Grep, safe Bash commands) without manual intervention.
What does the Auto-approve read-only permissions hook do?
Auto-approve read-only permissions is a Claude Code PermissionRequest hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Stop clicking approve on harmless reads.
As a PermissionRequest hook it runs before the action completes, so it can block or adjust what Claude is about to do. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.
Use cases
- Reduce interruptions for non-destructive operations
- Automated security policy based on command safety
Tags
#permission#security#auto-allow#readonly#policy
settings.json fragment
{
"hooks": {
"PermissionRequest": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/permission-auto-allow.mjs",
"type": "command"
}
],
"matcher": ""
}
]
}
}Script · .claude/hooks/permission-auto-allow.mjs
#!/usr/bin/env node
// @hookstack permission-request-auto-allow-readonly
// Auto-autorise les outils lecture seule et les commandes Bash sûres (PermissionRequest)
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
const SAFE_BASH = [
/^ls/,
/^pwd/,
/^echo/,
/^cat(?!.*>)/,
/^head/,
/^tail/,
/^wc/,
/^which/,
/^whereis/,
/^file/,
/^stat/,
/^git\s+(status|log|diff|show|branch|tag)/,
/^npm\s+(list|ls|outdated|view)/,
];
const READ_ONLY_TOOLS = ["Read", "Glob", "Grep"];
export function run(input) {
const toolName = input.tool_name || "";
const toolInput = input.tool_input || {};
let allow = READ_ONLY_TOOLS.includes(toolName);
if (!allow && toolName === "Bash") {
const cmd = (toolInput.command || "").trim();
allow = SAFE_BASH.some((p) => p.test(cmd));
}
return allow
? {
hookSpecificOutput: {
hookEventName: "PermissionRequest",
decision: { behavior: "allow" },
},
}
: null;
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, "utf8"));
const result = run(input);
if (result) process.stdout.write(JSON.stringify(result));
}
Learn more
Related hooks
- Secret detection before Bash executionCatch a leaked API key before it ever runs
- Destructive command blockingStops a disk-wiping shell command before it runs
- Sensitive file write protectionYour .env and keys stay untouched by the agent
- Lock file write protectionLock files stay intact - package manager only