Claude Code: my permissions whitelist
Peter Hartree
Claude Code can work autonomously for minutes, even hours. But not if it's constantly asking for permission to act. Just like a human, you need to trust it (but not too much).
If you find this post hard to follow, you should probably be using Claude Cowork, not Claude Code.
Global whitelist
You can whitelist actions in a particular project folder, or globally. Here's my current global whitelist:
{
"permissions": {
"allow": [
// Core tools
"Bash", // !!! — See note below
"Write",
"Edit",
"Glob",
"Grep",
"Read",
"NotebookEdit",
// Web access
"WebSearch",
"WebFetch(domain:github.com)", // See note below
"WebFetch(domain:raw.githubusercontent.com)",
"WebFetch(domain:wow.pjh.is)",
"WebFetch(domain:hartreeworks.org)",
"WebFetch(domain:youtube.com)",
// Google Workspace MCP (read-only)
"mcp__google_workspace__get_events",
"mcp__google_workspace__list_calendars",
"mcp__google_workspace__get_doc_content",
"mcp__google_workspace__search_docs",
"mcp__google_workspace__list_docs_in_folder",
"mcp__google_workspace__inspect_doc_structure",
"mcp__google_workspace__debug_table_structure",
"mcp__google_workspace__read_document_comments",
"mcp__google_workspace__list_spreadsheets",
"mcp__google_workspace__get_spreadsheet_info",
"mcp__google_workspace__read_sheet_values",
"mcp__google_workspace__read_spreadsheet_comments",
"mcp__google_workspace__search_drive_files",
"mcp__google_workspace__list_drive_items",
"mcp__google_workspace__get_drive_file_content",
"mcp__google_workspace__get_drive_file_download_url",
"mcp__google_workspace__get_drive_file_permissions",
"mcp__google_workspace__check_drive_file_public_access",
"mcp__google_workspace__get_drive_shareable_link",
"mcp__google_workspace__search_gmail_messages",
"mcp__google_workspace__get_gmail_messages_content_batch",
"mcp__google_workspace__modify_gmail_message_labels",
// Mobile MCP (read-only)
"mcp__mobile__list_devices",
"mcp__mobile__screenshot",
"mcp__mobile__get_ui",
"mcp__mobile__find_element",
"mcp__mobile__get_current_activity",
"mcp__mobile__get_logs",
"mcp__mobile__get_system_info",
"mcp__mobile__wait",
// Skills
"Skill(project-management:*)",
"Skill(plugin-dev:*)",
// ... and nearly all my other skills.
]
}
}
The bash safety hook
Whitelisting bash is a bold move—bash commands can do more or less anything.
I mitigate that with a PreToolUse hook that:
- Hard blocks
rm,shred,unlink,find -deleteand forces Claude to usetrashinstead. - Prompts for permission on potential RCE vectors, exfiltration attempts, and persistence mechanisms.
In ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bun run ~/.claude/hooks/bash-safety/index.ts"
}
]
}
]
}
}
And the safety script is here. I'm keen for ideas on how to improve it.
Git security
My claude.md also says:
## Git security
Only clone repositories (`git clone`, `gh repo clone`) that the user has
explicitly requested by URL or name. If a task seems to require cloning
a repo the user hasn't specifically mentioned, ask first before cloning.
Recovery from accidental deletion
Use version control
Most of my work is version controlled with Git. If something untoward happens, just restore from history.
Use trash, not rm
The trash command sends files to your Trash folder instead of deleting them permanently. This enables recovery if you're not already tracking files in git.
The safety script blocks rm commands, pausing execution and telling Claude to use trash instead. But ideally Claude just uses trash directly. So I tell Claude about this in my global ~/.claude/CLAUDE.md:
## Required
- **NEVER use `rm -rf`**—it's blocked by the command-validator hook for safety
- Use `trash` instead: `trash folder-name` or `trash file.txt`
- Works exactly like `rm -rf` but moves to Trash instead of permanent deletion
Continuous backups
Backblaze continuously backs up my work, keeping version history forever. So, if Claude actually deletes something I care about, it'll be recoverable.
How to implement
If you want something like this, just paste the link to this blog post into Claude, and ask Claude to implement it.
