Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 9, 2026

Fix detection job permissions: {} preventing actions/checkout from succeeding

Problem

The detection job had permissions: {} but included a checkout step when running in dev/script mode, causing a 404 error because the GITHUB_TOKEN had no contents: read permission.

Solution

  • Add test to verify detection job gets contents: read permission when checkout is needed
  • Update buildThreatDetectionJob to conditionally set permissions based on whether checkout is needed
  • Follow the same pattern used in pre-activation job (check actionMode.IsDev() || actionMode.IsScript())
  • Update existing test to account for new behavior
  • Recompile all workflows
  • Verify fix with tests
  • Address PR feedback (use existing helper, fix linter issues)
  • Run make agent-finish before committing

Changes

  1. pkg/workflow/threat_detection.go: Updated buildThreatDetectionJob to check if checkout is needed and set contents: read permission accordingly
  2. pkg/workflow/detection_permissions_test.go: Added comprehensive tests for both dev mode (with checkout) and release mode (without checkout), now uses existing extractJobSection helper
  3. pkg/workflow/threat_detection_test.go: Updated existing test expectations to account for conditional permissions
  4. All .lock.yml files: Recompiled with correct permissions
Original prompt

This section details on the original issue you should resolve

<issue_title>Detection job permissions: {} prevents actions/checkout from succeeding</issue_title>
<issue_description>## Description

When compiling a workflow with gh aw compile, the generated detection job sets permissions: {} (no scopes), but also injects a Checkout main repo step using actions/checkout. This checkout step fails with a 404 "repository not found" error because the GITHUB_TOKEN has no contents: read permission.

The agent job in the same compiled workflow correctly sets permissions: contents: read, and its checkout step succeeds.

Steps to Reproduce

  1. Create any workflow .md file with permissions: contents: read and an engine using copilot
  2. Run gh aw compile
  3. Inspect the generated .lock.yml — the detection job has:
    detection:
      permissions: {}
      steps:
        # ...
        - name: Checkout main repo
          uses: actions/checkout@v5
  4. Push and trigger the workflow
  5. The detection job fails at the checkout step with a 404

Expected Behavior

The detection job should either:

  • Set permissions: contents: read (since it injects a checkout step that requires it), or
  • Not inject a checkout step if it intends to run with no permissions

Actual Behavior

The checkout step fails because permissions: {} means the GITHUB_TOKEN has zero scopes. GitHub returns a 404 (not 403) for security reasons.

Environment

  • gh-aw CLI version: v0.42.17 (also reproduced on v0.42.13)
  • Engine: copilot</issue_description>

Comments on the Issue (you are @copilot in this section)

@pelikhan Would it be possible to share a repro? The checkout should only happen in dev mode, not in release mode.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


Changeset

  • Type: patch
  • Description: Ensure the detection job requests contents: read whenever it injects actions/checkout, mirroring the agent job permissions.

Generated by Changeset Generator

- Detection job now gets `contents: read` permission when running in dev/script mode (where checkout is needed)
- In release mode (no checkout needed), detection job continues to use empty permissions
- Added test to verify detection job permissions in both dev and release modes
- Updated existing test to account for new permission behavior
- Recompiled all workflows with correct permissions

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix permissions in detection job for actions/checkout Fix detection job checkout failure from missing contents permission Feb 9, 2026
Copilot AI requested a review from pelikhan February 9, 2026 23:40
@pelikhan pelikhan marked this pull request as ready for review February 9, 2026 23:42
Copilot AI review requested due to automatic review settings February 9, 2026 23:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a permissions mismatch in the compiled “detection” job: when dev/script mode injects an actions/checkout step (“Checkout actions folder”), the job now receives contents: read instead of permissions: {}, preventing checkout failures due to an unscoped GITHUB_TOKEN.

Changes:

  • Update detection job permission rendering to conditionally set contents: read only when the checkout-actions-folder step is present (dev/script modes).
  • Update existing threat detection job unit test expectations to reflect the new permission behavior.
  • Add focused regression tests for detection job permissions in dev vs release mode and regenerate affected compiled workflow lock files.

Reviewed changes

Copilot reviewed 141 out of 141 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/workflow/threat_detection.go Conditionally renders detection job permissions (contents: read only when local actions checkout is injected).
pkg/workflow/threat_detection_test.go Updates expected permissions for the detection job based on action mode.
pkg/workflow/detection_permissions_test.go Adds regression tests validating detection job permissions with/without checkout.
.github/workflows/workflow-skill-extractor.lock.yml Detection job now has permissions: contents: read.
.github/workflows/workflow-normalizer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/workflow-health-manager.lock.yml Detection job now has permissions: contents: read.
.github/workflows/workflow-generator.lock.yml Detection job now has permissions: contents: read.
.github/workflows/weekly-issue-summary.lock.yml Detection job now has permissions: contents: read.
.github/workflows/video-analyzer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/unbloat-docs.lock.yml Detection job now has permissions: contents: read.
.github/workflows/ubuntu-image-analyzer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/typist.lock.yml Detection job now has permissions: contents: read.
.github/workflows/tidy.lock.yml Detection job now has permissions: contents: read.
.github/workflows/test-project-url-default.lock.yml Detection job now has permissions: contents: read.
.github/workflows/test-dispatcher.lock.yml Detection job now has permissions: contents: read.
.github/workflows/test-create-pr-error-handling.lock.yml Detection job now has permissions: contents: read.
.github/workflows/terminal-stylist.lock.yml Detection job now has permissions: contents: read.
.github/workflows/technical-doc-writer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/super-linter.lock.yml Detection job now has permissions: contents: read.
.github/workflows/sub-issue-closer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/step-name-alignment.lock.yml Detection job now has permissions: contents: read.
.github/workflows/static-analysis-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/stale-repo-identifier.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-test-tools.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-project.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-opencode.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-copilot.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-codex.lock.yml Detection job now has permissions: contents: read.
.github/workflows/smoke-claude.lock.yml Detection job now has permissions: contents: read.
.github/workflows/slide-deck-maintainer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/sergo.lock.yml Detection job now has permissions: contents: read.
.github/workflows/semantic-function-refactor.lock.yml Detection job now has permissions: contents: read.
.github/workflows/security-review.lock.yml Detection job now has permissions: contents: read.
.github/workflows/security-guard.lock.yml Detection job now has permissions: contents: read.
.github/workflows/security-compliance.lock.yml Detection job now has permissions: contents: read.
.github/workflows/scout.lock.yml Detection job now has permissions: contents: read.
.github/workflows/schema-consistency-checker.lock.yml Detection job now has permissions: contents: read.
.github/workflows/safe-output-health.lock.yml Detection job now has permissions: contents: read.
.github/workflows/research.lock.yml Detection job now has permissions: contents: read.
.github/workflows/repository-quality-improver.lock.yml Detection job now has permissions: contents: read.
.github/workflows/repo-tree-map.lock.yml Detection job now has permissions: contents: read.
.github/workflows/repo-audit-analyzer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/release.lock.yml Detection job now has permissions: contents: read.
.github/workflows/q.lock.yml Detection job now has permissions: contents: read.
.github/workflows/python-data-charts.lock.yml Detection job now has permissions: contents: read.
.github/workflows/prompt-clustering-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/pr-triage-agent.lock.yml Detection job now has permissions: contents: read.
.github/workflows/pr-nitpick-reviewer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/portfolio-analyst.lock.yml Detection job now has permissions: contents: read.
.github/workflows/poem-bot.lock.yml Detection job now has permissions: contents: read.
.github/workflows/plan.lock.yml Detection job now has permissions: contents: read.
.github/workflows/pdf-summary.lock.yml Detection job now has permissions: contents: read.
.github/workflows/org-health-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/notion-issue-summary.lock.yml Detection job now has permissions: contents: read.
.github/workflows/mergefest.lock.yml Detection job now has permissions: contents: read.
.github/workflows/mcp-inspector.lock.yml Detection job now has permissions: contents: read.
.github/workflows/lockfile-stats.lock.yml Detection job now has permissions: contents: read.
.github/workflows/layout-spec-maintainer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/jsweep.lock.yml Detection job now has permissions: contents: read.
.github/workflows/issue-triage-agent.lock.yml Detection job now has permissions: contents: read.
.github/workflows/issue-monster.lock.yml Detection job now has permissions: contents: read.
.github/workflows/issue-classifier.lock.yml Detection job now has permissions: contents: read.
.github/workflows/issue-arborist.lock.yml Detection job now has permissions: contents: read.
.github/workflows/instructions-janitor.lock.yml Detection job now has permissions: contents: read.
.github/workflows/hourly-ci-cleaner.lock.yml Detection job now has permissions: contents: read.
.github/workflows/grumpy-reviewer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/go-pattern-detector.lock.yml Detection job now has permissions: contents: read.
.github/workflows/go-logger.lock.yml Detection job now has permissions: contents: read.
.github/workflows/go-fan.lock.yml Detection job now has permissions: contents: read.
.github/workflows/glossary-maintainer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/github-remote-mcp-auth-test.lock.yml Detection job now has permissions: contents: read.
.github/workflows/github-mcp-tools-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/github-mcp-structural-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/functional-pragmatist.lock.yml Detection job now has permissions: contents: read.
.github/workflows/firewall-escape.lock.yml Detection job now has permissions: contents: read.
.github/workflows/example-workflow-analyzer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/duplicate-code-detector.lock.yml Detection job now has permissions: contents: read.
.github/workflows/draft-pr-cleanup.lock.yml Detection job now has permissions: contents: read.
.github/workflows/docs-noob-tester.lock.yml Detection job now has permissions: contents: read.
.github/workflows/discussion-task-miner.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dictation-prompt.lock.yml Detection job now has permissions: contents: read.
.github/workflows/developer-docs-consolidator.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dev.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dev-hawk.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dependabot-project-manager.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dependabot-go-checker.lock.yml Detection job now has permissions: contents: read.
.github/workflows/dependabot-burner.lock.yml Detection job now has permissions: contents: read.
.github/workflows/delight.lock.yml Detection job now has permissions: contents: read.
.github/workflows/deep-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-workflow-updater.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-testify-uber-super-expert.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-team-status.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-team-evolution-insights.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-syntax-error-quality.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-semgrep-scan.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-secrets-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-safe-output-optimizer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-repo-chronicle.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-regulatory.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-performance-summary.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-observability-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-news.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-multi-device-docs-tester.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-mcp-concurrency-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-issues-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-firewall-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-file-diet.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-doc-updater.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-copilot-token-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-compiler-quality.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-code-metrics.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-cli-tools-tester.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-cli-performance.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-choice-test.lock.yml Detection job now has permissions: contents: read.
.github/workflows/daily-assign-issue-to-user.lock.yml Detection job now has permissions: contents: read.
.github/workflows/craft.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-session-insights.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-pr-prompt-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-pr-nlp-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-pr-merged-report.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-cli-deep-research.lock.yml Detection job now has permissions: contents: read.
.github/workflows/copilot-agent-analysis.lock.yml Detection job now has permissions: contents: read.
.github/workflows/commit-changes-analyzer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/code-simplifier.lock.yml Detection job now has permissions: contents: read.
.github/workflows/code-scanning-fixer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/cloclo.lock.yml Detection job now has permissions: contents: read.
.github/workflows/cli-version-checker.lock.yml Detection job now has permissions: contents: read.
.github/workflows/cli-consistency-checker.lock.yml Detection job now has permissions: contents: read.
.github/workflows/claude-code-user-docs-review.lock.yml Detection job now has permissions: contents: read.
.github/workflows/ci-doctor.lock.yml Detection job now has permissions: contents: read.
.github/workflows/ci-coach.lock.yml Detection job now has permissions: contents: read.
.github/workflows/changeset.lock.yml Detection job now has permissions: contents: read.
.github/workflows/breaking-change-checker.lock.yml Detection job now has permissions: contents: read.
.github/workflows/brave.lock.yml Detection job now has permissions: contents: read.
.github/workflows/blog-auditor.lock.yml Detection job now has permissions: contents: read.
.github/workflows/auto-triage-issues.lock.yml Detection job now has permissions: contents: read.
.github/workflows/audit-workflows.lock.yml Detection job now has permissions: contents: read.
.github/workflows/artifacts-summary.lock.yml Detection job now has permissions: contents: read.
.github/workflows/archie.lock.yml Detection job now has permissions: contents: read.
.github/workflows/agent-persona-explorer.lock.yml Detection job now has permissions: contents: read.
.github/workflows/agent-performance-analyzer.lock.yml Detection job now has permissions: contents: read.

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

Comment on lines 59 to 69
// Extract detection job section
detectionStart := strings.Index(yaml, " detection:")
require.Greater(t, detectionStart, 0, "Detection job not found")

// Find the next job by looking for a line that starts with " " followed by a lowercase letter and ":"
// This matches job definitions like " agent:", " safe_outputs:", etc.
searchStart := detectionStart + len(" detection:")
nextJobPattern := "\n "
var detectionSection string

// Search for the next job
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

This test reimplements job-section extraction via manual string scanning. There is already an extractJobSection(yamlContent, jobName) helper in pkg/workflow/compiler_test_helpers.go used across other tests; using it here would reduce duplication and make the test less brittle to formatting changes (indentation, new fields, etc.).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 2316145 - now using the existing extractJobSection helper from compiler_test_helpers.go instead of reimplementing the extraction logic.

Comment on lines 60 to 62
detectionStart := strings.Index(yaml, " detection:")
require.Greater(t, detectionStart, 0, "Detection job not found")

Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

require.Greater(t, detectionStart, 0, ...) will fail if the substring happens to start at index 0. Using require.NotEqual(t, -1, detectionStart, ...) (or GreaterOrEqual(..., 0)) is the correct way to assert that strings.Index found a match.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 2316145 - replaced require.Greater(t, detectionStart, 0, ...) with require.NotEmpty(t, detectionSection, ...) which correctly handles all cases including when the job section is at index 0.

Comment on lines 127 to 130
compiler := NewCompiler()
// Set to release mode (default) - no checkout needed
compiler.actionMode = ActionModeRelease

Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

The comment says “Set to release mode (default)”, but NewCompiler() defaults to version dev and action-mode dev (auto-detected). Consider rewording to avoid implying release is the default, or explicitly set compiler.version to a non-dev value when exercising release-mode behavior.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 2316145 - updated the comment to clarify that dev mode is the default: "Set to dev mode to trigger checkout (dev is also the default)" and removed the misleading "(default)" text from the release mode test.

@pelikhan pelikhan added the smoke label Feb 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

🧪 Smoke Project is now testing project operations...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Changeset Generator completed successfully!

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@pelikhan
Copy link
Contributor

pelikhan commented Feb 9, 2026

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.52.0
jq 1.7
yq 4.52.2
curl 8.x
gh 2.86.0
node 20.20.0
python3 3.x
go 1.24.12
java not available
dotnet not available

Result: 10/12 tools available ⚠️

Missing tools:

  • java
  • dotnet

AI generated by Agent Container Smoke Test

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Smoke Project completed successfully. All project operations validated.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

PR titles: chore: create workflow video with voice over; docs: update architecture documentation
GitHub MCP: ✅
Serena MCP: ✅
Playwright: ✅
File write+cat: ✅
Build gh-aw: ✅
Overall: PASS

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Smoke Test Results - Run 21845575538

PRs Tested:

Results: ✅ GitHub MCP | ✅ Safe Inputs | ✅ Serena | ✅ Playwright | ✅ File I/O | ✅ Build | ✅ Workflow Dispatch

Overall: ✅ PASS

@pelikhan @Copilot

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

- Use extractJobSection helper instead of manual string parsing
- Fix linter error: use require.NotEmpty instead of require.Greater for index check
- Fix comment: clarify that dev mode is the default, not release mode

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

Copilot AI commented Feb 9, 2026

@copilot lint go

https://github.com/github/gh-aw/actions/runs/21845239601/job/63039798484#step:7:1

Fixed in 2316145 - resolved the linter errors by using extractJobSection helper and require.NotEmpty instead of require.Greater. Linter now passes with 0 issues.

@pelikhan pelikhan merged commit 5857f7b into main Feb 10, 2026
48 checks passed
@pelikhan pelikhan deleted the copilot/fix-detection-job-permissions branch February 10, 2026 00:24
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.

Detection job permissions: {} prevents actions/checkout from succeeding

2 participants