Coding agent permissions: modes, allow and deny rules

OHarness checks every tool call against allow, ask and deny rules and then a permission mode. deny beats everything — including bypass mode — so an explicit refusal is the one boundary you can rely on.

Updated

Cette page est rédigée en anglais. Les termes qu'elle explique sont ceux que l'on cherche en anglais, et un terme technique traduit est un terme différent.

The five modes

ModeBehaviour
default (Manual)Ask before anything that changes state
acceptEditsFile edits pass, everything else asks
planRead-only; every change is refused
autoEdits and routine commands pass, risky ones ask
bypassPermissionsApprove everything — except what a deny rule forbids

Pick one with /mode in a session or --permission-mode on the command line. auto is a judgement about cost, not a security check: it measures blast radius (rm, sudo, git push, kubectl, npm publish, writes outside the project) and asks about anything it does not recognise as routine.

Rules

Rules match the tool name, or a Tool(argument) form with wildcards:

{
  "allow": ["Bash(npm run test:*)", "mcp__github__get_*"],
  "ask":   ["Bash(git push*)"],
  "deny":  ["Bash(rm -rf *)", "write(.env*)"]
}

Where rules live

ScopeFileFor
user~/.oharness/settings.jsonA personal habit
project.oharness/settings.jsonBelongs to the repository, reviewable
local.oharness/settings.local.jsonThis checkout only, gitignored

Denials accumulate across scopes and are never overridden, so a project can forbid what a user allowed globally. "Always allow" in a prompt writes the most specific pattern — approving Bash(npm test) does not grant every Bash(...). /permissions shows the rules in force.

What a permission system is not

The writable-roots check (workspaceMode) refuses paths outside the project before asking, but it inspects arguments; it does not confine the process. A shell command can reach anything you can. For real confinement, run the agent in a container or VM and treat rules as a guard against mistakes.

Common questions

How do I stop a coding agent from running dangerous commands?

Add deny rules. In OHarness, a rule such as "deny": ["Bash(rm -rf *)", "Bash(git push*)"] refuses those commands in every mode, including bypassPermissions. Deny rules are the boundary; modes are convenience.

Does bypass mode ignore deny rules?

No. In OHarness, deny beats everything, including bypassPermissions. An explicit refusal is the one rule a user can rely on absolutely.

Can a repository set permissions for everyone who uses it?

Yes. Rules in .oharness/settings.json are committed with the project. Denials from any scope accumulate, so a project can forbid something even if a user allowed it globally.

Related