Permissions: What to Automate, and What Never To
Permission prompts are friction, and friction gets disabled. A framework for deciding what runs unattended, based on reversibility rather than danger.
Permission prompts have a design problem: they interrupt you when you are concentrating, and the correct answer is "yes" often enough that you stop reading them.
That is not a hypothetical. It is how every security prompt in computing history has gone. Prompt often enough and you have trained a reflex, not a decision.
So the question is not "how much should I approve?" It is which decisions are worth your attention at all, and how to make the rest disappear without pretending they are safe.
Reversibility, not danger
The useful axis is not how dangerous an action sounds. It is how hard it is to undo.
Trivially reversible — reading files, searching, running tests, git status and diff. Worst case is wasted time. Automate freely.
Reversible with effort — editing files, creating files, local commits. Git makes these recoverable, provided the work was committed at some point. Automate within a project you control.
Reversible only with outside help — pushing to a shared branch, deploying, publishing a package, sending an email. Recoverable, but it involves other people, or the internet has already seen it. Approve individually.
Not reversible — dropping a production table, force-pushing over someone's work, deleting a cloud resource, sending to a mailing list. No undo. These should not be automatable at all, and the fact that a tool can do them is not a reason to let it.
Note that "dangerous-sounding" and "irreversible" come apart. rm -rf node_modules sounds alarming and costs a reinstall. git push --force sounds routine and can destroy work that exists nowhere else.
The line I actually hold
Two rules, and they are about outward-facing effects rather than technical risk:
Nothing leaves the machine without me asking for it. Publishing, deploying, emailing, posting. Not because those are technically dangerous, but because they are social — once content is on an external service it may be cached or indexed even if deleted, and the audience has already seen it. Approval in one context does not carry to the next: agreeing to deploy on Tuesday is not standing permission to deploy on Thursday.
Look before overwriting or deleting. Read the target first. This catches the case where a path is subtly wrong and the destination is not what anyone assumed. Cheap, and it is the check that prevents the worst outcomes.
Neither is about distrust. Both are about the fact that a plausible-looking wrong action executes exactly as smoothly as a right one.
Allowlists over blanket approval
The productive middle ground is allowing specific things you have verified, rather than approving broadly.
{
"permissions": {
"allow": [
"mcp__pencil"
]
}
}
The pattern that works: run normally for a couple of weeks, notice which prompts you approve every single time without thinking, and allowlist exactly those. Read-only shell commands are the usual candidates — ls, git status, git diff, test runners.
This is better than a blanket setting because the surface stays small and legible. You can read your allowlist and understand what you have agreed to. A single "allow everything" flag has no such property.
Project-level settings help here too. A repo you own can allow more than a client's production infrastructure. Same tool, different blast radius, different rules.
About the dangerous flag
There is a setting that skips the confirmation for permissive modes. Mine is on:
{ "skipDangerousModePermissionPrompt": true }
Being straight about what this is: it removes a speed bump, not a wall. It is defensible in a disposable environment — a container, a scratch repo, a worktree you are about to throw away.
It is not defensible with production credentials in the environment. And the honest risk is not that you will make a bad decision. It is that you will forget which mode you are in, because the reminder is exactly what you disabled.
If you turn something like this on, make your prompt or status line show the mode. Removing a confirmation is fine. Removing the signal is what gets people.
The one nobody thinks about
A prompt is not the only way instructions reach your assistant. Content it reads is another.
If it fetches a web page, reads an email, or opens a shared document, that content enters context. Text shaped like an instruction inside a fetched document is still just text in a document — but a system that reads a page and then acts on what the page says has a real problem.
This is why the earlier point about MCP servers reading other people's content matters more than it first appears. Your own notes are one thing. A shared drive where anyone can drop a file is another.
Practical version: treat fetched content as data. If something read from an external source seems to be asking for an action, that is a red flag, not an instruction.
What I would tell someone starting
Do not configure permissions up front. You do not yet know which prompts are noise and which are the ones that will save you.
Run with defaults for two weeks. Keep a note of prompts you approve reflexively. Allowlist those, specifically. Leave everything else prompting.
You will end up with a short allowlist of read-only operations and prompts on everything that writes or reaches the network — which is roughly the right answer, arrived at from evidence rather than from a blog post.
Next: something concrete. Building a print-perfect A4 PDF page in Nuxt, and every way the browser fights you.
Need a developer who ships fastwithout shipping mess?
I build and maintain WordPress, Laravel and Nuxt applications for businesses that care about performance and maintainability.