The permissions.allow and permissions.deny arrays control which tools Claude can use without asking.
Patterns are specific: "Bash" allows any bash command. "Bash(npm *)" allows only npm commands. "Edit" allows all file edits. You can write "Bash(git commit *)" to allow only that exact git operation.
Deny rules override allow rules, so if you allow "Bash" but deny "Bash(rm -rf *)", the rm command gets blocked.
permissions.defaultMode sets the fallback behavior. "default" means Claude asks for anything not explicitly allowed. "acceptEdits" auto-approves file changes. I'd configure permissions via /permissions in the CLI to see what's active before editing the file directly.