docs(security): ci netns, knowledge .git tmpfs, matrix id/secret split

Security fixes landed without updating the security-model docs; bring them
current as present-tense invariants:

- security.md: matrix identities are public / cross-agent-readable via
  GetAgentMeta while the token stays private; name validation extends to
  GetAgentMeta; the nix-build blast radius has a network dimension (hive-ci
  netns) alongside the 0600 token policy.
- boundary.md: the core dashboard /api has no app-layer auth — protection is
  the gateway plus network isolation; stated as a standing invariant.
- ci.md: hive-ci runs in its own private netns behind the bridge, reaches the
  forge via the gateway, and cannot reach host-loopback (dashboard/forge port).
- knowledge.md: /knowledge excludes .git via tmpfs so the core token in
  .git/config isn't readable by agents.

Refs #2308, #2310, #2313.
This commit is contained in:
sock 2026-07-10 17:04:31 +02:00 committed by mara
commit 6c95933775
4 changed files with 39 additions and 2 deletions

View file

@ -39,6 +39,13 @@ So a compromised/confused agent's reach on the forge or matrix is bounded by
_its own_ account's scope, not the swarm's. This is the main thing standing
between "one agent does something dumb" and "the whole hive is affected".
**Identity vs. secret (matrix).** The scoping is on the _secret_, not the
_identity_: an agent's matrix **token** is private to its own account, but its
matrix **identities** — the public handles (`name`, `user_id` `@user:server`,
`homeserver`) — are intentionally readable by any agent via `GetAgentMeta`, so
peers can find and address one another on a shared matrix instance. Only the
public handle crosses that boundary; the token never does.
### Threat model: prompt injection → confused deputy
The realistic adversary **never needs to breach the container**. They supply
@ -127,6 +134,11 @@ Defense-in-depth layers (in order):
dashboard renders anchors only for tokens that passed the same checks the
read endpoint enforces.
The same invariant holds wherever an agent-supplied name reaches a filesystem
path: the agent socket's `GetAgentMeta` validates `name` with
`validate_agent_name` before building `agent_notes_dir(name)`, so a `..`
component can't traverse.
## Nix builds and credential isolation
### Background
@ -143,6 +155,13 @@ Unsandboxed nix builds run as `nixbld` users (non-root, typically UIDs 30001-300
Without sandbox isolation, a build derivation's builder script has read access to
any file in the container that the nixbld user can read.
The blast radius also has a **network** dimension. hive-ci runs its unsandboxed
builds of untrusted PR code in its own private netns behind the hive bridge: a
build reaches the forge only through the gateway and cannot reach host-loopback
services — including the core dashboard at `127.0.0.1:<dashboard_port>`, which
has no application-layer auth of its own (see [`docs/ci.md`](ci.md)). The `0600`
token policy bounds file reads; network isolation bounds network reach.
**What is NOT exposed**:
- `/home/<name>/.claude/` — mode `0700`, owned by the per-agent