Skip to content

Commit 70dd911

Browse files
Mossakaclaude
andauthored
Update docs to align with AWF chroot mode (v0.13.1+) (#13758)
Updates sandbox.md, architecture.mdx, and security-architecture-spec.md to reflect the --enable-chroot mode introduced in commit 578ac0d: - Replace explicit volume mount tables with chroot filesystem visibility - Replace utility mount lists with "all host binaries available" - Replace environment variable category tables with --env-all explanation - Add GOROOT special case documentation - Simplify runtime tools section to explain transparent PATH inheritance - Add chroot-based transparency subsection to architecture - Update security spec SI-04 through SI-07 requirements Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 578ac0d commit 70dd911

File tree

3 files changed

+66
-146
lines changed

3 files changed

+66
-146
lines changed

docs/src/content/docs/introduction/architecture.mdx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ The SafeOutputs subsystem provides security by design: the agent never requires
160160

161161
## Agent Workflow Firewall (AWF)
162162

163-
The Agent Workflow Firewall (AWF) provides network egress control at the substrate level. AWF mediates all outbound network requests from the agent, enforcing a domain allowlist that constrains which external endpoints the agent may contact. This mechanism prevents unauthorized data exfiltration and limits the blast radius of a compromised agent to only those domains explicitly permitted by configuration.
163+
The Agent Workflow Firewall (AWF) enforces network egress control via a domain allowlist, preventing data exfiltration and containing compromised agents to permitted domains.
164+
165+
AWF separates two concerns:
166+
- **Filesystem**: All host binaries and runtimes accessible; setup actions work transparently
167+
- **Network**: All traffic routed through proxy enforcing the domain allowlist
164168

165169
```mermaid
166170
flowchart TB

docs/src/content/docs/reference/sandbox.md

Lines changed: 33 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -78,121 +78,50 @@ network:
7878
- "api.example.com"
7979
```
8080

81-
#### Default Mounted Volumes
82-
83-
AWF automatically mounts several paths from the host into the container to enable agent functionality:
84-
85-
| Host Path | Container Path | Mode | Purpose |
86-
|-----------|----------------|------|---------|
87-
| `/tmp` | `/tmp` | `rw` | Temporary files and cache |
88-
| `${HOME}/.cache` | `${HOME}/.cache` | `rw` | Build caches (Go, npm, etc.) |
89-
| `${GITHUB_WORKSPACE}` | `${GITHUB_WORKSPACE}` | `rw` | Repository workspace directory |
90-
| `/opt/hostedtoolcache` | `/opt/hostedtoolcache` | `ro` | Runtimes (Node.js, Python, Go, Ruby, Java) |
91-
| `/opt/gh-aw` | `/opt/gh-aw` | `ro` | Script and configuration files |
92-
| `/usr/local/bin/copilot` | `/usr/local/bin/copilot` | `ro` | Copilot CLI binary |
93-
| `/home/runner/.copilot` | `/home/runner/.copilot` | `rw` | Copilot configuration and state |
94-
95-
These default mounts ensure the agent has access to essential tools and the repository files. Custom mounts specified via `sandbox.agent.mounts` are added alongside these defaults.
96-
97-
#### Mounted System Utilities
98-
99-
AWF mounts common system utilities from the host into the container as read-only binaries. These utilities are frequently used in workflow scripts and are organized by priority:
100-
101-
**Essential Utilities** (most commonly used):
102-
103-
| Utility | Purpose |
104-
|---------|---------|
105-
| `cat` | Display file contents |
106-
| `curl` | HTTP client for API calls |
107-
| `date` | Date/time operations |
108-
| `find` | Locate files by pattern |
109-
| `gh` | GitHub CLI operations |
110-
| `grep` | Pattern matching |
111-
| `jq` | JSON processing |
112-
| `yq` | YAML processing |
113-
114-
**Common Utilities** (frequently used for file operations):
115-
116-
| Utility | Purpose |
117-
|---------|---------|
118-
| `cp` | Copy files |
119-
| `cut` | Extract text columns |
120-
| `diff` | Compare files |
121-
| `head` | Display file start |
122-
| `ls` | List directory contents |
123-
| `mkdir` | Create directories |
124-
| `rm` | Remove files |
125-
| `sed` | Stream text editing |
126-
| `sort` | Sort text lines |
127-
| `tail` | Display file end |
128-
| `wc` | Count lines/words |
129-
| `which` | Locate commands |
130-
131-
All utilities are mounted read-only (`:ro`) from `/usr/bin/` on the host. They execute on the read-write workspace directory inside the container.
132-
133-
> [!TIP]
134-
> Available Utilities
135-
> Run `which jq` or `jq --version` in your workflow to verify utility availability. The agent has access to all mounted utilities without additional setup.
81+
#### Chroot Mode
82+
83+
AWF v0.13.1+ uses **chroot mode** (`--enable-chroot`) to provide transparent host filesystem access while maintaining network isolation via iptables. This eliminates explicit volume mounts and environment variable configuration.
84+
85+
```text
86+
┌─────────────────────────────────────────────┐
87+
│ AWF Container (chroot) │
88+
│ • Full filesystem visibility │
89+
│ • All host binaries available │
90+
│ • Network: RESTRICTED via iptables/Squid │
91+
└─────────────────────┬───────────────────────┘
92+
93+
Allowed domains only
94+
```
13695

137-
> [!WARNING]
138-
> Docker socket access is not supported for security
139-
> reasons. The agent firewall does not mount
140-
> `/var/run/docker.sock`, and custom mounts cannot add
141-
> it, preventing agents from spawning Docker
142-
> containers.
143-
144-
#### Mirrored Environment Variables
145-
146-
AWF automatically mirrors essential environment variables from the GitHub Actions runner into the agent container. This ensures compatibility with workflows that depend on runner-provided tool paths.
147-
148-
The following environment variables are mirrored (if they exist on the host):
149-
150-
| Category | Environment Variables |
151-
|----------|----------------------|
152-
| **Java** | `JAVA_HOME`, `JAVA_HOME_8_X64`, `JAVA_HOME_11_X64`, `JAVA_HOME_17_X64`, `JAVA_HOME_21_X64`, `JAVA_HOME_25_X64` |
153-
| **Android** | `ANDROID_HOME`, `ANDROID_SDK_ROOT`, `ANDROID_NDK`, `ANDROID_NDK_HOME`, `ANDROID_NDK_ROOT`, `ANDROID_NDK_LATEST_HOME` |
154-
| **Browsers** | `CHROMEWEBDRIVER`, `EDGEWEBDRIVER`, `GECKOWEBDRIVER`, `SELENIUM_JAR_PATH` |
155-
| **Package Managers** | `CONDA`, `VCPKG_INSTALLATION_ROOT`, `PIPX_HOME`, `PIPX_BIN_DIR`, `GEM_HOME`, `GEM_PATH` |
156-
| **Go** | `GOPATH`, `GOROOT` |
157-
| **.NET** | `DOTNET_ROOT` |
158-
| **Rust** | `CARGO_HOME`, `RUSTUP_HOME` |
159-
| **Node.js** | `NVM_DIR` |
160-
| **Homebrew** | `HOMEBREW_PREFIX`, `HOMEBREW_CELLAR`, `HOMEBREW_REPOSITORY` |
161-
| **Swift** | `SWIFT_PATH` |
162-
| **Azure** | `AZURE_EXTENSION_DIR` |
96+
#### Filesystem Access
16397

164-
> [!NOTE]
165-
> Environment Variable Handling
166-
> Variables are only passed to the container if they exist on the host runner. Missing variables are silently ignored, ensuring workflows work across different runner configurations.
98+
AWF chroot mode makes the host filesystem visible inside the container with appropriate permissions:
16799

168-
#### Runtime Tools (hostedtoolcache)
100+
| Path Type | Mode | Examples |
101+
|-----------|------|----------|
102+
| User paths | Read-write | `$HOME`, `$GITHUB_WORKSPACE`, `/tmp` |
103+
| System paths | Read-only | `/usr`, `/opt`, `/bin`, `/lib` |
104+
| Docker socket | Hidden | `/var/run/docker.sock` (security) |
169105

170-
AWF mounts the `/opt/hostedtoolcache` directory from the GitHub Actions runner, providing access to all runtimes installed via `actions/setup-*` steps. This directory contains pre-installed and dynamically-installed versions of popular development tools.
106+
Custom mounts can still be added via `sandbox.agent.mounts` for paths that need different permissions.
171107

172-
**Available Runtimes:**
108+
#### Host Binaries
173109

174-
| Runtime | Setup Action | Example Versions |
175-
|---------|-------------|------------------|
176-
| **Node.js** | `actions/setup-node` | 18.x, 20.x, 22.x |
177-
| **Python** | `actions/setup-python` | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
178-
| **Go** | `actions/setup-go` | 1.22.x, 1.23.x, 1.24.x, 1.25.x |
179-
| **Ruby** | `ruby/setup-ruby` | 3.2, 3.3, 3.4 |
180-
| **Java** | `actions/setup-java` | 8, 11, 17, 21, 25 |
110+
All host binaries are available without explicit mounts: system utilities, `gh`, language runtimes, build tools, and anything installed via `apt-get` or setup actions. Verify with `which <tool>`.
181111

182-
**PATH Integration:**
112+
> [!WARNING]
113+
> Docker socket is hidden for security. Agents cannot spawn containers.
183114

184-
All runtime binaries are automatically added to PATH inside the agent container. The PATH is configured using a dynamic `find` command that discovers all `bin` directories within `/opt/hostedtoolcache`:
115+
#### Environment Variables
185116

186-
```bash
187-
# PATH includes all hostedtoolcache binaries
188-
export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/null | tr '\n' ':')$PATH"
189-
```
117+
AWF passes all environment variables via `--env-all`. The host `PATH` is captured as `AWF_HOST_PATH` and restored inside the container, preserving setup action tool paths.
190118

191-
**Version Priority:**
119+
> [!NOTE]
120+
> Go's "trimmed" binaries require `GOROOT`—AWF automatically captures it after `actions/setup-go`.
192121

193-
When multiple versions of a runtime are installed, versions configured by `actions/setup-*` take precedence. The agent detects which specific version is active by reading environment variables like `GOROOT`, `JAVA_HOME`, and ensures that version's binaries appear first in PATH.
122+
#### Runtime Tools
194123

195-
**Using Runtimes in Workflows:**
124+
Setup actions work transparently. Runtimes update `PATH`, which AWF captures and restores inside the container.
196125

197126
```yaml wrap
198127
---
@@ -207,13 +136,9 @@ jobs:
207136
python-version: '3.12'
208137
---
209138
210-
Use `go build` or `python3` in your workflow - both are available!
139+
Use `go build` or `python3` - both are available.
211140
```
212141

213-
> [!TIP]
214-
> Verify Runtime Availability
215-
> Use `node --version`, `python3 --version`, `go version`, or `ruby --version` in your workflow to confirm runtime availability. The agent automatically inherits all runtimes configured by setup actions.
216-
217142
#### Custom AWF Configuration
218143

219144
Use custom commands, arguments, and environment variables to replace the standard AWF installation with a custom setup:

specs/security-architecture-spec.md

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -651,26 +651,19 @@ The sandbox isolation layer provides process-level and container-level isolation
651651

652652
**SI-04**: The AWF sandbox MUST provide:
653653
- Container-based process isolation
654-
- Network egress control via iptables
655-
- Domain-based allowlisting
656-
- Mounted volumes for workspace access
657-
- Mounted system utilities (read-only)
654+
- Network egress control via iptables and domain-based allowlisting
655+
- Chroot-based filesystem transparency (all host binaries accessible, no explicit mounts)
656+
- Hidden Docker socket for security
657+
- Automatic environment variable inheritance via `--env-all`
658+
- Capability drop post-setup (CAP_NET_ADMIN, CAP_SYS_CHROOT)
658659

659-
**SI-05**: AWF MUST mount the following volumes by default:
660+
**SI-05**: AWF chroot mode MUST enforce this filesystem access model:
660661

661-
| Host Path | Container Path | Mode | Purpose |
662-
|-----------|----------------|------|---------|
663-
| `/tmp` | `/tmp` | `rw` | Temporary files |
664-
| `${HOME}/.cache` | `${HOME}/.cache` | `rw` | Build caches |
665-
| `${GITHUB_WORKSPACE}` | `${GITHUB_WORKSPACE}` | `rw` | Repository workspace |
666-
| `/opt/hostedtoolcache` | `/opt/hostedtoolcache` | `ro` | Runtimes (Node, Python, Go) |
667-
| `/opt/gh-aw` | `/opt/gh-aw` | `ro` | Scripts and configs |
668-
669-
**SI-06**: AWF MUST mount common system utilities as read-only binaries:
670-
- Essential: `cat`, `curl`, `date`, `find`, `gh`, `grep`, `jq`, `yq`
671-
- Common: `cp`, `cut`, `diff`, `head`, `ls`, `mkdir`, `rm`, `sed`, `sort`, `tail`, `wc`
672-
673-
**SI-07**: AWF MUST NOT mount Docker socket (`/var/run/docker.sock`) for security reasons.
662+
| Path Type | Mode | Examples |
663+
|-----------|------|----------|
664+
| User paths | Read-write | `$HOME`, `$GITHUB_WORKSPACE`, `/tmp` |
665+
| System paths | Read-only | `/usr`, `/opt`, `/bin`, `/lib` |
666+
| Docker socket | Hidden | `/var/run/docker.sock` |
674667

675668
### 8.4 MCP Server Sandbox
676669

@@ -688,23 +681,21 @@ The sandbox isolation layer provides process-level and container-level isolation
688681
- Be scanned for vulnerabilities
689682
- Have SBOMs tracked
690683

691-
### 8.5 Environment Variable Mirroring
692-
693-
**SI-11**: The implementation SHOULD mirror essential environment variables from the host to the agent container:
694-
- Language toolchain paths (JAVA_HOME, GOROOT, etc.)
695-
- Package manager paths (PIPX_HOME, GEM_HOME, etc.)
696-
- Browser driver paths (CHROMEWEBDRIVER, etc.)
684+
### 8.5 Environment Variable Inheritance
697685

698-
**SI-12**: Undefined environment variables MUST be silently ignored (no errors).
686+
**SI-06**: AWF MUST pass all environment variables via `--env-all` and implement PATH inheritance:
687+
- Host `PATH` captured as `AWF_HOST_PATH` and restored inside container
688+
- `GOROOT` explicitly captured after `actions/setup-go` (Go's trimmed binaries require it)
689+
- Undefined variables silently ignored
699690

700691
### 8.6 Sandbox Guarantees
701692

702-
**SI-13**: The sandbox isolation layer MUST guarantee:
703-
- Agent processes cannot access host filesystem outside mounted volumes
704-
- Agent processes cannot spawn Docker containers
705-
- Agent processes have network access only to allowed domains
706-
- MCP servers execute in separate, isolated containers
707-
- MCP servers have independent network allowlists
693+
**SI-07**: The sandbox isolation layer MUST guarantee:
694+
- Read-only system paths, read-write user paths only (`$HOME`, `$GITHUB_WORKSPACE`, `/tmp`)
695+
- No Docker socket access
696+
- Network access only to allowed domains (iptables enforcement independent of chroot)
697+
- MCP servers in isolated containers with independent network allowlists
698+
- Defense in depth: filesystem visibility (chroot) and network isolation (iptables) remain separate layers
708699

709700
---
710701

@@ -1046,12 +1037,12 @@ A conforming implementation MUST provide a compliance test suite covering all MU
10461037
#### 12.2.5 Sandbox Isolation Tests
10471038

10481039
- **T-SI-001**: Verify agent sandbox type support (AWF, SRT)
1049-
- **T-SI-002**: Verify AWF default volume mounts
1050-
- **T-SI-003**: Verify AWF system utility mounts
1051-
- **T-SI-004**: Verify Docker socket denial
1052-
- **T-SI-005**: Verify MCP server container isolation
1053-
- **T-SI-006**: Verify MCP server security profile (non-root, dropped caps)
1054-
- **T-SI-007**: Verify environment variable mirroring
1040+
- **T-SI-002**: Verify AWF chroot filesystem visibility and access model
1041+
- **T-SI-003**: Verify Docker socket hidden from chroot
1042+
- **T-SI-004**: Verify `--env-all` and `AWF_HOST_PATH` mechanism
1043+
- **T-SI-005**: Verify GOROOT capture for Go runtime
1044+
- **T-SI-006**: Verify MCP server container isolation
1045+
- **T-SI-007**: Verify network isolation independent of chroot
10551046

10561047
#### 12.2.6 Threat Detection Tests
10571048

0 commit comments

Comments
 (0)