skribbl
productpricingfree!questionswriting
download
concepts · 7 August 2026 · 9 min read

Who may command whom: permissions for coding agents

Two permission questions. Most setups only answer the first one.

skribbl/writing/concepts
authority, written down

Once there is more than one agent, two permission questions appear: what each one may do to the repository, and which of them may instruct the others. Most setups answer the first and leave the second implicit. What goes wrong when authority is inferred rather than authored, and how to write it down.

two questions, not one

The moment you run more than one coding agent, permission splits into two questions that are usually treated as one: what may this agent do to the repository, and which agent may tell which other agent what to do. The first is capability, and every agent harness has some answer to it, whether that is an approval prompt, an allowlist of tools, a sandbox or a permission mode. The second is authority, and most setups have no answer to it at all, because with a single agent the question does not arise. It arises the instant there is a second one.

The confusion is understandable: both questions are about what an agent is allowed to do, and the word "permissions" gets used for both. But they fail differently, they are enforced in different places, and a setup that answers the first perfectly can still let a confused agent send three others off to rewrite something nobody asked about. This post is mostly about the second, because it is the one with no default.

CAPABILITYwhat an agent may do to the world: files, commands, network, migrations
AUTHORITYwhich agent may instruct, interrupt or hand work to which other agent
ENFORCED BYcapability: the harness. authority: whatever sits between the agents
FAILS AScapability: an agent did something. authority: an agent was told to

capability: what an agent may touch

Capability is the better understood half, so it gets the shorter section. What is worth noticing is that it decomposes into three axes people routinely collapse.

Where it may write

The single highest-value capability boundary in multi-agent coding is not a tool allowlist, it is a directory. Give each agent its own git worktree on its own branch and a large class of problems stops existing, because two agents can no longer write the same file at the same time. The worktree post covers the mechanics. Everything else in this section is a smaller lever than that one.

What it may run

An agent that may run the test suite is a different animal from one that may run a database migration, push a branch or install packages. Harnesses express this differently: approval prompts per call, permission modes chosen at launch, sandboxes that deny by default. The unglamorous advice is to set the mode when the agent is created rather than negotiate it later, because twenty minutes of answering "yes" to prompts trains you to stop reading them.

What happens around it

Some harnesses let you interpose on tool calls with your own code. Claude Code fires shell hooks at named points, including before a tool runs, and an exit code from that hook can block the call; the hooks guide works through the events and payloads. This is how a capability policy stops being a setting and becomes logic you can write. It is also where policy goes badly wrong: a hook that fails closed blocks a tool call because your script had a typo, so a hook inside a permission boundary needs to be as boring and as tested as the boundary itself.

authority: which agent may command whom

Now the second question. Once agents can pass messages, three things become possible, and they need separating because they carry different risk:

  • Dispatch. Agent A gives agent B a task. B does work it did not choose. This is the one that needs governing, because it converts one agent's mistake into another agent's commits.
  • Report. Agent B tells agent A what it found. Low risk in itself: information flowing back to a coordinator changes nobody's behaviour except by persuasion.
  • Share. Agent A hands agent B context: a plan, a finding, a file. Between those two, roughly as risky as what the context contains, which is more than people assume once you remember that context is where injected instructions live.

Each of these is directional. "A and B are connected" is not a permission, it is a topology note. The permission is "A may dispatch to B," and it does not imply the reverse. A supervisor with three workers has three dispatch grants going out and three report grants coming back, and collapsing those six facts into three undirected edges hands every worker the ability to command the supervisor. That is the most natural bug to write, because an undirected edge is the easier data structure.

The default has to be deny. If any agent may instruct any other because they all happen to be running under the same process, you do not have a permissive authority model, you have the absence of one, and the difference shows up the first time an agent misreads a plan file. The topologies this all sits inside are laid out in the orchestration definition; the point here is narrower, which is that a topology and a permission model must be the same object or they will disagree.

why inferring authority is a bug, not a convenience

