Skip to content

Require dangerously-disable-sandbox-agent feature flag to allow sandbox.agent: false#38205

Merged
pelikhan merged 2 commits into
mainfrom
copilot/feature-dangerously-disable-sandbox-agent
Jun 9, 2026
Merged

Require dangerously-disable-sandbox-agent feature flag to allow sandbox.agent: false#38205
pelikhan merged 2 commits into
mainfrom
copilot/feature-dangerously-disable-sandbox-agent

Conversation

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

sandbox.agent: false previously compiled without restriction, making it easy to silently disable the agent firewall. This change gates it behind an explicit opt-in feature flag so the security trade-off is visible in every workflow that disables the sandbox.

Behavior

Without the flag, compilation now fails:

Validation failed for field 'sandbox.agent'
Value: false
Reason: disabling the agent sandbox requires the 'dangerously-disable-sandbox-agent' feature flag

To allow sandbox.agent: false, the workflow must declare:

features:
  dangerously-disable-sandbox-agent: true
sandbox:
  agent: false

Changes

  • pkg/constants/feature_constants.go — new DangerouslyDisableSandboxAgentFeatureFlag = "dangerously-disable-sandbox-agent" constant
  • pkg/workflow/sandbox_validation.govalidateSandboxConfig returns a ValidationError when sandbox.agent: false is present without the feature flag
  • pkg/workflow/sandbox_agent_false_test.go — acceptance test updated to include the feature flag; new TestSandboxAgentFalseRequiresFeatureFlag covers the rejection path
  • Test fixtures (compiler_validators_test.go, importable_tools_test.go, pull_request_target_validation_test.go, workflow_run_validation_test.go) — workflows using sandbox.agent: false as test setup now carry the feature flag to preserve existing assertions

pr-sous-chef: updated branch for run https://github.com/github/gh-aw/actions/runs/27236053686

Generated by 👨‍🍳 PR Sous Chef · 78.6 AIC · ⌖ 1.09 AIC · ⊞ 17.3K ·

…ent: false

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Require dangerously-disable-sandbox-agent feature flag for sandbox.agent: false Require dangerously-disable-sandbox-agent feature flag to allow sandbox.agent: false Jun 9, 2026
Copilot AI requested a review from pelikhan June 9, 2026 20:31
@pelikhan pelikhan marked this pull request as ready for review June 9, 2026 20:38
Copilot AI review requested due to automatic review settings June 9, 2026 20:38
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #38205 does not have the 'implementation' label (has_implementation_label=false) and has 95 new lines of code in business logic directories, which is below the 100-line threshold (requires_adr_by_default_volume=false).

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel failed during test quality analysis.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens security posture by preventing workflows from silently disabling the agent sandbox (sandbox.agent: false) unless they explicitly opt in via a new “dangerously” feature flag.

Changes:

  • Introduces dangerously-disable-sandbox-agent as a first-class feature flag constant.
  • Adds validation that rejects sandbox.agent: false unless the feature flag is enabled.
  • Updates several workflow/test fixtures to include the feature flag and adds a negative-path test.
Show a summary per file
File Description
pkg/constants/feature_constants.go Adds the DangerouslyDisableSandboxAgentFeatureFlag constant and documents intended usage.
pkg/workflow/sandbox_validation.go Enforces the new feature-flag gate when sandbox.agent: false is set.
pkg/workflow/sandbox_agent_false_test.go Updates the “allowed” acceptance test to include the feature flag and adds a rejection test when the flag is missing.
pkg/workflow/compiler_validators_test.go Updates a validator test fixture to include the new feature flag when agent sandbox is disabled.
pkg/workflow/importable_tools_test.go Updates embedded workflow fixtures that disable the agent sandbox to include the feature flag.
pkg/workflow/pull_request_target_validation_test.go Updates embedded workflow fixtures that disable the agent sandbox to include the feature flag.
pkg/workflow/workflow_run_validation_test.go Updates embedded workflow fixtures that disable the agent sandbox to include the feature flag.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 7/7 changed files
  • Comments generated: 3

