Skip to content

Instantly share code, notes, and snippets.

@iannuttall
Created July 23, 2025 07:39
Show Gist options
  • Save iannuttall/a7570cee412cc05d32d7a039830f28c7 to your computer and use it in GitHub Desktop.
Save iannuttall/a7570cee412cc05d32d7a039830f28c7 to your computer and use it in GitHub Desktop.
{
"permissions": {
"allow": [
"Read(**)",
"Edit(**)",
"MultiEdit(**)",
"Write(**)",
"Glob(**)",
"Grep(**)",
"LS(**)",
"WebSearch(**)",
"TodoRead()",
"TodoWrite(**)",
"Task(**)",
"Bash(git status*)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git show*)",
"Bash(git blame*)",
"Bash(git branch*)",
"Bash(git remote -v*)",
"Bash(git config --get*)",
"Bash(ls*)",
"Bash(cat *)",
"Bash(less *)",
"Bash(head*)",
"Bash(tail*)",
"Bash(grep*)",
"Bash(find*)",
"Bash(tree*)",
"Bash(pwd*)",
"Bash(wc*)",
"Bash(diff *)",
"Bash(sed -n*)",
"Bash(awk*)",
"Bash(cut*)",
"Bash(sort*)",
"Bash(uniq*)",
"Bash(basename *)",
"Bash(dirname *)",
"Bash(realpath *)",
"Bash(readlink *)",
"Bash(curl*)",
"Bash(jq*)",
"Bash(yq eval*)",
"Bash(python*)",
"Bash(python3*)",
"Bash(node*)",
"Bash(npm list*)",
"Bash(npm run*)",
"Bash(npx*)",
"Bash(black --check*)",
"Bash(black --diff*)",
"Bash(pylint*)",
"Bash(flake8*)",
"Bash(mypy*)",
"Bash(eslint*)",
"Bash(pytest*)",
"Bash(make test*)",
"Bash(npm test*)",
"Bash(make -n*)",
"Bash(man *)",
"Bash(pydoc*)",
"Bash(which *)",
"Bash(type *)",
"Bash(echo *)",
"Bash(printf *)",
"Bash(test *)",
"Bash(true*)",
"Bash(false*)",
"Bash(* | grep*)",
"Bash(* | jq*)",
"Bash(* | head*)",
"Bash(* | tail*)",
"Bash(* | wc*)",
"Bash(* | sort*)",
"Bash(* | uniq*)"
]
"deny": []
}
}
@normand1
Copy link

Very cool thanks! Ditto on the missing comma btw πŸ˜„

@vinta
Copy link

vinta commented Jul 23, 2025

You probably won't want to allow all of those tools since some of them could be dangerous.

Here is a more cautious but still convenient example (it assume you put all your code projects under ~/Projects):

{
  "permissions": {
    "additionalDirectories": ["~/.claude", "~/Projects"],
    "allow": [
      "Edit(~/Projects/**)",
      "Grep(~/Projects/**)",
      "Glob(**)",
      "LS(**)",
      "WebSearch(**)",
      "Bash(git add:*)",
      "Bash(git mv:*)",
      "Bash(git rm:*)",
      "Bash(git stash:*)",
      "Bash(git diff:*)",
      "Bash(git commit:*)",
      "Bash(ls:*)",
      "Bash(tree:*)",
      "Bash(pwd:*)",
      "Bash(which:*)",
      "mcp__ide__getDiagnostics"
    ],
    "deny": [
      "Read(~/.*)",
      "Edit(~/.*)",
      "Read(~/Library/**)",
      "Edit(~/Library/**)",
      "Read(~/Dropbox/**)",
      "Edit(~/Dropbox/**)",
      "Read(//etc/**)",
      "Edit(//etc/**)",
      "Bash(su:*)",
      "Bash(sudo:*)",
      "Bash(env:*)",
      "Bash(printenv:*)",
      "Bash(passwd:*)",
      "Bash(history:*)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(rsync:*)",
      "Bash(scp:*)",
      "Bash(sftp:*)",
      "Bash(socat:*)",
      "Bash(ssh:*)",
      "Bash(nc:*)",
      "Bash(ncat:*)",
      "Bash(netcat:*)",
      "Bash(nmap:*)",
      "Bash(git push:*)"
    ]
  },
  "env": {
    "DISABLE_BUG_COMMAND": "1",
    "DISABLE_ERROR_REPORTING": "1",
    "DISABLE_TELEMETRY": "1",
    "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1"
  }
}

@daehee
Copy link

daehee commented Jul 25, 2025

Thanks @vinta - that's helpful to see how you setup the deny rules.

@hexawulf
Copy link

hexawulf commented Jul 27, 2025

Here's my πŸ” Safe and Hardened ~/.claude/settings.json

🧠 Explanation of Key Changes
βœ… Still allowed:
Safe inspection tools: git, ls, cat, tree, head, tail
Static checks: black --check, flake8, mypy, etc.
Testing commands (pytest, make test) are kept but can be moved to deny if you want zero mutation.

❌ Now blocked:
rm, mv, cp, chmod, chown, dd β€” classic dangerous commands
curl, wget, python*, node*, npm run*, npx* β€” may pull or execute code
echo, printf β€” harmless alone but could be part of chaining to do damage
Bash(* | ) β€” blocks all generic pipelines like Bash( | jq*), which are too permissive

πŸ›‘οΈ Tips to Keep It Safe
Only allow commands with known, non-destructive flags (e.g., --check, -n, --dry-run)
Prefer exact matches over globs where possible
Avoid Bash() and Bash( | something) patterns unless scoped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment