Skip to content

fix: legacy-security mode installs awf non-rootless, uses plain sudo for log parsing - #48098

Open
pelikhan with Copilot wants to merge 10 commits into
mainfrom
copilot/legacy-security-enable-emits-sudo-e-awf
Open

fix: legacy-security mode installs awf non-rootless, uses plain sudo for log parsing#48098
pelikhan with Copilot wants to merge 10 commits into
mainfrom
copilot/legacy-security-enable-emits-sudo-e-awf

Conversation

Copilot AI commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

legacy-security: enable opts the agent job into sudo -E awf, but the install step unconditionally passed --rootless when NetworkIsolation=true (the default), placing the binary in ~/.local/bin — outside sudo's secure_path. Result: agent startup fails with sudo: awf: command not found. The print_firewall_logs.sh step had the same logic flaw.

Changes

  • pkg/workflow/copilot_engine_installation.gogenerateAWFInstallationStep: skip --rootless when agentConfig.LegacySecurity is true, so the binary lands in /usr/local/bin
  • pkg/workflow/engine_firewall_support.gogenerateFirewallLogParsingStep: skip --rootless when LegacySecurity is true; AWF already has full sudo access in this mode
  • .github/workflows/smoke-service-ports.lock.yml — regenerated (this workflow was already using legacy-security: enable and was silently broken)
  • Tests added for both functions covering the LegacySecurity=true + NetworkIsolation=true combination, plus an end-to-end compilation test

The condition in both places went from:

