-
Notifications
You must be signed in to change notification settings - Fork 434
Require dangerously-disable-sandbox-agent feature flag to allow sandbox.agent: false
#38205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,7 @@ import ( | |
| ) | ||
|
|
||
| func TestSandboxAgentMandatory(t *testing.T) { | ||
| t.Run("sandbox.agent: false is accepted and disables agent sandbox", func(t *testing.T) { | ||
| t.Run("sandbox.agent: false with feature flag is accepted and disables agent sandbox", func(t *testing.T) { | ||
| // Create temp directory for test workflows | ||
| workflowsDir := t.TempDir() | ||
|
|
||
|
|
@@ -20,13 +20,15 @@ network: | |
| allowed: | ||
| - defaults | ||
| - github.com | ||
| features: | ||
| dangerously-disable-sandbox-agent: true | ||
| sandbox: | ||
| agent: false | ||
| strict: false | ||
| on: workflow_dispatch | ||
| --- | ||
|
|
||
| Test workflow to verify sandbox.agent: false is accepted and disables agent sandbox. | ||
| Test workflow to verify sandbox.agent: false is accepted when the feature flag is set. | ||
| ` | ||
|
|
||
| workflowPath := filepath.Join(workflowsDir, "test-agent-false.md") | ||
|
|
@@ -35,13 +37,13 @@ Test workflow to verify sandbox.agent: false is accepted and disables agent sand | |
| t.Fatalf("Failed to write workflow file: %v", err) | ||
| } | ||
|
|
||
| // Compile the workflow | ||
| // Compile the workflow (validation runs unconditionally; validateSandboxConfig | ||
| // is not gated by skipValidation, so this exercises the feature-flag check) | ||
| compiler := NewCompiler() | ||
| compiler.SetSkipValidation(true) | ||
|
|
||
| // Should succeed in non-strict mode | ||
| // Should succeed when the feature flag is set | ||
| if err := compiler.CompileWorkflow(workflowPath); err != nil { | ||
| t.Fatalf("Expected compilation to succeed with sandbox.agent: false in non-strict mode, but got error: %v", err) | ||
| t.Fatalf("Expected compilation to succeed with sandbox.agent: false and feature flag, but got error: %v", err) | ||
| } | ||
|
|
||
| // Read the compiled workflow | ||
|
|
@@ -157,6 +159,43 @@ Test workflow to verify default sandbox.agent behavior (awf). | |
| }) | ||
| } | ||
|
|
||
| func TestSandboxAgentFalseRequiresFeatureFlag(t *testing.T) { | ||
| t.Run("sandbox.agent: false without feature flag is rejected", func(t *testing.T) { | ||
| workflowsDir := t.TempDir() | ||
|
|
||
| markdown := `--- | ||
| engine: copilot | ||
| network: | ||
| allowed: | ||
| - defaults | ||
| - github.com | ||
| sandbox: | ||
| agent: false | ||
| strict: false | ||
| on: workflow_dispatch | ||
| --- | ||
|
|
||
| Test workflow to verify sandbox.agent: false is rejected without the feature flag. | ||
| ` | ||
|
|
||
| workflowPath := filepath.Join(workflowsDir, "test-agent-false-no-flag.md") | ||
| err := os.WriteFile(workflowPath, []byte(markdown), 0644) | ||
| if err != nil { | ||
| t.Fatalf("Failed to write workflow file: %v", err) | ||
| } | ||
|
|
||
| compiler := NewCompiler() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fragile test: missing Every other 💡 Why this is fragileThe test asserts the error message contains Fix: compiler := NewCompiler()
compiler.SetSkipValidation(true) // ensure schema validation is skipped so validateSandboxConfig fires first |
||
|
|
||
| err = compiler.CompileWorkflow(workflowPath) | ||
| if err == nil { | ||
| t.Fatal("Expected compilation to fail when sandbox.agent: false without feature flag, but got nil error") | ||
| } | ||
| if !strings.Contains(err.Error(), "dangerously-disable-sandbox-agent") { | ||
| t.Fatalf("Expected error to reference 'dangerously-disable-sandbox-agent', got: %v", err) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| func TestNetworkFirewallFrontmatterRejected(t *testing.T) { | ||
| t.Run("network.firewall is rejected by schema", func(t *testing.T) { | ||
| // Create temp directory for test workflows | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,12 +76,19 @@ func validateSandboxConfig(workflowData *WorkflowData) error { | |
| sandboxConfig := workflowData.SandboxConfig | ||
|
|
||
| // Check if sandbox.agent: false was specified | ||
| // In non-strict mode, this is allowed (with a warning shown at compile time) | ||
| // The strict mode check happens in validateStrictFirewall() | ||
| // This requires the "dangerously-disable-sandbox-agent" feature flag to be enabled. | ||
| // Without the feature flag, setting sandbox.agent: false is a validation error. | ||
| if sandboxConfig.Agent != nil && sandboxConfig.Agent.Disabled { | ||
|
Comment on lines
78
to
81
|
||
| // sandbox.agent: false is allowed in non-strict mode, so we don't error here | ||
| // The warning is emitted in compiler.go | ||
| sandboxValidationLog.Print("sandbox.agent: false detected, will be validated by strict mode check") | ||
| if !isFeatureEnabled(constants.DangerouslyDisableSandboxAgentFeatureFlag, workflowData) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/tdd] 💡 Suggested optionsIf the env-var bypass is intentional (useful for local dev/CI runner-level override), add a test to document it: t.Run("GH_AW_FEATURES env var enables sandbox.agent: false", func(t *testing.T) {
t.Setenv("GH_AW_FEATURES", "dangerously-disable-sandbox-agent")
// compile a workflow with sandbox.agent: false but no frontmatter flag
// expect: compilation succeeds
})If the env-var bypass is not intended (the whole point is that the opt-in must be visible in the committed workflow file), Either way, a one-line comment on the |
||
| flag := string(constants.DangerouslyDisableSandboxAgentFeatureFlag) | ||
| return NewValidationError( | ||
| "sandbox.agent", | ||
| "false", | ||
| fmt.Sprintf("disabling the agent sandbox requires the '%s' feature flag", flag), | ||
| fmt.Sprintf("Add the feature flag to your workflow frontmatter:\n\nfeatures:\n %s: true\nsandbox:\n agent: false\n\nSee: %s", flag, constants.DocsSandboxURL), | ||
| ) | ||
| } | ||
| sandboxValidationLog.Printf("sandbox.agent: false permitted by %s feature flag", constants.DangerouslyDisableSandboxAgentFeatureFlag) | ||
| } | ||
|
|
||
| // Validate mounts syntax if specified in agent config | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd] The new test only covers
sandbox.agent: falsewith the flag entirely absent. An edge case worth locking in: settingdangerously-disable-sandbox-agent: falseexplicitly should also be rejected —parseFeatureValuereturnsfalsefor a booleanfalse, so the code handles it correctly, but there is no test asserting that behaviour.💡 Suggested additional sub-test