Merge pull request 'Issue 344: the known gaps in the agent's boundary, accepted for now' (#244) from issues/344-known-gaps-in-the-agents-boundary into main

This commit was merged in pull request #244.
This commit is contained in:
2026-10-09 11:59:23 +00:00
@@ -0,0 +1,107 @@
---
status: open
opened: 2026-10-09
located-in: []
fixed-by:
amended-design:
---
# 344. Known gaps in the agent's boundary, accepted for now
## Symptom
Three reviews on 2026-10-09 checked whether an agent can become root or approve in the operator's name. They
covered ADR 0266 (agents on the control-node run under an account of their own), the root routes found beside it,
and ADR 0259 (the operator's answers on any channel). Most findings are being fixed in the pull requests those
records name. The gaps below are **not** being fixed now.
The operator decided on 2026-10-09: *"that's not too big of an issue, i kind of trust you to not do weird stuff all
of a sudden. We can improve security later on, you should note down the known gaps though."* This issue is that
note. Each gap says what is open, why it matters, and what would close it.
## The gaps
1. **On every machine but the control-node, agents run as the operator, with passwordless sudo.** ADR 0266 gives
agents an account of their own on the control-node only. On the laptop, the workstation and the home server, an
agent session holds everything the operator's account holds, root included.
*Closes with:* a follow-up decision that extends ADR 0266 to every node where agents run.
2. **Tools that run a caller's command as the operator remain on those machines.** These are the login shell's
`execute` (withheld on the control-node by [ADR 0268](../../02-DECISIONS/0268-the-login-shells-execute-is-withheld-on-the-control-node-until-a-call-to-it-needs-a-persons-approval.md)),
the launcher's `run` and the terminal emulator's `open`. Through any of them, an agent reaches root on that
machine.
*Closes with:* `execute: withhold` mesh-wide once the operator's command exists (issue 343), and the
approval mark of [research 039](../../01-RESEARCH/039-a-tool-that-needs-a-persons-approval/00-overview.md)
for the other two.
3. **The operator's chat client runs on a machine where agents run as the operator.** An agent there can focus the
desktop client and tap Approve. Telegram then authenticates the tap as the operator, and the router issues a
genuine warrant. The client's data directory was also found readable by every account (directories 755, files
644), so another account could copy the logged-in session.
*Closes with:* gap 1 on that machine; no agent access to the operator's display; the client's data kept 0700.
4. **One X display gives its clients no isolation.** Any program with access to the operator's display can read
other windows and send them input.
*Closes with:* agents' accounts get no access to the operator's display (no X authority cookie).
5. **The acts a warrant authorises can still be called directly, as verbs.** Release, stop, a plan's go and stop, a
service restart and silencing a condition all remain open to any agent through a tool runner. So "the mesh does
this only on approval" does not hold yet.
*Closes with:* the approval mark of research 039, which withholds those verbs from agents.
6. **The tool runner on the control-node runs as the operator** and can read the forge administrator's password
file. A future tool that reads a path the caller chooses could leak it.
*Closes with:* the tool runner under an account of its own; secrets read only by the module that owns them.
7. **The forge's tools still use a site administrator's token.** The tools' own guards refuse admin and
protection-weakening calls. The account itself could do more, because the forge puts protection edits under the
repository scope.
*Closes with:* a non-administrator forge account for the tools, with write access through a team.
8. **The controller's credential can rewrite the router's record** (identities, asks, the hour after a link). The
router itself enforces the hour, but its record is only as safe as the controller.
*Closes with:* the router's state in a bucket only the router may write.
9. **On a large data pool the root search may never finish.** The node-engine's search for programs that run as
root now has one bound of fifteen minutes (`mesh-host` #61; the inner two-minute limit is gone). On a machine with
a very large data pool the walk can still run past it, and the verdict then stays "not judged". That is loud,
not silent.
*Closes with:* setuid turned off on the data datasets, so the walk skips them.
10. **An agent can merge its own pull request.** No mesh repository's main requires an approval on the forge
(`required_approvals: 0`), and the forge tool merges as the forge's administrator once the required checks are
green. An agent can therefore change a module that runs on every node, open the pull request, wait for the
checks and merge it, and the controller walks the change out. The checks judge whether every machine still
composes, not what the change is for. The operator's yes in a session is a convention, and nothing checks it.
*Closes with:* a merge that needs the operator's own approval: a required approval on the forge from the
operator's personal account only, or an approval through ADR 0259's asks. That holds only when the forge's
tools cannot act as another user (gap 12) and cannot post an approving review themselves.
11. **Any caller of the mesh's tools can see the operator's screen.** The display server module's tools answer every
window's title, which can hold a mail subject or a chat's name, and can return a screenshot as data over the bus
(mesh-catalog #154). A session on another machine needs no access to the display to read it.
*Closes with:* the approval mark of research 039 for screenshot and window-listing tools, or limiting them to
the operator's own sessions.
12. **The forge's tools can act as any forge user.** The tools' token belongs to a site administrator, and the
forge lets an administrator act as another user by adding `sudo=<user>` to a call. The generic API tool passed
that query on unchanged. Measured on 2026-10-09: a read through the tool with `sudo` set to the operator's
account answered as the operator. An agent could therefore post comments, pull requests and approving reviews
as the operator. The operator's own forge account is also a site administrator, so acting as it is acting as
an administrator.
*Closed* on 2026-10-09 by mesh-catalog #153: the tools send only a known list of query keys, never `sudo`, and
every caller-supplied path segment is checked, so `..` cannot reach another endpoint. A non-administrator account
for the tools (gap 7) remains.
13. **The forge applies only the first protection rule that matches a branch.** A rule named for the branch comes
before a glob rule. A weak rule named for a branch next to a strong glob would leave the branch weakly protected,
while a reader that asks "does any rule protect it" sees it as protected. No repository has such a pair today
(every rule is named `main`), and the tools refuse to create one.
*Closed* on 2026-10-09 by mesh-controller #177: the build-source check judges the first matching rule, as the
forge does.
## Why it is an issue
Each gap is a known way around a rule the mesh states. A gap that is written down can be weighed and closed. A
gap that is forgotten turns into a belief that the rule holds. This issue stays open until every gap above is
closed or decided against in writing.