Skip to main content
Working with an agent? Give them a link to this page as markdown.

Hardening dev containers

The standard dev container example is for a cooperative development environment. Watcher and the coding agent run as the same user. The container can read the host's Watcher sign-in. A process in the workspace can stop Watcher, edit the agent hooks, read the shared credentials, or call the local Watcher API.

Do not use that example as a security boundary against code running in the workspace. If the workspace is untrusted, design the boundary around your container platform, agent configuration, and authentication requirements.

Choose the boundary first​

Decide which components are trusted before adding container controls:

  • The Docker host controls the whole deployment. Anyone who can change the image or Compose definition also controls the whole deployment.
  • Repository code controls dev container lifecycle commands. This applies unless those files are protected by policy outside the repository.
  • Agent hook input comes from the workspace. Treat it as untrusted.
  • A developer can always start a different, unmonitored agent. This applies unless launch is controlled outside the workspace.

Container hardening can restrict an unprivileged workspace process. It cannot protect against the Docker host. It cannot protect against the image builder. It cannot protect against the repository administrator.

Design options​

You can combine the following controls into a stronger deployment. They are design guidance. They are not a copyable hardened template.

ConcernPossible controlRemaining limitation
Watcher credentials and stateRun Watcher in a separate sidecar. Give only that sidecar its credentials and state volume.The container host can still inspect both containers.
Hook integrityInstall root-owned managed hooks in the image. Enable each agent's managed-hooks-only setting.The deployment must pin agent versions that enforce those settings. Test those versions.
Process isolationUse separate PID and network namespaces. Drop Linux capabilities. Remove passwordless sudo. Do not mount a container-runtime socket.Both containers still depend on the host kernel and configuration.
Communication with WatcherExpose a narrow Unix socket that accepts only known hook events. Do not expose the full local API.The relay becomes security-sensitive code. It needs its own validation and resource limits.
Transcript accessPass bounded snapshots for the current hook. Do not mount the repository or agent home into the Watcher sidecar.Snapshot selection must reject symlinks. It must reject path escapes, oversized input, and unexpected file types.
AvailabilityCheck Watcher and relay health. Restart failed services. Decide which permission hooks should fail closed during an outage.Lifecycle events can still be missing during an extended outage.
Artifact integrityPin Watcher and agent versions. Verify downloaded checksums. Make protected image paths read-only.Anyone allowed to rebuild or replace the image remains trusted.

Runtime reliability​

The standard example checks that Watcher starts. Then it leaves Watcher running in the background. A deployment that needs stronger runtime guarantees can:

  • supervise the Watcher process and restart it after repeated health failures;
  • check authentication separately, then warn or block according to local policy; and
  • reinstall hooks after agent changes and verify that a real session reaches the Analyzer.

Failing closed improves monitoring coverage. However, it turns a Watcher outage into a development outage.

Authentication​

Do not pass the desktop credential directory into an untrusted workspace. A sidecar can use a separate browser sign-in or its own watcher login. An unattended deployment can use an organization API key with only the permissions it needs (see Signing in without a browser). Keep either form of authentication out of the workspace container.

Reusing the desktop sign-in is appropriate for the standard example. The example assumes the workspace is trusted and keeps setup small. It is not compatible with a boundary that prevents workspace processes from reading Watcher credentials.

Validation​

Test the finished deployment against its threat model. At minimum, verify that the workspace cannot do the following:

  • read Watcher credentials or state;
  • replace or disable managed hooks;
  • signal the Watcher process or reach its control API;
  • modify the relay or its socket directory;
  • mount the Docker or containerd socket; or
  • make permission-bearing hooks continue silently when Watcher is unavailable.

Also run an agent turn and confirm the session reaches the Analyzer. Isolation checks do not prove that authentication works. They do not prove that hook discovery works. They do not prove that upload works.