There is a tempting shortcut available to anyone building a multi-agent tool, and it is worth naming precisely so it can be refused: derive authority from something you can already see. The agents are laid out on a screen, so treat the one above as the supervisor. They are in a directory tree, so treat the parent as the coordinator. They were created in an order, so treat the first as the lead. Every one of these is cheap to implement and every one of them is wrong for the same reason.

An inferred permission changes when the thing it was inferred from changes, and those things change for reasons that have nothing to do with permission. You move a node because two labels were overlapping. You rename a directory. You restart a session in a different order. None of those are decisions about who may command whom, and all of them silently rewrite the answer.

We have a first-hand version. In Skribbl, authority between agents is granted by drawing a link, and each link carries a direction saying which way commands may flow. For a while three separate places in the code recomputed that direction from where the two nodes happened to sit, and one of them ran inside the handler that fires while you drag. Dragging an agent above another silently changed who could command whom. Nothing looked broken: the links were still there, the diagram was still accurate as a diagram, and the permission it encoded had quietly inverted.

The fix was not a better inference, it was deleting the inference. The gesture that creates the link authors the direction once, the value is stored, and geometry is never consulted again. Exactly one caller may still derive direction from position, a one-time migration for canvases saved before the field existed. A second caller would reintroduce the bug, which is why the constraint is written down rather than remembered.

The general form: a permission must be authored by a deliberate act and stored as data. If you can point at the moment a person granted it, and at the record that resulted, you have a permission. If you can only point at a rule that computes it from state, you have a derived value that will change under you.

authoring it instead

What replaces inference is unromantic: a list of grants, each a fact somebody deliberately created. The shape is the same whether it lives in a config file, a database row or a line drawn between two nodes.

grant := (from_agent, to_agent, verb, created_by, created_at)

verb  := dispatch | share | report

# a supervisor with two workers, written out in full
(lead,    worker_a, dispatch)
(lead,    worker_b, dispatch)
(worker_a, lead,    report)
(worker_b, lead,    report)

# note what is absent: worker_a cannot dispatch to worker_b,
# and neither worker can dispatch to lead.

Three properties are worth insisting on, and each goes wrong in practice.

  • It is enumerable. You can print the list. A permission model you cannot render as a finite list of facts is one nobody will audit, and an unaudited permission model only ever gets more permissive.
  • It is checked at the moment of the message, not at setup. Grants change while agents are running. A check performed when the fleet was created is a check against a world that no longer exists.
  • It is bounded against recursion. Two agents that may each dispatch to the other can hand work back and forth indefinitely, spending real money the entire time. A hop cap on chains of delegation is the cheapest possible fix, and the interaction with spend is direct enough that the token budget post is worth reading alongside this one.

The verb matters as much as the pair. A grant that says "A may talk to B" without saying what kind of talking is permitted collapses report into dispatch, and reporting is the one you want liberally granted while dispatch is the one you want scarce.

revocation is the real test

Anyone can grant. The question that separates a permission model from a configuration format is what it costs to take a grant back, and there are three properties to check.

It must be as cheap as granting

If creating a link takes one gesture and removing it takes finding a config file, remembering a syntax and restarting the fleet, the model drifts open. Permissions accumulate, and after two weeks every agent can command every other agent because no individual action was expensive enough to prevent it.

It must be visible

You should see the current grants without running a command, ideally while looking at the agents themselves. A permission model in a file you have to open is one you check when you are already suspicious, which is too late.

It must apply to work in flight

Revocation that only affects future sessions is not revocation. The moment the grant goes, the next message that tries to cross it has to be dropped, and dropped loudly enough that you can tell a permission working from a delivery failing.

There is a nice property in tying all three to the thing you already look at. If the picture of your fleet and the enforcement of its permissions are the same object rather than two representations that need syncing, they cannot disagree, and an out-of-date architecture diagram stops being possible. That is the design bet behind how our own tool differs from the tab-list and kanban shapes. It is a bet and not a proven result: it makes the permission model impossible to ignore, which helps only if you would otherwise have ignored it.

