Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/content/docs/reference/sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ network:

#### Chroot Mode

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.
AWF v0.15.0+ uses **chroot mode by default** to provide transparent host filesystem access while maintaining network isolation via iptables. This eliminates explicit volume mounts and environment variable configuration.

```text
┌─────────────────────────────────────────────┐
Expand Down
8 changes: 3 additions & 5 deletions pkg/workflow/claude_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,10 @@ func (e *ClaudeEngine) GetExecutionSteps(workflowData *WorkflowData, logFile str
// Get allowed domains (Claude defaults + network permissions + HTTP MCP server URLs + runtime ecosystem domains)
allowedDomains := GetClaudeAllowedDomainsWithToolsAndRuntimes(workflowData.NetworkPermissions, workflowData.Tools, workflowData.Runtimes)

// Build AWF arguments: enable-chroot mode + standard flags + custom args from config
// AWF v0.13.1+ chroot mode provides transparent access to host binaries and environment
// while maintaining network isolation, eliminating the need for explicit mounts and env flags
// Build AWF arguments: standard flags + custom args from config
// AWF v0.15.0+ uses chroot mode by default, providing transparent access to host binaries
// and environment while maintaining network isolation
var awfArgs []string
Comment on lines +273 to 276
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s still a comment later in this file that references --enable-chroot (around line ~357). Since this PR removes that flag for AWF v0.15.0+, please update that remaining comment to avoid misleading guidance (e.g., describe chroot mode as default and remove mention of --enable-chroot).

Copilot uses AI. Check for mistakes.
awfArgs = append(awfArgs, "--enable-chroot")
claudeLog.Print("Enabled chroot mode for transparent host access")

// TTY is required for Claude Code CLI
awfArgs = append(awfArgs, "--tty")
Expand Down
10 changes: 4 additions & 6 deletions pkg/workflow/codex_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,10 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri
// Get allowed domains (Codex defaults + network permissions + HTTP MCP server URLs + runtime ecosystem domains)
allowedDomains := GetCodexAllowedDomainsWithToolsAndRuntimes(workflowData.NetworkPermissions, workflowData.Tools, workflowData.Runtimes)

// Build AWF arguments: enable-chroot mode + standard flags + custom args from config
// AWF v0.13.1+ chroot mode provides transparent access to host binaries and environment
// while maintaining network isolation, eliminating the need for explicit mounts and env flags
// Build AWF arguments: standard flags + custom args from config
// AWF v0.15.0+ uses chroot mode by default, providing transparent access to host binaries
// and environment while maintaining network isolation
var awfArgs []string
awfArgs = append(awfArgs, "--enable-chroot")
codexEngineLog.Print("Enabled chroot mode for transparent host access")

// Pass all environment variables to the container
awfArgs = append(awfArgs, "--env-all")
Expand Down Expand Up @@ -279,7 +277,7 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri
// INSTRUCTION reading is done inside the AWF command to avoid Docker Compose interpolation
// issues with $ characters in the prompt.
//
// AWF with --enable-chroot and --env-all handles most PATH setup natively:
// AWF v0.15.0+ with --env-all handles most PATH setup natively (chroot mode is default):
// - GOROOT, JAVA_HOME, etc. are handled via AWF_HOST_PATH and entrypoint.sh
// However, npm-installed CLIs (like codex) need hostedtoolcache bin directories in PATH.
npmPathSetup := GetNpmBinPathSetup()
Expand Down
10 changes: 4 additions & 6 deletions pkg/workflow/copilot_engine_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,10 @@ func (e *CopilotEngine) GetExecutionSteps(workflowData *WorkflowData, logFile st
// Get allowed domains (copilot defaults + network permissions + HTTP MCP server URLs + runtime ecosystem domains)
allowedDomains := GetCopilotAllowedDomainsWithToolsAndRuntimes(workflowData.NetworkPermissions, workflowData.Tools, workflowData.Runtimes)

// Build AWF arguments: enable-chroot mode + standard flags + custom args from config
// AWF v0.13.1+ chroot mode provides transparent access to host binaries and environment
// while maintaining network isolation, eliminating the need for explicit mounts and env flags
// Build AWF arguments: standard flags + custom args from config
// AWF v0.15.0+ uses chroot mode by default, providing transparent access to host binaries
// and environment while maintaining network isolation
var awfArgs []string
awfArgs = append(awfArgs, "--enable-chroot")
copilotExecLog.Print("Enabled chroot mode for transparent host access")

// Pass all environment variables to the container
awfArgs = append(awfArgs, "--env-all")
Expand Down Expand Up @@ -340,7 +338,7 @@ func (e *CopilotEngine) GetExecutionSteps(workflowData *WorkflowData, logFile st
// AWF v0.2.0 uses -- to separate AWF args from the actual command
// The command arguments should be passed as individual shell arguments, not as a single string
//
// AWF with --enable-chroot and --env-all handles PATH natively:
// AWF v0.15.0+ with --env-all handles PATH natively (chroot mode is default):
// 1. Captures host PATH → AWF_HOST_PATH (already has correct ordering from actions/setup-*)
// 2. Passes ALL host env vars including JAVA_HOME, DOTNET_ROOT, GOROOT
// 3. entrypoint.sh exports PATH="${AWF_HOST_PATH}" and tool-specific vars
Expand Down
18 changes: 9 additions & 9 deletions pkg/workflow/firewall_args_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ func TestFirewallArgsInCopilotEngine(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Check that the command contains --enable-chroot for AWF v0.13.1+ chroot mode
if !strings.Contains(stepContent, "awf --enable-chroot") {
t.Error("Expected command to contain 'awf --enable-chroot'")
// Check that the command contains awf (AWF v0.15.0+ uses chroot mode by default)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected command to contain 'sudo -E awf'")
}

if !strings.Contains(stepContent, "--allow-domains") {
Expand Down Expand Up @@ -150,15 +150,15 @@ func TestFirewallArgsInCopilotEngine(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Check that --enable-chroot is used for transparent host access (AWF v0.13.1+)
// This replaces the need for explicit binary mounts like --mount /usr/bin/gh:/usr/bin/gh:ro
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected AWF command to contain '--enable-chroot' for transparent host access")
// Check that AWF is used for transparent host access (AWF v0.15.0+)
// Chroot mode is now the default, so no --enable-chroot flag is needed
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF command for transparent host access")
}

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests no longer assert that --enable-chroot is absent from the generated AWF command. Since the goal of this PR is to stop emitting that flag, consider adding a negative assertion (e.g., fail if stepContent contains --enable-chroot) to prevent regressions where the flag gets reintroduced.

Suggested change
// Ensure we are not explicitly passing the chroot flag (chroot is the default)
if strings.Contains(stepContent, "--enable-chroot") {
t.Error("AWF command should not include '--enable-chroot' flag when chroot mode is the default")
}

Copilot uses AI. Check for mistakes.
// Verify that individual binary mounts are no longer used (replaced by chroot)
// Verify that individual binary mounts are not used (chroot mode is default)
if strings.Contains(stepContent, "--mount /usr/bin/gh:/usr/bin/gh:ro") {
t.Error("Individual binary mounts should be replaced by --enable-chroot mode")
t.Error("Individual binary mounts should not be present with default chroot mode")
}
})

Expand Down
44 changes: 17 additions & 27 deletions pkg/workflow/gh_cli_mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"testing"
)

// TestChrootModeInAWFContainer tests that AWF uses --enable-chroot mode for transparent host access
// TestChrootModeInAWFContainer tests that AWF uses chroot mode (default in v0.15.0+) for transparent host access
func TestChrootModeInAWFContainer(t *testing.T) {
t.Run("chroot mode is enabled when firewall is enabled", func(t *testing.T) {
t.Run("chroot mode is enabled by default when firewall is enabled", func(t *testing.T) {
workflowData := &WorkflowData{
Name: "test-workflow",
EngineConfig: &EngineConfig{
Expand All @@ -31,9 +31,9 @@ func TestChrootModeInAWFContainer(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Check that --enable-chroot is used instead of individual binary mounts
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected AWF command to contain '--enable-chroot' for transparent host access")
// Check that AWF is used (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF command for transparent host access")
}
})

Expand Down Expand Up @@ -63,11 +63,6 @@ func TestChrootModeInAWFContainer(t *testing.T) {
if strings.Contains(stepContent, "awf") {
t.Error("Expected no AWF command when firewall is disabled")
}

// Check that --enable-chroot is not present
if strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected no --enable-chroot when firewall is disabled")
}
})

t.Run("chroot mode replaces individual binary mounts", func(t *testing.T) {
Expand All @@ -92,12 +87,12 @@ func TestChrootModeInAWFContainer(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Verify --enable-chroot is present
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected --enable-chroot to be present")
// Verify AWF is present (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF to be present")
}

// Verify individual binary mounts are NOT present (replaced by chroot)
// Verify individual binary mounts are NOT present (replaced by default chroot mode)
individualMounts := []string{
"--mount /usr/bin/gh:/usr/bin/gh:ro",
"--mount /usr/bin/cat:/usr/bin/cat:ro",
Expand All @@ -108,7 +103,7 @@ func TestChrootModeInAWFContainer(t *testing.T) {

for _, mount := range individualMounts {
if strings.Contains(stepContent, mount) {
t.Errorf("Individual mount '%s' should be replaced by --enable-chroot mode", mount)
t.Errorf("Individual mount '%s' should be replaced by default chroot mode", mount)
}
}
})
Expand Down Expand Up @@ -136,9 +131,9 @@ func TestChrootModeInAWFContainer(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Verify both --enable-chroot and custom args are present
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected --enable-chroot to be present with custom firewall args")
// Verify AWF is present with custom args (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF to be present with custom firewall args")
}

if !strings.Contains(stepContent, "--custom-flag") {
Expand Down Expand Up @@ -174,12 +169,7 @@ func TestChrootModeInAWFContainer(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Verify --enable-chroot is present
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected --enable-chroot to be present when using AWF")
}

// Verify AWF is being used
// Verify AWF is being used (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "awf") {
t.Error("Expected AWF to be used when firewall is enabled")
}
Expand Down Expand Up @@ -210,9 +200,9 @@ func TestChrootModeEnvFlags(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Verify --enable-chroot is present (provides transparent host access)
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected --enable-chroot to be present")
// Verify AWF is present (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF to be present")
}

// Verify --env-all IS used (required for AWF to receive host environment variables)
Expand Down
12 changes: 6 additions & 6 deletions pkg/workflow/sandbox_mounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ func TestCopilotEngineWithCustomMounts(t *testing.T) {
t.Error("Expected command to contain custom mount '--mount /usr/local/bin/custom-tool:/usr/local/bin/custom-tool:ro'")
}

// Verify --enable-chroot is present (replaces standard mounts)
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected command to contain '--enable-chroot' for transparent host access")
// Verify AWF is present (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF command for transparent host access")
}
})

Expand All @@ -307,9 +307,9 @@ func TestCopilotEngineWithCustomMounts(t *testing.T) {

stepContent := strings.Join(steps[0], "\n")

// Verify --enable-chroot is present (provides transparent host access)
if !strings.Contains(stepContent, "--enable-chroot") {
t.Error("Expected command to contain '--enable-chroot' for transparent host access")
// Verify AWF is present (chroot mode is default in v0.15.0+)
if !strings.Contains(stepContent, "sudo -E awf") {
t.Error("Expected AWF command for transparent host access")
}

// Custom mount should not be present
Expand Down
Loading