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:
@@ -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.
|
||||
Reference in New Issue
Block a user