Comment on lines +40 to +46
@@ -39,9 +41,9 @@ Test workflow to verify sandbox.agent: false is accepted and disables agent sand
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)
Comment thread pkg/workflow/sandbox_validation.go Outdated
Comment on lines +82 to +90
if !isFeatureEnabled(constants.DangerouslyDisableSandboxAgentFeatureFlag, workflowData) {
return NewValidationError(
"sandbox.agent",
"false",
"disabling the agent sandbox requires the 'dangerously-disable-sandbox-agent' feature flag",
fmt.Sprintf("Add the feature flag to your workflow frontmatter:\n\nfeatures:\n dangerously-disable-sandbox-agent: true\nsandbox:\n agent: false\n\nSee: %s", constants.DocsSandboxURL),
)
}
sandboxValidationLog.Print("sandbox.agent: false permitted by dangerously-disable-sandbox-agent feature flag")
Comment on lines 78 to 81
// 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 {
@github-actions github-actions Bot mentioned this pull request Jun 9, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /tdd and /grill-with-docs — commenting with minor gaps to address, no blocking issues.

📋 Key Themes & Highlights

Positive Highlights

  • ✅ The core gate is clean and correctly placed in validateSandboxConfig, which runs unconditionally (not gated by skipValidation).
  • ✅ Both the acceptance path (flag present → compiles) and the rejection path (flag absent → ValidationError naming the flag) are covered by tests.
  • ✅ The DangerouslyDisableSandboxAgentFeatureFlag constant doc follows the established pattern in feature_constants.go, with frontmatter example included.
  • ✅ Fixture updates across 6 test files are mechanical and correct — no missed callsites.

Observations

  1. Env-var bypass path (GH_AW_FEATURES) — isFeatureEnabled accepts the flag via environment variable as well as frontmatter. For a gate whose stated purpose is to make the opt-in "visible in every workflow", it is worth deciding (and testing) whether the env-var path is intentional. See inline comment on sandbox_validation.go:82.

  2. Explicit false edge casefeatures: dangerously-disable-sandbox-agent: false + sandbox.agent: false should be rejected. parseFeatureValue handles it correctly but there is no test. See inline comment on sandbox_agent_false_test.go:163.

  3. Pre-existing error message now incomplete — The NewConfigurationError at sandbox_validation.go:130 (unchanged code) suggests sandbox: agent: false as the remedy when MCP servers are missing, but does not mention that doing so now also requires the feature flag. Out of scope for this PR, but worth a follow-up.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 401.1 AIC · ⌖ 13.3 AIC

// 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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] isFeatureEnabled also accepts this flag via the GH_AW_FEATURES environment variable, so GH_AW_FEATURES=dangerously-disable-sandbox-agent on the runner silently bypasses the frontmatter gate. This path is untested, and for a "dangerously"-named security flag the behaviour should be explicit.

💡 Suggested options

If 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), isFeatureEnabled would need a frontmatter-only mode for security-critical flags.

Either way, a one-line comment on the isFeatureEnabled call here stating the intent would help reviewers.

}

