---
title: "Chapter 09: Isolation Before Autonomy"
description: "Build and verify a disposable worker boundary before granting unattended shell access."
type: "lesson"
order: 9
chapter: "03-controlled-agents"
duration: "45–90 minutes"
---

# Chapter 09: Isolation Before Autonomy

## Objective

Build and verify a disposable worker boundary before granting unattended shell access.

Your tutor should stop at each gate and wait for your evidence before continuing.

## Concept

The worker’s allowed damage should be smaller than the value of the machine you use every day. A Git branch protects review history; it does not protect files outside the checkout. A worktree shares repository metadata. A container shares the host kernel and can become host-equivalent through privileged mode, mounts, or a Docker socket.

For this course, use a disposable Linux VM with a separate unprivileged worker account. A human administrator installs the toolchain and applies network policy before agent execution. The agent gets the toy checkout and one scoped model credential. It gets no production data, organization-wide Git token, SSH agent forwarding, cloud role, host home mount, or deployment secret.

Model access implies some network access. Egress policy must therefore live outside the agent account. Allow the provider endpoints you actually use; deny instance metadata, internal networks, and other destinations where feasible. Establish cache/package downloads during preparation, then restrict runtime egress. Exact endpoints depend on the provider and authentication route; verify them rather than pasting a guessed universal firewall rule.

## Concept check

**Q1.** What makes a writable Docker socket dangerous?

**Q2.** Why is a patched Git that removes force-push insufficient as the only control?

<details>
<summary>Concept answer key — attempt first</summary>

## Answer key (concept)

**Q1.** It can grant control over the host through the daemon. **Pass criteria:** identify host authority, not merely container access.

**Q2.** Other binaries or HTTP calls can still reach Git hosting APIs with the same credential. **Pass criteria:** enforce permissions at the remote service too.

</details>

## Gate: Provision the boundary

Choose an existing cloud account and a Linux VM size you are willing to pay for. A modest development VM is enough for the Python/PostgreSQL lab; the final nested-VM test needs hardware virtualization support. Set an external expiry and budget alert before provisioning. Do not expose application or database ports to the public Internet. Limit SSH ingress to your administrative source.

As the administrator, create an unprivileged worker account with its own home directory. Install Nix and devenv, prepare the checkout and caches, and then verify the worker has no administrative privilege. Keep the original acceptance tests and expected source commit on the owner’s machine.

This is intentionally a provider-neutral gate: show your tutor the actual VM, network, identity, and lifetime settings. A provider-specific one-click script would hide the authority decisions we need you to understand.

## Gate: Smoke-test the restriction

Run as the worker:

```bash
id
sudo -n true
test -S /var/run/docker.sock && echo 'STOP: Docker socket is exposed'
test -n "${SSH_AUTH_SOCK:-}" && echo 'STOP: SSH forwarding is exposed'
```

**Pass:** `id` shows the worker, `sudo -n true` is denied (or sudo is absent), and neither exposure message appears. Inspect group memberships and mounts too. These checks are probes, not a comprehensive security audit.

Create a harmless owner-only canary file outside the worker’s home, then try to read it as the worker. **Pass:** permission denied. Never use an actual private key as the canary. Confirm the worker cannot reach a known disallowed endpoint under the external network policy. Do not probe real secrets or retrieve cloud metadata credentials.

## Gate: Transfer the exact exercise

Clone your learning repository with read-only access or transfer a Git bundle. Check out the recorded exercise commit. Do not forward your personal SSH agent. Warm the environment and run the known baseline checks before injecting a scoped model key.

The Chapter 06 acceptance suite is intentionally red. First run the original unit file alone to prove the environment works; then show the expected missing-function failure. Review `.envrc`, Nix expressions, hooks and scripts before execution, since repository content can run code.

## Gate: Run, review, and retire

Now execute the bounded loop from Chapter 08. Stop after its first completed experiment. Transfer the allowed source diff back to a fresh owner-controlled checkout, retain the original tests, and run full validation. Inspect added files and staged changes as well as the ordinary diff.

Commit and open a PR only after that review. Revoke the worker’s model credential and destroy the VM through the provider. Verify the instance and any chargeable disks are gone. Revoking a key and terminating a process are separate actions.

## Known failure modes

- No sudo is insufficient if the user belongs to a Docker group or can edit the controller’s service unit.
- A writable host mount defeats the intended file boundary.
- A low-cost model credential may still be usable for exfiltration to its allowed destination; give the worker only data it needs.
- A local timer is not reliable teardown if the agent can change or kill it.

## Check your understanding

**Q3.** What evidence should survive VM deletion?

**Q4.** Where must the strongest acceptance checks run?

<details>
<summary>Answer key — attempt every question first</summary>

## Answer key

**Q3.** Commit identity, redacted logs, diff, costs, and independent test results. **Pass criteria:** enough to reproduce and evaluate the change.

**Q4.** In a fresh owner-controlled environment using protected tests. **Pass criteria:** outside worker authority.

</details>

## References

- [Huntley’s overlay demonstration](https://github.com/ghuntley/nix-demo)
- [Nix sandbox configuration](https://nix.dev/manual/nix/stable/command-ref/conf-file.html#conf-sandbox)
- [GitHub secure workflow guidance](https://docs.github.com/en/actions/reference/security/secure-use)

---

[← Chapter 08](/nix-agent-lab/03-controlled-agents/08-bounded-ralph-loop/) · [Next: Chapter 10 →](/nix-agent-lab/04-cloud-and-system-tests/10-prove-cloud-parity/)