what this buys you under attack

Everything so far assumed honest mistakes. The case sharpens when you assume dishonest input, and coding agents read a great deal of input they did not choose: issue text, dependency README files, web pages fetched mid-task, the output of a tool that fetched something else.

Prompt injection is not solved and an authority model does not solve it. What it does is bound the blast radius. An agent talked into doing something stupid, holding no outbound dispatch grants, wastes its own turn inside its own worktree. The same agent with unrestricted delegation can direct every other agent you are running, and each of those will be executing instructions that look, from inside their own context, like they came from a colleague.

Two rules follow, both about the shape of the grant graph rather than about detection.

  • Agents that read untrusted input should not hold dispatch grants. Let the agent that scrapes, fetches or reads issue text report its findings upward. Let a different agent decide what to do about them.
  • Grants should be scarce enough to enumerate out loud. If you cannot say the whole list in a sentence, you cannot reason about what a compromised member of it could reach.

None of that is a security guarantee and should not be sold as one. It is the difference between a bad afternoon confined to one branch and a bad afternoon spread across four: real, and modest. The broader set of ways this goes wrong is in why multi-agent coding fails.

common questions

What is the difference between agent permissions and agent authority?

Permissions, or capabilities, describe what an agent may do to the world: which files it may write, which commands it may run, whether it may reach the network. Authority describes which agent may instruct which other agent. Answering the first does not answer the second, which is why a setup with careful tool allowlists can still have one agent sending three others off on work nobody asked for.

Can one AI coding agent give instructions to another?

It can if something in your setup lets it, and in most setups that something is implicit rather than written down. A safe design requires an explicit, directional grant for each pair before any message passes, with deny as the default. Direction is not optional: a supervisor being able to dispatch to a worker must not imply the reverse.

Why should agent authority not be inferred from layout or proximity?

Because inferred authority changes when the thing it was inferred from changes, and layout changes for reasons that have nothing to do with permission. Tidying a screen, renaming a directory or restarting sessions in a different order must never alter who may command whom. Authority should be authored by a deliberate act and stored as data, so the moment it was granted is something you can point at.

How do you revoke one agent's authority over another?

By deleting the specific grant, in one action, with the effect visible immediately and applied to work already in flight. If revocation takes more steps than granting did, the permission model will drift open over time, because permissions accumulate whenever removing one is more expensive than leaving it. Revocation that only affects the next session is not revocation.

Does an authority model protect against prompt injection?

It does not stop an agent from being manipulated, but it bounds what a manipulated agent can reach. An injected agent with no outbound grants wastes its own turn in its own worktree; the same agent with unrestricted delegation can direct every other agent you are running, and none of them can tell that instruction from a colleague's. Keep dispatch grants away from agents that read input you did not write.

If you want the practical setup rather than the model, the parallel-agent guide covers worktrees, branches and merge order at how to run agents in parallel, and the docs describe how drawn links and their directions work in practice.

READ NEXT
Why multi-agent coding fails, and the four fixesFour failure modes, four structural fixes, and the one nobody has solved.10 minClaude Code hooks: a practical guide with examplesEvery event, the payload it carries, and the exit code that blocks a tool call.12 minWhat is AI agent orchestration? A working definitionFour topologies, five problems, and an honest account of which one to reach for first.9 min
ON THIS PAGE
two questions, not onecapability: what it may touchauthority: who may command whomwhy inferring authority is a bugauthoring it insteadrevocation is the real testwhat this buys you under attackcommon questions
run them on a canvasSkribbl puts every agent, its terminal and what it is spending on one board. macOS, one day free.

get the next one by email.

One email when there is something worth reading. Unsubscribe is one click and it is in every issue.

get me
productpricingdocsquestionswhat it iscomparereleaseswritingnewsletterlaunchesprivacycancel
give them infinity.© skribbl