Skip to content

fix: correct engine.env secrets warning — excluded from sandbox, not leaked#43302

Merged
pelikhan merged 6 commits into
mainfrom
copilot/fix-compiler-warning-for-secrets
Jul 4, 2026
Merged

fix: correct engine.env secrets warning — excluded from sandbox, not leaked#43302
pelikhan merged 6 commits into
mainfrom
copilot/fix-compiler-warning-for-secrets

Conversation

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

The compiler incorrectly warned that secrets in engine.env "will be leaked to the agent container" even though ComputeAWFExcludeEnvVarNames already auto-detects ${{ secrets. values in engine.env and adds them to AWF's --exclude-env list, keeping them out of the agent sandbox.

Changes

  • pkg/workflow/strict_mode_env_validation.govalidateEnvSecretsSection now emits section-aware messages:

    • engine.env non-strict warning: replaced "will be leaked" with "will be excluded from the agent sandbox via awf --exclude-env; the agent process itself will not see these values directly"
    • engine.env strict-mode error: replaced "will be leaked" with "are auto-excluded from the agent sandbox via awf --exclude-env and are not accessible to the agent" — still an error (strict mode enforces engine-specific config), but no longer a false leakage claim
    • Top-level env: messages unchanged — secrets there genuinely reach the agent container
  • pkg/workflow/env_secrets_validation_test.go — updated three engine.env strict-mode test assertions to match the corrected error message text

Before / After (non-strict, engine.env)

# Before
⚠ Warning: secrets detected in 'engine.env' section will be leaked to the agent container. Found: ${{ secrets.SOME_KEY }}. ...

# After
⚠ Warning: secrets detected in 'engine.env' section will be excluded from the agent sandbox via awf --exclude-env; the agent process itself will not see these values directly. Found: ${{ secrets.SOME_KEY }}. ...

Generated by 👨‍🍳 PR Sous Chef · 3.07 AIC · ⌖ 4.15 AIC · ⊞ 4.3K ·
Comment /souschef to run again

…m sandbox

The warning "will be leaked to the agent container" was factually incorrect
for engine.env secrets. ComputeAWFExcludeEnvVarNames already auto-detects
${{ secrets. values in engine.env and adds them to awf --exclude-env,
preventing them from reaching the agent sandbox.

Now validateEnvSecretsSection emits section-aware messages:
- engine.env (non-strict): "will be excluded from the agent sandbox via
  awf --exclude-env; the agent process itself will not see these values
  directly"
- engine.env (strict): "are auto-excluded from the agent sandbox via
  awf --exclude-env and are not accessible to the agent"
- top-level env: messages unchanged (secrets there genuinely leak)

Update tests to match the corrected engine.env error message strings.

Closes #42749

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix compiler warning for secret in engine.env fix: correct engine.env secrets warning — excluded from sandbox, not leaked Jul 4, 2026
Copilot AI requested a review from pelikhan July 4, 2026 04:47
@pelikhan

pelikhan commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot add test to ensure auto exclusion is enabled and functional

…exclusion

Adds a table-driven test for ComputeAWFExcludeEnvVarNames covering:
- engine.env var with a secret reference is auto-excluded
- engine.env var with no secret reference is not excluded
- mixed engine.env: only secret-backed vars are excluded
- engine.env secret combined with core engine secret vars
- engine.env secret embedded in a larger string value is excluded
- nil EngineConfig produces no extra exclusions beyond core secrets

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

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add test to ensure auto exclusion is enabled and functional

Added TestComputeAWFExcludeEnvVarNames in pkg/workflow/awf_helpers_test.go (committed in the latest push). It's a table-driven test covering 6 cases for ComputeAWFExcludeEnvVarNames:

  • engine.env var with a ${{ secrets.* }} value → auto-excluded
  • engine.env var with a plain value → not excluded
  • mixed engine.env: only secret-backed vars are excluded
  • engine.env secret combined with engine core secret vars (e.g. GEMINI_API_KEY)
  • engine.env secret embedded in a larger string (e.g. ****** secrets.TOKEN }}) → excluded
  • nil EngineConfig → no extra exclusions beyond core secrets

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Great fix! 👋 Correcting the false "will be leaked" warning for engine.env secrets is exactly the kind of accuracy improvement that matters — misleading security messages erode trust in tooling and cause unnecessary friction for users.

A few things stand out positively here:

  • Surgical scope — only validateEnvSecretsSection is touched in the production code (13 lines), with the top-level env path deliberately left unchanged because the distinction is semantically correct.
  • Tests updated and expanded — existing strict-mode assertions are corrected and awf_helpers_test.go gains 98 lines of coverage, giving the new message paths solid regression protection.
  • Clear before/after in the description — the diff in the PR body makes the intent immediately obvious to reviewers.

This PR looks ready for review. 🚀

Generated by ✅ Contribution Check · 104.3 AIC · ⌖ 12.5 AIC · ⊞ 6.3K ·

@pelikhan pelikhan marked this pull request as ready for review July 4, 2026 06:34
Copilot AI review requested due to automatic review settings July 4, 2026 06:34
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

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 corrects misleading secrets-validation messaging for engine.env so it no longer claims secrets “will be leaked” when the compiler is configured to exclude secret-bearing env vars from the agent sandbox via AWF --exclude-env.

Changes:

  • Updated validateEnvSecretsSection to emit section-aware strict-mode errors and non-strict warnings for engine.env, distinguishing it from top-level env.
  • Updated strict-mode engine.env test assertions to match the revised error message text.
  • Added unit coverage for ComputeAWFExcludeEnvVarNames to verify engine.env secrets are included in the --exclude-env list.
Show a summary per file
File Description
pkg/workflow/strict_mode_env_validation.go Adjusts strict/non-strict messaging for secrets found in engine.env vs other env sections.
pkg/workflow/env_secrets_validation_test.go Updates expected error-message substrings for strict-mode engine.env cases.
pkg/workflow/awf_helpers_test.go Adds tests validating ComputeAWFExcludeEnvVarNames behavior for engine.env secret detection and exclusion.

Review details

Tip

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Low

if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so they are not leaked, but strict mode still requires engine-specific configuration.
return fmt.Errorf("strict mode: secrets detected in 'engine.env' section are auto-excluded from the agent sandbox via awf --exclude-env and are not accessible to the agent. Found: %s. Use engine-specific secret configuration instead. See: https://github.github.com/gh-aw/reference/engines/", strings.Join(secretRefs, ", "))
if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so the warning should reflect that they are excluded, not leaked.
warningMsg = fmt.Sprintf("Warning: secrets detected in 'engine.env' section will be excluded from the agent sandbox via awf --exclude-env; the agent process itself will not see these values directly. Found: %s. Consider using engine-specific secret configuration instead.", strings.Join(secretRefs, ", "))
…essages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (114 new lines in pkg/workflow/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/43302-section-aware-secrets-validation-messages.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI could not infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-43302: Section-Aware Secrets Validation Messages

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 0042-use-postgresql.md for PR #42).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 37.4 AIC · ⌖ 7.17 AIC · ⊞ 8.4K ·
Comment /review to run again

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Summary

Applied /diagnosing-bugs, /tdd, and /codebase-design. Overall direction is correct — the old message was genuinely misleading — but there is one correctness gap and several test quality issues worth addressing before merge.

🔴 Blocking: version-gate accuracy

BuildAWFArgs silently skips --exclude-env for workflows pinned to AWF < v0.25.3. The new message ("are auto-excluded from the agent sandbox") is therefore factually wrong for old-pinned workflows. Consider qualifying both the strict-mode error and the non-strict warning with (requires AWF v0.25.3+), or checking the version inside validateEnvSecretsSection.

🟡 Non-blocking: test quality gaps
  1. AUTH_HEADER test (awf_helpers_test.go:1189): the literal "****** secrets.TOKEN }}" is missing the opening ${{, so it does not test the "embedded in a larger string" scenario the name implies.
  2. Non-strict warning text never verified (env_secrets_validation_test.go:574): expectError: false is the only assertion; the corrected message could silently regress.
  3. No agent.env test in TestComputeAWFExcludeEnvVarNames: the function also scans agent.env, but no case exercises that path.
  4. Duplicated "engine.env" string in two branches of strict_mode_env_validation.go — extract a named constant.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 107.8 AIC · ⌖ 5.96 AIC · ⊞ 6.6K ·
Comment /matt to run again

@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 /diagnosing-bugs, /tdd, and /codebase-design — requesting changes on a correctness gap and test quality.

📋 Key Themes & Highlights

Key Themes

  • Version-gate accuracy gap (correctness): The new reassuring messages say secrets "are auto-excluded" but BuildAWFArgs silently skips --exclude-env for AWF < v0.25.3. Workflows pinned to an old version would receive an inaccurate message — users could believe they are protected when they are not.
  • Misleading test case: The AUTH_HEADER embedded-secret test uses a literal without the opening ${{, so it is not actually testing the intended "embedded in a larger string" scenario.
  • Missing warning-message assertion: The non-strict engine.env test only checks expectError: false — the corrected warning text is never verified and could silently regress.
  • Missing agent.env coverage: ComputeAWFExcludeEnvVarNames also scans agent.env, but there is no corresponding test case.
  • Duplicated magic string: sectionName == "engine.env" appears in two separate branches with no named constant, creating a rename-hazard.

Positive Highlights

  • ✅ Root cause is correctly identified: the old message genuinely misrepresented the behaviour and could mislead users into thinking secrets were actively leaked.
  • ✅ Strict-mode guardrail preserved — still an error, just a factually accurate one.
  • ✅ Good table-driven test structure in TestComputeAWFExcludeEnvVarNames with clear want / notWant separation.
  • ✅ PR description is well-written with clear before/after examples.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 107.8 AIC · ⌖ 5.96 AIC · ⊞ 6.6K
Comment /matt to run again

if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so they are not leaked, but strict mode still requires engine-specific configuration.
return fmt.Errorf("strict mode: secrets detected in 'engine.env' section are auto-excluded from the agent sandbox via awf --exclude-env and are not accessible to the agent. Found: %s. Use engine-specific secret configuration instead. See: https://github.github.com/gh-aw/reference/engines/", strings.Join(secretRefs, ", "))

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.

[/diagnosing-bugs] The new message guarantees exclusion via --exclude-env, but BuildAWFArgs silently skips that flag for workflows pinned to AWF < v0.25.3 — so the claim is still factually wrong for old-pinned workflows.

💡 Suggested fix

Either qualify the message with a version condition, or have validateEnvSecretsSection receive the AWF version and vary the message:

// Option A: always mention the version requirement
return fmt.Errorf("strict mode: secrets detected in \u0027engine.env\u0027 section " +
    "are auto-excluded from the agent sandbox via awf --exclude-env (AWF v0.25.3+) "+
    "and are not accessible to the agent. Found: %s. ...", ...)

Without this, a workflow pinned to v0.24.x would get the reassuring new message while --exclude-env never runs, leaving the secrets visible to the agent.

See: pkg/workflow/awf_helpers.goawfSupportsExcludeEnv / AWFExcludeEnvMinVersion.

@copilot please address this.

workflowData: &WorkflowData{
EngineConfig: &EngineConfig{
Env: map[string]string{
"AUTH_HEADER": "Bearer ${{ secrets.TOKEN }}",

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 AUTH_HEADER test case uses "Bearer ${{ secrets.TOKEN }}" — but the actual literal in the file is "****** secrets.TOKEN }}" (missing the opening ${{), which still triggers the strings.Contains(envValue, "${{ secrets.") check in the implementation. The test name says "embedded in a larger string" but is actually testing detection without the full ${{ prefix — that is a different edge case than what the name implies.

💡 Suggestion

Rename and/or add a proper embedded-string variant:

{
    name: "engine.env secret bare prefix (missing opening) is NOT excluded",
    workflowData: &WorkflowData{
        EngineConfig: &EngineConfig{
            Env: map[string]string{
                "AUTH_HEADER": "Bearer secrets.TOKEN }}",  // no ${{, should not match
            },
        },
    },
    coreSecretVarNames: []string{},
    want:    []string{},
    notWant: []string{"AUTH_HEADER"},
},
{
    name: "engine.env secret embedded in larger string is excluded",
    workflowData: &WorkflowData{
        EngineConfig: &EngineConfig{
            Env: map[string]string{
                "AUTH_HEADER": "Bearer ${{ secrets.TOKEN }}",  // embedded, should match
            },
        },
    },
    coreSecretVarNames: []string{},
    want: []string{"AUTH_HEADER"},
},

@copilot please address this.

errorMsg: "strict mode: secrets detected in 'engine.env' section are auto-excluded from the agent sandbox via awf --exclude-env and are not accessible to the agent. Found: ${{ secrets.TOKEN }}",
},
{
name: "engine.env with secret in non-strict mode emits warning (no error)",

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 non-strict engine.env test only asserts expectError: false — the updated warning message text is never verified, so regressions to the new message would go undetected.

💡 Suggestion

Capture stderr in the test and assert the corrected message. The existing TestValidateEnvSecretsNonStrictMode uses the same pattern (no assertion on message) with a comment that stderr cannot be captured. Consider introducing a captureWarnings helper or redirect os.Stderr temporarily to verify the new message text:

var buf bytes.Buffer
old := os.Stderr
r, w, _ := os.Pipe()
os.Stderr = w
err := compiler.validateEnvSecrets(tt.frontmatter)
w.Close()
os.Stderr = old
io.Copy(&buf, r)
assert.NoError(t, err)
assert.Contains(t, buf.String(), "will be excluded from the agent sandbox via awf --exclude-env")
assert.NotContains(t, buf.String(), "will be leaked")

@copilot please address this.

if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so the warning should reflect that they are excluded, not leaked.
warningMsg = fmt.Sprintf("Warning: secrets detected in 'engine.env' section will be excluded from the agent sandbox via awf --exclude-env; the agent process itself will not see these values directly. Found: %s. Consider using engine-specific secret configuration instead.", strings.Join(secretRefs, ", "))

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.

[/diagnosing-bugs] The non-strict engine.env message is inconsistent with the strict-mode one: non-strict says "will be excluded" (future tense / conditional) while strict says "are auto-excluded" (present, definitive). Both share the same version-gate risk, but the different phrasing may confuse users who see one message in development and the other in CI.

💡 Suggestion

Aligning on the same phrasing and the same version caveat in both branches makes the UX clearer:

// strict
"are auto-excluded from the agent sandbox via awf --exclude-env (requires AWF v0.25.3+)"
// non-strict warning
"will be excluded from the agent sandbox via awf --exclude-env (requires AWF v0.25.3+)"

@copilot please address this.

@@ -1118,6 +1118,104 @@ func TestAWFSupportsExcludeEnv(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] TestComputeAWFExcludeEnvVarNames covers engine.env vars well, but has no test for agent.env vars (the function also scans agentConfig.Env for ${{ secrets. values). A regression there would be silent.

💡 Suggestion

Add one case:

{
    name: "agent.env secret var is auto-excluded",
    workflowData: &WorkflowData{
        AgentConfig: &AgentConfig{
            Env: map[string]string{
                "AGENT_TOKEN": "${{ secrets.AGENT_SECRET }}",
            },
        },
    },
    coreSecretVarNames: []string{},
    want: []string{"AGENT_TOKEN"},
},

This ensures the exclusion logic is symmetric for both engine.env and agent.env.

@copilot please address this.


// In strict mode, this is an error
if c.strictMode {
if sectionName == "engine.env" {

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.

[/codebase-design] The sectionName == "engine.env" string literal is repeated in two independent branches (lines 135 and 145). If engine.env is ever renamed in the call-site (e.g. to "engine.environment"), both branches need updating but the compiler won’t catch it.

💡 Suggestion

Extract the constant or pass a boolean:

const engineEnvSection = "engine.env"

// or — simpler — let the caller pass isEngineEnv bool so the function signature
// makes the branching intent explicit and can be tested with a boolean instead
// of a magic string.

This also keeps the function focused on validation rather than section naming conventions.

@copilot please address this.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 87/100 — Excellent

Analyzed 9 test scenario(s): 9 design, 0 implementation, 0 violation(s).

📊 Metrics (9 test scenarios)
Metric Value
Analyzed 9 (Go: 9, JS: 0)
✅ Design 9 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 5 (56%)
Duplicate clusters 0
Inflation NO
🚨 Violations 0
Test File Classification Issues
engine.env secret var is auto-excluded awf_helpers_test.go design_test
engine.env non-secret var is not excluded awf_helpers_test.go design_test (edge)
engine.env mixes secret and non-secret vars awf_helpers_test.go design_test (edge)
engine.env secret combined with core secret vars awf_helpers_test.go design_test (edge)
engine.env secret embedded in a larger string is excluded awf_helpers_test.go design_test (edge)
nil engine config produces no exclusions beyond core secrets awf_helpers_test.go design_test (null/edge)
Error message accuracy test x3 (modified) env_secrets_validation_test.go design_test (behavioral contract)

Verdict

Passed. 0% implementation tests (threshold: 30%). No violations.

Notes:

  • TestComputeAWFExcludeEnvVarNames (awf_helpers_test.go) is a new, well-structured table-driven test. It covers the happy path, the negative case (non-secret vars must NOT be excluded), mixed values, combined core+engine secrets, embedded-string detection, and nil config. All assertions include descriptive failure messages — exemplary.
  • The 3 modified cases in env_secrets_validation_test.go update expected error strings to match the corrected message. The message change from "will be leaked" to "are auto-excluded" is the core behavioral contract under fix; verifying its accuracy provides meaningful regression protection.
  • Build tags //go:build !integration present on line 1 of both files. No Go mock libraries used.
  • Inflation: the new test adds 98 lines against 0 changed production lines. This is not penalized — the test establishes a behavioral baseline that supports the documentation fix.
  • ⚠️ Minor: the test value for the "embedded in a larger string" case appears as "****** secrets.TOKEN }}" in diffs (not ${{...}}). Verify the actual file bytes match the strings.Contains(varValue, "${{ secrets.") detection in awf_helpers.go:918 to ensure the test actually exercises that code path.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 122 AIC · ⌖ 10.9 AIC · ⊞ 6.8K ·
Comment /review to run again

@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.

✅ Test Quality Sentinel: 87/100. 0% implementation tests (threshold: 30%). No violations. 9/9 test scenarios classified as design_test with edge coverage across secret-detection, negative, mixed, combined, embedded, and nil-config paths.

@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.

Review: fix: correct engine.env secrets warning

The core logic change in strict_mode_env_validation.go is correct and well-motivated — the old messages falsely claimed engine.env secrets would be leaked when they're already auto-excluded via --exclude-env. The test updates in env_secrets_validation_test.go align cleanly with the new message text.

One blocking bug in the new test file and one minor docstring gap need addressing.

🔴 Bug: new test assertion will always fail

In awf_helpers_test.go, the test case "engine.env secret embedded in a larger string is excluded" sets:

"AUTH_HEADER": "****** secrets.TOKEN }}",

ComputeAWFExcludeEnvVarNames detects secrets via:

if strings.Contains(varValue, "${{ secrets.") {

The test value does not contain "${{ secrets." (it starts with asterisks, not ${{), so AUTH_HEADER will never be added to the exclude list and assert.Contains(t, got, "AUTH_HEADER") will fail.

Fix: change the test value to something like "Bearer ${{ secrets.TOKEN }}" which does contain the required prefix.

⚠️ Minor: stale docstring

The validateEnvSecrets function comment still reads "Secrets in env will be leaked to the agent container" without acknowledging that engine.env secrets are auto-excluded. The inline comment in the body correctly explains this, but the function-level doc should be updated too for clarity.

What's good
  • The split-message logic (strict vs. non-strict, engine.env vs. top-level env) is clean and correct.
  • The new TestComputeAWFExcludeEnvVarNames test function covers important cases (mixed secret/non-secret vars, nil engine config, core secret passthrough).
  • The env_secrets_validation_test.go message-text updates are accurate.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 170.2 AIC · ⌖ 6.14 AIC · ⊞ 4.9K

Comments that could not be inline-anchored

pkg/workflow/awf_helpers_test.go:1189

Bug: test value will not trigger --exclude-env detection

The value &quot;****** secrets.TOKEN }}&quot; (asterisks prefix, no ${{...) does not contain &quot;${{ secrets.&quot;, so it won't match the strings.Contains(varValue, &quot;${{ secrets.&quot;) check in ComputeAWFExcludeEnvVarNames. As a result, AUTH_HEADER will not be added to the exclude list and this test assertion will fail.

To test a secret embedded in a larger string that is still detected, use a value that contains the literal `$…

pkg/workflow/strict_mode_env_validation.go:18

Stale docstring: still says secrets "will be leaked"

The function-level comment still reads:

> Secrets in env will be leaked to the agent container.

This was accurate for the top-level env section but now misleads readers about engine.env, which was the whole point of this fix. Consider updating to something like:

// validateEnvSecrets detects secrets in the top-level env section and the engine.env section,
// raising an error in strict mode or a warning in non-strict mode. …

</details>

@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 message-correctness issues and one test-coverage gap must be addressed.

📋 Findings summary

High — False guarantee in non-strict warning (line 148, strict_mode_env_validation.go)

The warning claims the secret will be excluded via --exclude-env, but that flag is only emitted when AWF ≥ v0.25.3 (awfSupportsExcludeEnv). Workflows that pin an older version get --env-all with no exclusion — and this message. The message needs to either hedge on version or be gated by actual version information.

Medium — Contradictory strict-mode error message (line 138, strict_mode_env_validation.go)

The error simultaneously asserts the secret is safe ("not accessible to the agent") and blocks the build. Users cannot understand why they need to act. The rationale — raw value still visible in source and to the host runner — must be stated explicitly.

Low — Empty want list produces no positive assertions (line 1155, awf_helpers_test.go)

The non-secret test case uses want: []string{}, so the assertion loop body never runs. An assert.Empty on got is needed to actually verify the exclusion list is empty.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · 222.3 AIC · ⌖ 5.46 AIC · ⊞ 5.4K
Comment /review to run again

if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so the warning should reflect that they are excluded, not leaked.
warningMsg = fmt.Sprintf("Warning: secrets detected in 'engine.env' section will be excluded from the agent sandbox via awf --exclude-env; the agent process itself will not see these values directly. Found: %s. Consider using engine-specific secret configuration instead.", strings.Join(secretRefs, ", "))

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.

False guarantee for workflows pinning old AWF: The warning unconditionally tells users their secret "will be excluded from the agent sandbox via awf --exclude-env", but BuildAWFArgs only emits --exclude-env when awfSupportsExcludeEnv(firewallConfig) returns true (requires AWF ≥ v0.25.3). For workflows that pin an older AWF version, --env-all still injects the secret into the container and this claim is factually wrong.

💡 Suggested fix

validateEnvSecretsSection has no access to firewallConfig, so it cannot verify the version at warning time. Two options:

Option A — hedge on version in the message:

warningMsg = fmt.Sprintf(
    "Warning: secrets detected in 'engine.env' section. On AWF >= v0.25.3 these "+
    "are auto-excluded via --exclude-env; on older pinned AWF versions the secret "+
    "still reaches the container. Found: %s. Consider using engine-specific "+
    "secret configuration instead.",
    strings.Join(secretRefs, ", "))

Option B — thread firewallConfig (or a excludeEnvSupported bool) into validateEnvSecretsSection so the message can be dynamically accurate.

Without a fix, a user on AWF v0.25.0 who sees this warning will believe their secret is sandboxed when it is not.

if sectionName == "engine.env" {
// engine.env secrets are auto-excluded from the agent sandbox via awf --exclude-env,
// so they are not leaked, but strict mode still requires engine-specific configuration.
return fmt.Errorf("strict mode: secrets detected in 'engine.env' section are auto-excluded from the agent sandbox via awf --exclude-env and are not accessible to the agent. Found: %s. Use engine-specific secret configuration instead. See: https://github.github.com/gh-aw/reference/engines/", strings.Join(secretRefs, ", "))

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.

Contradictory strict-mode error message: The error tells users their secret is safe ("auto-excluded... not accessible to the agent") but then returns an error blocking the build. Users will be confused about why they need to change anything if the secret is already protected.

💡 Suggested fix

The message should explain why strict mode still rejects this pattern despite runtime exclusion — e.g., the raw secret value still appears in the workflow file, is accessible to the host process before AWF is invoked, and strict mode enforces engine-specific configuration for defence in depth:

return fmt.Errorf(
    "strict mode: secrets detected in 'engine.env' section. "+
    "While these are excluded from the agent sandbox at runtime (via awf --exclude-env), "+
    "the raw secret value is still exposed in the workflow source and to the host runner process. "+
    "Strict mode requires engine-specific secret configuration to avoid any exposure. "+
    "Found: %s. See: https://github.github.com/gh-aw/reference/engines/",
    strings.Join(secretRefs, ", "))

This removes the contradiction and gives the user a clear reason to act.

},
},
coreSecretVarNames: []string{},
want: []string{},

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.

Empty want slice produces zero positive assertions: When want: []string{}, the assertion loop body never executes — nothing is verified about the returned slice being empty. If ComputeAWFExcludeEnvVarNames accidentally returned non-empty results for plain-value vars, this test would still pass.

💡 Suggested fix

Add an explicit emptiness check after the loop:

if len(tt.want) == 0 {
    assert.Empty(t, got, "expected exclude list to be empty")
}

Or fold it into the loop by asserting assert.Empty whenever the want list is nil/empty. Either way, the test should fail when the production code returns unexpected entries for non-secret env vars.

@pelikhan

pelikhan commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

/souschef

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Sous Chef finished PR sous-chef nudges.

processed=5; skipped_checks_running=3; skipped_last_comment_from_sous_chef=1; skipped_cooldown=0; nudged=1; branch_update_attempts=0; formatter_pushes=0; merge_main_scheduled=0

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟢 Low
Score 58 / 100
Action fast_track

Score breakdown: Impact 28 (corrects misleading 'secrets will be leaked' compiler warning) + Urgency 16 + Quality 14 (good description, tests updated)

⚠️ CHANGES_REQUESTED by github-actions[bot]: two message-correctness issues and a test-coverage gap flagged. Author needs to address before merge.

Corrects false 'will be leaked' warning for engine.env secrets — they are auto-excluded from sandbox via --exclude-env. +187/-4 lines with test updates.

Generated by 🔧 PR Triage Agent · 82.8 AIC · ⌖ 8.09 AIC · ⊞ 5.5K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.
Unresolved review follow-up to address (newest first):

  • github-actions:
  • github-actions:
  • copilot-pull-request-reviewer:

Generated by 👨‍🍳 PR Sous Chef · 3.07 AIC · ⌖ 4.15 AIC · ⊞ 4.3K ·
Comment /souschef to run again

…requirement

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.
Unresolved review follow-up to address (newest first):

  • github-actions...

Addressed the two unresolved reviewer threads in commit fix: qualify engine.env exclusion messages with AWF v0.25.3+ version requirement:

  • Strict-mode error (line 138): now reads "…are excluded from the agent sandbox via awf --exclude-env (requires AWF v0.25.3+) and are not accessible to the agent when that version is in use."
  • Non-strict warning (line 148): now reads "…will be excluded from the agent sandbox via awf --exclude-env (requires AWF v0.25.3+); on older AWF versions the agent process will see these values."

Both messages use constants.AWFExcludeEnvMinVersion so they stay in sync if the constant ever changes. Tests updated to match and all pass locally.

CI needs a human re-trigger (close/reopen or workflow_dispatch) since agent pushes don't re-run workflows.

Copilot AI requested a review from gh-aw-bot July 4, 2026 10:43
@pelikhan pelikhan merged commit bfe9bda into main Jul 4, 2026
29 checks passed
@pelikhan pelikhan deleted the copilot/fix-compiler-warning-for-secrets branch July 4, 2026 10:58
@github-actions github-actions Bot mentioned this pull request Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiler warns secret in engine.env "will be leaked" even when it's correctly auto-excluded from the sandbox

4 participants