Repository navigation
[static-analysis] Report - 2026-09-11 #60184
Description
Overview
Daily static analysis scan of github/gh-aw — 299/299 workflows compiled and scanned successfully (529 compile warnings, non-fatal). 8 tools ran: zizmor, poutine, actionlint, runner-guard, syft, grype, yamllint, shellcheck.
Total findings: 15,046 (-18 vs 2026-09-10, -0.1%) — a quiet day. Two movers accounted for the entire delta; everything else was byte-identical to yesterday.
Key metrics
| Tool | Total | Critical | High | Medium | Low | Other |
|---|---|---|---|---|---|---|
| zizmor (workflow security) | 12,961 | 0 | 10 | 8,271 | 2,433 | 2,247 informational |
| poutine (supply chain) | 30 | – | – | – | – | 29 note + 1 warning |
| actionlint (YAML lint) | 0 | – | – | – | – | – |
| runner-guard (taint analysis) | 13 | 0 | 1 | 12 | 0 | – |
| syft (SBOM) | 3,866 pkgs / 11 images | – | – | – | – | – |
| grype (container CVEs) | 2,036 | 52 | 477 | 563 | 103 | 762 negligible, 79 unknown |
| yamllint | 0 | – | – | – | – | – |
| shellcheck | 6 | – | – | – | – | SC2086 x6 |
No new GitHub issues created for runner-guard this run — see Runner-Guard Analysis below.
What changed vs 2026-09-10
- zizmor -1:
dev-hawk.lock.yml'sgithub-envHigh finding is resolved (High count 11 → 10). This closes out a pattern that has regressed and been re-fixed 6+ times historically ([plan] Fix github-env HIGH vulnerability in ci-doctor and dev-hawk workflows #22249, Fix github-env HIGH vulnerability in ci-doctor and dev-hawk workflows #22528, [plan] Fix dangerous GITHUB_ENV write in dev-hawk workflow (High severity) #25861, Mitigategithub-envinjection risk indev-hawkby switching GH_HOST propagation to step outputs #27219, Resolve dev-hawkgithub-envhighs by tightening env-file usage in generated workflow steps #37586, Eliminate persistent zizmorgithub-envfinding indev-hawksafe-outputs path #38050). - grype -17: high -1, medium -16; critical/low/negligible/unknown all flat.
syftshows no package-count change, so this looks like a fix-state/rescoring update on existing packages rather than a package change. Coincides with thegh-aw-firewall/*images bumping 0.28.14 → 0.28.15 (no package-count delta). - Everything else (poutine, runner-guard, shellcheck, yamllint, actionlint) is byte-identical to yesterday.
Top priority issues
secrets-outside-env(zizmor, Medium, 8,195 occurrences / 296 of 299 workflows) — by far the largest cluster. Root cause is the shared Go compiler template, not per-workflow authoring. See Fix Suggestion below.- 3 remaining zizmor High findings (unchanged for 7+ consecutive days):
github-app— 8 occurrences acrosssquad-game-planner.lock.yml,squad-implement-worker.lock.yml,squad-plan.lock.yml,squad.lock.yml(unscoped app-token permissions)unpinned-images— 1 occurrence,smoke-service-ports.lock.ymlbot-conditions— 1 occurrence,squad.lock.yml
- RGS-012 (runner-guard, High) —
github-remote-mcp-auth-test.lock.yml:1739, secret exfiltration via outbound HTTP request to a non-GitHub domain. Recurring finding; already covered by closed issue [static-analysis] RGS-012: Secret Exfiltration via Outbound HTTP Request in github-remote-mcp-auth-test.lock.yml #55652 (fix in merged PR Suppress RGS-012 finding for pinned GitHub remote MCP handshake curl #55686 did not survive lock-file regeneration — the finding now fires at a shifted line, 1675→1739). Not re-filed per dedup policy; worth a follow-up PR to make the suppression regenerate-safe.
Fix suggestion: secrets-outside-env
Fix prompt for Copilot coding agent (zizmor secrets-outside-env, 8195 occurrences, 296/299 workflows)
Issue: Secrets referenced in a job that has no dedicated environment: protection
Severity: Medium
Affected Workflows: 296 of 299 (8195 occurrences, unchanged for 2 consecutive days) — the largest zizmor cluster in this repo by a wide margin
You are fixing a security vulnerability identified by zizmor.
Vulnerability: secrets-outside-env - secrets referenced without a dedicated environment
Rule: secrets-outside-env - (docs.zizmor.sh/redacted)
Current Issue:
A job references one or more `secrets.*` values (directly, or indirectly via
steps that consume org/repo secrets) but the job has no `environment:` key.
GitHub Environments let you attach protection rules (required reviewers,
wait timers, deployment branch restrictions) and scope which secrets are
even visible to a job. Without a declared environment, any code that runs
in that job -- including anything reachable via prompt injection into an
agentic step -- has ambient access to every secret available to the
job/repo, with no additional approval gate and no scoping.
Note: gh-aw generates these `.lock.yml` files from `.md` workflow sources
via a shared Go compiler template (not hand-written per workflow), and the
finding appears in nearly all 299 workflows on the same job (typically
`activation` or similar). This is a compiler/template-level issue, not a
per-workflow one -- fixing the shared job template that emits secrets
usage is far more effective than editing 296 generated lock files by hand.
Required Fix:
1. Identify the shared Go template/source that emits the job flagged by
zizmor (check pkg/workflow/*.go or the .md frontmatter compiler for the
job name shown in the finding, e.g. `activation`).
2. Determine which secrets that job actually needs (e.g. `secrets.GITHUB_TOKEN`,
an LLM provider API key, a GH App private key).
3. Add an `environment:` key to that job specifying a named GitHub
Environment (e.g. `environment: agent-runtime`), OR, if per-workflow
environments aren't desired, document why the risk is accepted and add
a `# zizmor: ignore[secrets-outside-env]` suppression with a one-line
justification comment -- only if a security reviewer has confirmed the
job's blast radius is already minimal (e.g. read-only permissions).
4. If introducing a real environment: create/configure the environment in
repo settings (required reviewers / branch restrictions as appropriate),
and confirm the job's secrets access still works in CI.
5. Recompile all workflows (`gh-aw compile` or equivalent) and re-run
zizmor to confirm the finding count drops for every regenerated
workflow, not just one.
Example:
Before:
```yaml
jobs:
activation:
needs: pre_activation
if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@...
with:
token: ${{ secrets.GITHUB_TOKEN }}
After:
jobs:
activation:
needs: pre_activation
if: needs.pre_activation.outputs.activated == 'true'
environment: agent-runtime
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@...
with:
token: ${{ secrets.GITHUB_TOKEN }}Please apply this fix at the shared compiler-template level (not to
individual .lock.yml files) so it takes effect across all 296 affected
workflows on the next gh-aw compile run. Validate against a sample of
affected workflows including: ab-testing-advisor.lock.yml, and re-run the
static-analysis scan to confirm the count drops from 8195 toward 0 (or to
a documented, justified residual with ignore annotations).
</details>
### Runner-Guard Analysis
Runner-guard performs source-to-sink taint analysis; the raw scan output does not emit an overall score/grade, only per-finding severity — so this section reports findings directly rather than a composite score.
| Rule | Name | Severity | Count | Workflows |
|---|---|---|---|---|
| RGS-005 | Excessive Permissions on Untrusted Trigger | Medium | 12 | 4 (`agentic_commands.yml`, `ai-moderator.lock.yml`, `q.lock.yml`, `squad.lock.yml`) |
| RGS-012 | Secret Exfiltration via Outbound HTTP Request | High | 1 | 1 (`github-remote-mcp-auth-test.lock.yml:1739`) |
**Issue-creation decision: 0 new issues created.**
- RGS-005 is Medium severity — below this workflow's Critical/High issue-filing threshold.
- RGS-012 is the only Critical/High-eligible finding. Verified via `issue_read` (not `search_issues`, which returns unreliable filtered results in this environment) that it is already covered by **closed** issue #55652 (fix merged via PR #55686). Per dedup policy, closed issues are skipped rather than reopened or commented on. The underlying finding still fires post-fix because the flagged line shifted (1675→1739) when the lock file was regenerated — the suppression didn't survive regeneration. This is worth a dedicated follow-up (make the fix regeneration-safe) but not a new duplicate issue today.
### All findings — details
<details>
<summary><b>zizmor — 12,961 findings by rule</b></summary>
| Rule | Severity | Count | Affected workflows |
|---|---|---|---|
| secrets-outside-env | Medium | 8,195 | 296 |
| anonymous-definition | Informational | 2,194 | 299 |
| undocumented-permissions | Low | 1,794 | 299 |
| adhoc-packages | Low | 606 | 236 |
| artipacked | Medium | 75 | 72 |
| template-injection | Informational | 52 | – |
| obfuscation | Low | 30 | 30 |
| github-app | High | 8 | squad-game-planner, squad-implement-worker, squad-plan, squad |
| template-injection | Low | 3 | – |
| secrets-inherit | Medium | 1 | – |
| unpinned-images | High | 1 | smoke-service-ports |
| superfluous-actions | Informational | 1 | – |
| bot-conditions | High | 1 | squad |
</details>
<details>
<summary><b>poutine — 30 findings</b></summary>
| Rule | Severity | Count | Affected workflows |
|---|---|---|---|
| github_action_from_unverified_creator_used | note | 29 | 28 |
| pr_runs_on_self_hosted | warning | 1 | smoke-copilot-arm |
</details>
<details>
<summary><b>syft — 3,866 packages across 11 images</b></summary>
| Image | Packages |
|---|---|
| ghcr.io/oraios/serena:1.7.0 | 1,678 |
| ghcr.io/github/gh-aw-firewall/agent:0.28.15 | 567 |
| ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.15 | 347 |
| ghcr.io/github/gh-aw-mcpg:v0.4.20 | 288 |
| ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15 | 193 |
| grafana/mcp-grafana:1.1.0-alpine | 178 |
| ghcr.io/github/gh-aw-node | 177 |
| ghcr.io/xberg-io/xberg:latest | 169 |
| node:lts-alpine | 165 |
| ghcr.io/github/gh-aw-firewall/squid:0.28.15 | 63 |
| ghcr.io/github/github-mcp-server:v1.12.1 | 41 |
`gh-aw-firewall/*` images bumped 0.28.14 → 0.28.15 today with no package-count delta.
</details>
<details>
<summary><b>grype — 2,036 findings by severity, critical breakdown by image</b></summary>
| Severity | Count |
|---|---|
| Critical | 52 |
| High | 477 |
| Medium | 563 |
| Low | 103 |
| Negligible | 762 |
| Unknown | 79 |
| Image | Critical count |
|---|---|
| ghcr.io/oraios/serena:1.7.0 | 12 |
| ghcr.io/github/gh-aw-firewall/squid:0.28.15 | 10 |
| ghcr.io/xberg-io/xberg:latest | 7 |
| node:lts-alpine | 4 |
| grafana/mcp-grafana:1.1.0-alpine | 4 |
| ghcr.io/github/gh-aw-mcpg:v0.4.20 | 4 |
| ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.15 | 4 |
| ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15 | 4 |
| ghcr.io/github/gh-aw-node | 2 |
| ghcr.io/github/github-mcp-server:v1.12.1 | 1 |
</details>
<details>
<summary><b>shellcheck — 6 findings</b></summary>
Rule SC2086 (unquoted variable expansion), 6 occurrences across 4 workflows: `daily-cli-performance`, `daily-hippo-learn`, `hippo-embed`, `smoke-claude`. Unchanged since 2026-08-27.
</details>
<details>
<summary><b>Historical trend (last 5 scan days)</b></summary>
| Date | Total findings | Δ vs prior | zizmor High | grype Critical | Notes |
|---|---|---|---|---|---|
| 2026-09-07 | 15,259 | -64 | 11 | — | quietest day at the time |
| 2026-09-08 | 15,233 | -26 | 11 | 28 | grype improved (-26) |
| 2026-09-09 | 15,243 | +10 | 11 | 28 | grype medium +10 |
| 2026-09-10 | 15,064 | -179 | 11 | 52 | zizmor -184, grype critical +24/high +83 (rescoring) |
| **2026-09-11** | **15,046** | **-18** | **10** | 52 | dev-hawk github-env resolved; grype high/medium down |
</details>
### Recommendations & next steps
- [ ] Land the `secrets-outside-env` compiler-template fix (see Fix Suggestion above) — highest-leverage change available, affects 296 workflows in one PR.
- [ ] Address the 3 remaining zizmor High findings: scope `github-app` token permissions (4 `squad-*` workflows), pin the image in `smoke-service-ports.lock.yml` (`unpinned-images`), and review the `bot-conditions` logic in `squad.lock.yml`.
- [ ] Make the RGS-012 suppression on `github-remote-mcp-auth-test.lock.yml` regeneration-safe so it survives future `gh-aw compile` runs (it has now regressed at least once after #55686).
- [ ] Consider triaging the top grype-critical images (`serena:1.7.0` at 12, `gh-aw-firewall/squid:0.28.15` at 10) for available base-image/package upgrades.
- [ ] No action needed on poutine, actionlint, yamllint this run (flat or zero).
**References:**
- Workflow run: [§34563295452](https://github.com/github/gh-aw/actions/runs/34563295452)
> [!WARNING]
> <details>
> <summary>Firewall blocked 1 domain</summary>
>
> The following domain was blocked by the firewall during workflow execution:
>
> - `api.anthropic.com`
>
> To allow these domains, add them to the `network.allowed` list in your workflow frontmatter:
>
> ```yaml
> network:
> allowed:
> - defaults
> - "api.anthropic.com"
> ```
>
> See [Network Configuration](https://github.github.com/gh-aw/reference/network/) for more information.
>
> </details>
> Generated by [📊 Static Analysis Report](https://github.com/github/gh-aw/actions/runs/34563295452) · claude · agent · 381.8 AIC · ⌖ 10.1 AIC · ⊞ 12.3K · [◷](https://github.com/search?q=repo%3Agithub%2Fgh-aw+is%3Aissue+%22gh-aw-workflow-call-id%3A+github%2Fgh-aw%2Fstatic-analysis-report%22&type=issues)
> - [x] expires <!-- gh-aw-expires: 2026-09-18T05:21:36.988Z --> on Sep 17, 2026, 9:21 PM UTC-08:00
<!-- gh-aw-agentic-workflow: Static Analysis Report, engine: claude, model: agent, id: 34563295452, workflow_id: static-analysis-report, run: https://github.com/github/gh-aw/actions/runs/34563295452 -->
<!-- gh-aw-workflow-id: static-analysis-report -->
<!-- gh-aw-workflow-call-id: github/gh-aw/static-analysis-report -->
Activity
github-actions commentedon Sep 13, 2026
This issue is being closed as outdated. A newer issue has been created: #60569
View newer issue
This action was performed automatically by the
Static Analysis Reportworkflow.