DEV Community

hefty
hefty

Posted on

Your coding agent's worktree is not its security boundary

An agent opens a fresh worktree, completes a task, and hands back a diff. The files are separate. The result is easy to review. It's tempting to call that containment, but the worktree only separates where the task's edits go. It does not decide which other files the process can read, which credentials it can use, or where it can connect.

DeepSeek's dsh-superagent-prototype makes the distinction unusually explicit. Its README describes a research prototype that handles permitted GitHub requests (and optionally Feishu), gives work a separate session and directory, then returns results to the original thread. Its deployment guide describes the other half of that setup: the published presets use danger-full-access under the operator's OS account. The guide warns that account wrappers choosing default identities do not prevent the worker from reading the operator's home directory or invoking programs by path, and recommends a dedicated OS account for isolation.

That warning describes this prototype's documented presets, not every coding agent. It left me with a better deployment question than "does it use a worktree?": whose authority does the worker inherit?

Four controls that answer different questions

A session or worktree tells you where the agent's conversation and edits belong. A credential wrapper picks which account a particular integration uses by default. The OS identity and its runtime restrictions determine what a process can access when it runs. A human review gate tells you whether to accept the work it returns.

Those controls are related, but they aren't substitutes. A narrowly scoped GitHub token doesn't restrict access to a second credential already readable by the process. A clean diff can't show you everything the worker may have read during execution. Rejecting the PR afterward cannot undo a secret read.

The Reddit roundup keeps coming back to reachable credentials and broad tokens. Its incident accounts are author-curated, not a verified dataset, so I wouldn't turn its tally into a risk estimate. A DEV.to essay focuses instead on approvals and configuration trust. Those decisions matter too, but approving a plan does not restrict the OS process that executes it.

A preflight I'd run before the first task

This is a proposed review procedure, not a test I ran on the DeepSeek prototype or a universal sandbox recipe:

  1. Write down the account that will actually execute the worker, not just the GitHub identity it uses to post results. Identify the home directory and any other mounted paths visible to that account.
  2. Inventory the credentials and network destinations the task genuinely needs. Keep unrelated projects, personal credentials, and production access outside the worker's reach with enforceable account, mount, credential, and egress controls appropriate to the runner.
  3. In a disposable environment containing only synthetic files and tokens, try both an allowed access and a denied access under the same runner configuration planned for real work. Record the observed results. A declared policy is useful; a denied-action check tells you whether it is applied where this worker runs.
  4. After any preset change, compare a redacted before/after description of the effective account, mounts, credential scope, and egress rules. A text diff checker for redacted permission manifests can help spot changed lines; leave whitespace-ignore off when indentation might matter. Compare only sanitized or synthetic text, never live secrets or private configurations. A text diff reveals textual differences, not whether the policy enforces what you intended.

Then look at the returned patch and the checks the worker actually ran. Code review is still necessary. It just comes after the access boundary has already mattered.

Don't mistake a dedicated account for a finished sandbox

A separate OS account reduces what the worker can inherit from your personal account, which is why the prototype's deployment guide recommends one. Its value depends on the permissions, mounts, network access, and credentials you give it. A shared volume containing another project's secrets would weaken that separation; an unrestricted outbound path deserves its own review. The right setup depends on the job, and none of these steps is proof of complete containment.

For a small documentation task, a restricted runner may be easy to arrange. A task that needs package installs, external services, or customer data asks for a more deliberate exception process. If a proposed exception expands the boundary, review that expansion before launching the run, not only when a tidy PR arrives.

Before a run, find out what the agent could reach. Afterward, inspect what it changed. A worktree helps with the second question; don't let it answer the first by accident.

Source notes

Top comments (0)