func TestSandboxAgentFalseRequiresFeatureFlag(t *testing.T) {
t.Run("sandbox.agent: false without feature flag is rejected", func(t *testing.T) {

Copy link
Copy Markdown
Contributor

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: false with the flag entirely absent. An edge case worth locking in: setting dangerously-disable-sandbox-agent: false explicitly should also be rejected — parseFeatureValue returns false for a boolean false, so the code handles it correctly, but there is no test asserting that behaviour.

💡 Suggested additional sub-test
t.Run("sandbox.agent: false with feature flag explicitly false is rejected", func(t *testing.T) {
    workflowsDir := t.TempDir()
    markdown := `---
engine: copilot
features:
  dangerously-disable-sandbox-agent: false
sandbox:
  agent: false
strict: false
on: workflow_dispatch
---
Test workflow.
`
    workflowPath := filepath.Join(workflowsDir, "test.md")
    _ = os.WriteFile(workflowPath, []byte(markdown), 0644)
    compiler := NewCompiler()
    err := compiler.CompileWorkflow(workflowPath)
    if err == nil {
        t.Fatal("Expected compilation to fail when flag is explicitly false")
    }
    if !strings.Contains(err.Error(), "dangerously-disable-sandbox-agent") {
        t.Fatalf("Expected error to reference flag, got: %v", err)
    }
})

@pelikhan

pelikhan commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

REQUEST_CHANGES: Two integration-test files were not updated to include the new feature flag, so go test -tags=integration will fail after this merge.

### Broken integration tests (blocking)

pkg/workflow/sandbox_agent_disabled_test.go (build tag: integration) — 4 test cases broken

All four sandbox.agent: false cases in this file are missing dangerously-disable-sandbox-agent: true in their workflow frontmatter. With the new validateSandboxConfig logic, each will fail before reaching its expected outcome:

Test case Expected Will actually get
"disables firewall but keeps MCP gateway" require.NoError feature-flag validation error
"shows warning at compile time" require.NoError feature-flag validation error
TestSandboxAgentFalseWithTools require.NoError feature-flag validation error
"is refused in strict mode" error containing "strict mode" error containing "dangerously-disable-sandbox-agent" (feature-flag check fires before strict-mode check)

pkg/workflow/aw_info_steps_test.go (build tag: integration) — 1 test case broken

The "firewall disabled" test case (the markdown at the sandbox: agent: false line) calls compiler.CompileWorkflow and then t.Fatalf("Failed to compile workflow: %v", err) if it fails. With the new validation it will fail.

Fix: apply the same treatment used in this PR for all the other test files — add:

features:
  dangerously-disable-sandbox-agent: true

to the frontmatter strings in those two files.

🔎 Code quality review by PR Code Quality Reviewer · 7.01 AIC · ⌖ 13.6 AIC

t.Fatalf("Failed to write workflow file: %v", err)
}

compiler := NewCompiler()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fragile test: missing SetSkipValidation(true) breaks error-message assertion if the default changes.

Every other compiler := NewCompiler() in this file is immediately followed by compiler.SetSkipValidation(true) (lines 41-42, 93-94, 139-140). This test omits that call and silently inherits the current default (skipValidation: true, annotated in compiler_types.go as "for now").

💡 Why this is fragile

The test asserts the error message contains "dangerously-disable-sandbox-agent", which is only true when validateSandboxConfig is the first validator to fail. If skipValidation defaults change to false, schema validation runs first and can produce a different error (e.g. "missing required field: permissions"), causing the strings.Contains assertion to fail — masking the real reason.

Fix:

compiler := NewCompiler()
compiler.SetSkipValidation(true) // ensure schema validation is skipped so validateSandboxConfig fires first

…ges; remove misleading SetSkipValidation(true) from feature-flag test

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Addressed both actionable review threads:

  1. sandbox_validation.go:82-90 — replaced all three hardcoded 'dangerously-disable-sandbox-agent' strings with constants.DangerouslyDisableSandboxAgentFeatureFlag in the reason text, YAML suggestion, and log message.

  2. sandbox_agent_false_test.go:40-46 — removed the misleading compiler.SetSkipValidation(true) call from the positive feature-flag test. validateSandboxConfig runs unconditionally (not gated by skipValidation), so the feature-flag check is exercised regardless. A comment clarifies this. The negative test (TestSandboxAgentFalseRequiresFeatureFlag) was already consistent — it never set SetSkipValidation.

sandbox_agent_disabled_test.go uses SetSkipValidation(true) throughout to skip YAML schema validation (those tests assert compiled-YAML content, not validation behavior) — no changes needed there.

Commit: Use DangerouslyDisableSandboxAgentFeatureFlag constant in error messages; remove misleading SetSkipValidation(true) from feature-flag test

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@copilot review all comments and address the unresolved integration-test feedback in sandbox_agent_disabled_test.go and aw_info_steps_test.go.

Generated by 👨‍🍳 PR Sous Chef · 78.6 AIC · ⌖ 1.09 AIC · ⊞ 17.3K ·

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Please refresh the branch and rerun checks after those fixture updates.

Generated by 👨‍🍳 PR Sous Chef · 78.6 AIC · ⌖ 1.09 AIC · ⊞ 17.3K ·

@pelikhan pelikhan merged commit 0175f04 into main Jun 9, 2026
29 checks passed
@pelikhan pelikhan deleted the copilot/feature-dangerously-disable-sandbox-agent branch June 9, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants