|
10 | 10 | schedule: |
11 | 11 | - cron: '0 0 * * 0' # Weekly on Sunday |
12 | 12 | workflow_dispatch: |
| 13 | +# Estate guardrail: cancel superseded runs so re-pushes don't pile up |
| 14 | +# queued runs across the estate. Safe here because this workflow only |
| 15 | +# performs read-only checks/lint/test/scan with no publish or mutation. |
| 16 | +concurrency: |
| 17 | + group: ${{ github.workflow }}-${{ github.ref }} |
| 18 | + cancel-in-progress: true |
13 | 19 |
|
14 | 20 | permissions: |
15 | 21 | contents: read |
16 | 22 | # security-events: read lets the built-in GITHUB_TOKEN query this |
17 | | - # repo\'s own Dependabot alerts via the Hypatia DependabotAlerts rule. |
| 23 | + # repo's own Dependabot alerts via the Hypatia DependabotAlerts rule |
| 24 | + # (DA001-DA004). Without this, `scan_from_path` gets HTTP 403 and |
| 25 | + # the rule silently returns no findings. |
| 26 | + # See 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md. |
18 | 27 | security-events: read |
| 28 | + # pull-requests: write lets the advisory "Comment on PR with findings" |
| 29 | + # step post its summary. Without it the built-in GITHUB_TOKEN gets |
| 30 | + # "Resource not accessible by integration" and (absent continue-on-error) |
| 31 | + # hard-fails the scan — exactly what the gate-decoupling design forbids. |
| 32 | + pull-requests: write |
19 | 33 |
|
20 | 34 | jobs: |
21 | 35 | scan: |
|
41 | 55 | fi |
42 | 56 |
|
43 | 57 | - name: Build Hypatia scanner (if needed) |
44 | | - working-directory: /home/runner/hypatia |
45 | 58 | run: | |
| 59 | + cd "$HOME/hypatia" |
46 | 60 | if [ ! -f hypatia ]; then |
47 | 61 | echo "Building hypatia scanner..." |
48 | 62 | mix deps.get |
|
52 | 66 | - name: Run Hypatia scan |
53 | 67 | id: scan |
54 | 68 | env: |
55 | | - # Suppress the Dependabot "GITHUB_TOKEN not set" warning. |
| 69 | + # Pass the built-in Actions token through to Hypatia so the |
| 70 | + # DependabotAlerts rule can query this repo's own alerts. |
| 71 | + # For cross-repo scanning (fleet-coordinator scan-supervised), |
| 72 | + # a PAT with `security_events` scope is required instead. |
56 | 73 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
57 | 74 | run: | |
58 | 75 | echo "Scanning repository: ${{ github.repository }}" |
@@ -199,6 +216,11 @@ jobs: |
199 | 216 |
|
200 | 217 | - name: Comment on PR with findings |
201 | 218 | if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0 |
| 219 | + # Advisory only — posting findings as a PR comment must never gate |
| 220 | + # the scan (hypatia#213 gate decoupling). Belt-and-braces alongside |
| 221 | + # the pull-requests: write permission above: a token/API hiccup or |
| 222 | + # a fork PR (read-only token) skips the comment, not the check. |
| 223 | + continue-on-error: true |
202 | 224 | uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7 |
203 | 225 | with: |
204 | 226 | script: | |
|
0 commit comments