if agentConfig != nil && agentConfig.NetworkIsolation && !agentConfig.Disabled {

to:

if agentConfig != nil && agentConfig.NetworkIsolation && !agentConfig.Disabled && !agentConfig.LegacySecurity {

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 23.1 AIC · ⌖ 6.65 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.98 AIC · ⌖ 8.12 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30240308794

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 23.9 AIC · ⌖ 8.09 AIC · ⊞ 7.1K ·
Comment /souschef to run again


pr-sous-chef run: https://github.com/github/gh-aw/actions/runs/30259748826

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 3.73 AIC · ⌖ 8.62 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 13.7 AIC · ⌖ 7.37 AIC · ⊞ 7.1K ·
Comment /souschef to run again


pr-sous-chef run: https://github.com/github/gh-aw/actions/runs/30293408015

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 28.1 AIC · ⌖ 8.01 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30304405147

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 15.2 AIC · ⌖ 6.68 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 15.5 AIC · ⌖ 7.12 AIC · ⊞ 7.1K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 5.67 AIC · ⌖ 5.66 AIC · ⊞ 7.1K ·
Comment /souschef to run again

Copilot AI and others added 2 commits July 26, 2026 03:29
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…do for log parsing

When `legacy-security: enable` is set, the AWF execution step correctly uses
`sudo -E awf` (which requires the binary to be in sudo's secure_path, i.e.
/usr/local/bin). However, two other steps incorrectly added `--rootless`:

1. The `install_awf_binary.sh` step passed `--rootless` (installing to
   ~/.local/bin), making `sudo awf` fail with "command not found".
2. The `print_firewall_logs.sh` step passed `--rootless` (using non-interactive
   sudo with a non-sudo fallback), even though AWF had full sudo access.

Fix: In both `generateAWFInstallationStep` and `generateFirewallLogParsingStep`,
skip `--rootless` when `LegacySecurity` is true, even if `NetworkIsolation` is
also true (which is the default).

This also fixes the compiled `.github/workflows/smoke-service-ports.lock.yml`
which already used `legacy-security: enable`.

Closes #47804

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix agent startup failure due to legacy security mode fix: legacy-security mode installs awf non-rootless, uses plain sudo for log parsing Jul 26, 2026
Copilot AI requested a review from pelikhan July 26, 2026 03:44
@pelikhan
pelikhan marked this pull request as ready for review July 26, 2026 03:46
@pelikhan
pelikhan requested review from Copilot and lpcox and removed request for Copilot July 26, 2026 03:46
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

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

The fix is correct and well-scoped. Both generateAWFInstallationStep and generateFirewallLogParsingStep now correctly skip --rootless when LegacySecurity is true, matching the documented behavior that sudo -E awf requires the binary in sudos secure_path. The reuse of getAgentConfig in engine_firewall_support.go is consistent with the existing pattern. Tests cover the unit cases and an end-to-end compilation check.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 17.4 AIC · ⌖ 5.14 AIC · ⊞ 5K

@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 — one minor observation on the new code; no blocking issues.

📋 Key Themes & Highlights

Findings

  • Dead nil guard (engine_firewall_support.go:139): the agentCfg == nil branch is unreachable — see inline comment.

Positive Highlights

  • ✅ Root cause correctly identified and fixed in both affected callsites
  • ✅ Regression tests added for the LegacySecurity=true + NetworkIsolation=true combination in three different test files
  • ✅ End-to-end compilation test (TestLegacySecurityInstallNonRootless) verifies the lock file output end-to-end
  • smoke-service-ports.lock.yml regenerated — confirming the previously silently broken workflow is now correct
  • ✅ Comment in copilot_engine_installation.go clearly documents the sudo secure_path constraint

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 26.1 AIC · ⌖ 4.67 AIC · ⊞ 6.7K
Comment /matt to run again

Comment thread pkg/workflow/engine_firewall_support.go Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Design Decision Gate — ADR Required

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

Draft ADR committed: docs/adr/48098-legacy-security-awf-install-non-rootless.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-48098: Legacy-Security Mode Installs AWF to Non-Rootless Path

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

Why ADRs Matter

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 🏗️ · sonnet46 · 50.8 AIC · ⌖ 10 AIC · ⊞ 8.5K ·
Comment /review to run again

Copilot AI review requested due to automatic review settings July 26, 2026 04:11

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.

Copilot was unable to review this pull request because there is no eligible user to bill. To allow Copilot reviews on bot-authored pull requests, enable direct organization billing in your organization's Copilot settings.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 70/100 — Acceptable

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

📊 Metrics (6 tests)
Metric Value
Analyzed 6 (Go: 6, JS: 0)
✅ Design 6 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 0 (0%)
Duplicate clusters 0
Inflation N/A (integration tests)
🚨 Violations 0
Test File Classification Coverage
TestGenerateFirewallLogParsingStepFixesFirewallPermissions engine_firewall_support_test.go:273 design_test, behavioral_contract Firewall logs preservation
TestGenerateFirewallLogParsingStepNetworkIsolationOmitsSudo engine_firewall_support_test.go:293 design_test, behavioral_contract Network isolation + rootless
TestGenerateFirewallLogParsingStepWithNetworkIsolationFalse engine_firewall_support_test.go:312 design_test, behavioral_contract Explicit false boundary
TestGenerateFirewallLogParsingStepLegacySecurityOmitsRootless engine_firewall_support_test.go:334 design_test, behavioral_contract Core fix: legacy-security mode
TestCustomAWFConfiguration (legacy-security subtest) sandbox_custom_agent_test.go:103 design_test, behavioral_contract Core fix: AWF install path
TestLegacySecurityInstallNonRootless sandbox_network_isolation_rootless_test.go:146 design_test, behavioral_contract Core fix: non-rootless install
⚠️ Quality Concern: No Error/Edge Case Testing

All 6 tests verify happy-path behavior only:

  • ✅ Firewall step generation with valid configs
  • ✅ AWF installation step generation with valid configs
  • ✅ Compilation succeeds with legacy-security mode

Missing:

  • ❌ Compilation error handling
  • ❌ Invalid configuration validation
  • ❌ Missing required fields
  • ❌ Error message assertions

Impact: While these tests provide excellent coverage of the intended behavior (the PR's core feature — legacy-security mode handling), they don't guard against misuse (invalid configs, missing setup steps). Consider adding error-case tests in a follow-up to strengthen robustness.

Verdict

passed. 0% implementation tests (threshold: 30%). All tests are design-level behavioral contracts covering the core feature (legacy-security mode installation and log-parsing). No coding violations detected.

Note: Test inflation ratio (19.5:1) is legitimately high for integration tests that write temporary files and compile workflows, but not counted against the score.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 27.1 AIC · ⌖ 10.3 AIC · ⊞ 8.1K ·
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: 70/100. 0% implementation tests (threshold: 30%). All tests are design-level behavioral contracts covering the core feature (legacy-security mode installation and log-parsing).

@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: legacy-security non-rootless install fix

The core fix is correct — LegacySecurity mode must install AWF to /usr/local/bin (non-rootless) so sudo -E awf can find it, and the firewall log parsing step must match. Two issues flagged; neither is a blocker but one warrants attention.

Findings

Medium — Dead nil guard in engine_firewall_support.go:139

The agentCfg == nil branch in (agentCfg == nil || !agentCfg.LegacySecurity) is unreachable. isAWFNetworkIsolationEnabled already returns false when agentConfig is nil, so the outer && short-circuits before the inner || is evaluated. This is not a correctness bug today, but it misleads readers and could silently regress if isAWFNetworkIsolationEnabled is refactored. See inline comment.

Low — TestLegacySecurityInstallNonRootless relies on implicit network-isolation defaults

The test frontmatter does not declare network-isolation: true explicitly, meaning the test only exercises the LegacySecurity exception if network isolation happens to be the default. See inline comment.

Out-of-diff observation (no comment posted)

Other callers of isAWFNetworkIsolationEnabled — notably difc-proxy host selection in awf_helpers.go:738 and compiler_difc_proxy.go:266/585 — do not have a LegacySecurity exception. For legacy-security+network-isolation, AWF runs on the host network (non-rootless), so the difc-proxy should route via host.docker.internal rather than awmg-cli-proxy. This PR does not touch those files; worth a follow-up issue.

🔎 Code quality review by PR Code Quality Reviewer · sonnet46 · 63.7 AIC · ⌖ 4.87 AIC · ⊞ 5.7K
Comment /review to run again

Comment thread pkg/workflow/engine_firewall_support.go Outdated
Comment thread pkg/workflow/sandbox_network_isolation_rootless_test.go
@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟡 medium
Priority Score 70 / 100
Score Breakdown Impact: 35 · Urgency: 22 · Quality: 13
Recommended Action ⚡ fast_track

Summary: legacy-security: enable users get sudo: awf: command not found because the install unconditionally uses --rootless, placing the binary outside secure_path. Fix is targeted and correct; multiple AI reviewer APPROVALs (github-actions[bot]). No open CHANGES_REQUESTED in latest round.

Next action: Fast-track — ready for human approval and merge.

Generated by 🔧 PR Triage Agent · sonnet46 · 49 AIC · ⌖ 8.25 AIC · ⊞ 5.7K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@lpcox review please

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, verify whether any reviewer feedback or ADR/body follow-up still blocks this PR, and summarize the current maintainer-visible blocker set.

Recent context:

  • latest human comment asks for maintainer review
  • checks on the current head look green from the visible rollup

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 23.9 AIC · ⌖ 8.09 AIC · ⊞ 7.1K ·
Comment /souschef to run again

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟡 medium
Priority Score 60 / 100
Recommended Action ⚡ fast_track
CI Status 🟡 in-progress (19 pass, 0 fail of 26)

Score breakdown: Impact 30/50 · Urgency 16/30 · Quality 14/20

Rationale: legacy-security: enable mode broken — binary installed rootless but invoked as sudo awf, causing ENOENT. Targeted fix (164+/5−, 7 files). AI reviewer approved (Test Quality 70/100). Affects users who have opted into legacy-security mode specifically.

Run §30246015734

Generated by 🔧 PR Triage Agent · sonnet46 · 36.5 AIC · ⌖ 5.31 AIC · ⊞ 5.7K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@lpcox can we merge "sudo" mode with "legacy-security"?

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address the unresolved review feedback below, and then reply with whether this PR is ready for maintainer review.

Unresolved review feedback / follow-up (newest first):

Recent maintainer context:

Run: https://github.com/github/gh-aw/actions/runs/30259748826

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 3.73 AIC · ⌖ 8.62 AIC · ⊞ 7.1K ·
Comment /souschef to run again

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

Copilot AI commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address the unresolved review feedback below, and then reply with whether this PR is ready for maintainer review.

Unresolved review feedback / follow-up (...

Addressed the three unresolved github-actions review comments in commit bb2db96:

  • removed the unreachable nil-guard in /home/runner/work/gh-aw/gh-aw/pkg/workflow/engine_firewall_support.go
  • made the legacy-security test explicitly network-isolated via sandbox.agent.sudo: false in /home/runner/work/gh-aw/gh-aw/pkg/workflow/sandbox_network_isolation_rootless_test.go
  • replied on each review thread comment.

Validation:

  • make agent-report-progress passed
  • make test passed
  • parallel_validation returned no review findings and no CodeQL alerts.

Current maintainer-visible blockers: PR API currently reports mergeable_state: dirty, and CI on the latest head is unverified until a maintainer re-triggers workflows (agent pushes do not trigger CI).

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, verify whether the latest maintainer question about merging "sudo" mode with "legacy-security" still needs a code or design follow-up, and reply with the current maintainer-visible blocker set.

Recent maintainer context:

Run: https://github.com/github/gh-aw/actions/runs/30264173356

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 13.7 AIC · ⌖ 7.37 AIC · ⊞ 7.1K ·
Comment /souschef to run again

Copilot AI commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, verify whether the latest maintainer question about merging "sudo" mode with "legacy-security" still needs a code or design follow-up, and reply with the c...

Current status after triage:

  • The maintainer question about merging sudo mode with legacy-security still appears to be a design follow-up (no new code change in this PR addresses that unification).
  • For this bugfix PR, the implementation and tests for the legacy-security rootless/sudo-path issue are already in place at bb2db96.

Maintainer-visible blockers right now:

  1. PR API still reports mergeable_state: dirty.
  2. CI on the latest head is not yet a fresh green signal from a maintainer-triggered run (latest branch run is in progress; prior referenced run 30264173356 had no failed jobs).
  3. One review thread remains open in GitHub UI (addressed by reply, but not marked resolved).

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage Report

Field Value
Category bug
Risk Medium
Priority Score 82/100
Recommended Action fast_track

Score Breakdown:

  • Impact: 40/50 — Fixes agent startup failure in legacy-security mode; critical-path for affected users
  • Urgency: 25/30 — Bug causes hard failure, CI passing, PR is 1 day old
  • Quality: 17/20 — Excellent description with root cause analysis, ADR included, tests added

CI Status: ✅ Passing (copilot check: success)

Reviews: APPROVED (x2 by github-actions[bot])

Notes: Well-documented bug fix with ADR, test coverage, and clear root cause. CI passes. Approved by automation. Ready for human fast-track review.

Generated by 🔧 PR Triage Agent · sonnet46 · 29 AIC · ⌖ 7.59 AIC · ⊞ 5.7K ·

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk medium
Score 76/100 (impact:35, urgency:25, quality:16)
Action fast_track

Carry-over (1 day old). Fixes legacy-security: enable installing AWF rootlessly, making it unreachable via sudo. Agent startup fails. High urgency — users of legacy-security mode are broken.

Generated by 🔧 PR Triage Agent · sonnet46 · 54.1 AIC · ⌖ 8.18 AIC · ⊞ 5.7K ·

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟡 medium
Score 60/100 (impact:30 urgency:18 quality:12)
Action fast_track

legacy-security mode broken: installs awf non-rootless causing EACCES failures. Fix is targeted (165 adds, 5 dels, 7 files). AI reviewer approved. Carry-over from prior run.

Generated by 🔧 PR Triage Agent · sonnet46 · 63.9 AIC · ⌖ 5.94 AIC · ⊞ 5.7K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts on this branch.

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

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts on this branch.

Resolved on commit 4bb0af6dfa by merging origin/main into this branch and fixing the conflict in /home/runner/work/gh-aw/gh-aw/.github/workflows/smoke-service-ports.lock.yml (kept AWF v0.27.42 while preserving non-rootless install behavior for legacy-security). Local validation passed via make agent-report-progress.

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.

legacy-security: enable emits sudo -E awf but installs awf with --rootless, so the agent fails at startup with sudo: awf: command not found

4 participants