Repository navigation
[static-analysis] Report - 2026-10-21 #70795
Description
🔍 Static Analysis Report - 2026-10-21
Analysis Summary
- Tools Used: zizmor, poutine, actionlint, runner-guard, syft, grype, yamllint, shellcheck
- Total Findings: 21,729 (+1,352 / +6.6% vs 2026-10-20)
- Workflows Scanned: 346 (+2 vs 2026-10-20)
- Workflows Affected: 346 of 346 (every workflow has at least one low-severity zizmor finding)
Findings by Tool
| Tool | Total | Critical | High | Medium | Low |
|---|---|---|---|---|---|
| zizmor (security) | 19,080 | 0 | 2 | 12,561 | 6,507 (+10 informational) |
| poutine (supply chain) | 30 | 0 | 0 | 1 | 0 (+29 informational) |
| actionlint (linting) | 166 | - | - | - | - |
| runner-guard (taint analysis) | 23 | 0 | 4 | 19 | 0 |
| syft (SBOM inventory) | 12 images / 3,947 packages | - | - | - | - |
| grype (container CVEs) | 2,426 | 43 | 565 | 743 | 143 (+866 negligible, 82 unknown) |
| yamllint (yaml linting) | 0 | - | - | - | - |
| shellcheck (shell linting) | 4 | - | - | - | - |
Clustered Findings by Tool and Type
Zizmor Security Findings
| Issue Type | Severity | Count | Affected Workflows |
|---|---|---|---|
| secrets-outside-env | Medium | 12,484 | 341 |
| self-repository | Low | 3,083 | 346 |
| undocumented-permissions | Low | 2,800 | 346 |
| adhoc-packages | Low | 559 | 293 |
| artipacked | Medium | 76 | 73 |
| template-injection | Low/Informational | 47 | 42 |
| obfuscation | Low | 27 | 27 |
| secrets-inherit | Medium | 1 | windows-grower.lock.yml |
| superfluous-actions | Informational | 1 | smoke-codex.lock.yml |
| unpinned-images | High | 1 | smoke-service-ports.lock.yml |
| bot-conditions | High | 1 | squad.lock.yml |
Poutine Supply Chain Findings
| Issue Type | Severity | Count | Affected Workflows |
|---|---|---|---|
| github_action_from_unverified_creator_used | Informational | 29 | 29 (see details) |
| pr_runs_on_self_hosted | Medium | 1 | smoke-copilot-arm.lock.yml (likely false positive — ubuntu-24.04-arm is a GitHub-hosted ARM runner) |
Actionlint Linting Issues
| Issue Type | Count | Affected Workflows |
|---|---|---|
| expression (missing needs-context property) | 164 | 33 |
| shellcheck (embedded) | 2 | 1 (sergo.lock.yml) |
<b>Expression finding breakdown (by missing property)</b>
| Missing property | Count |
|---|---|
| missing_tool | 66 |
| report_incomplete | 33 |
| noop | 33 |
| report_failed_jobs (new today) | 32 |
All 164 stem from the same root cause: safe-outputs conclusion-job expressions reference needs.<job>.outputs.{property} for properties that are not declared on the generated needs-context object type. report_failed_jobs appeared for the first time in today's scan — likely a new safe-outputs conclusion-job tool was added to the compiler template without a matching needs-context type update.
Syft SBOM Inventory
| Image | Packages | Affected Workflows |
|---|---|---|
| ghcr.io/oraios/serena:1.7.0 | 1,678 | serena-based workflows |
| ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.70 | 346 | firewall-enabled workflows |
| ghcr.io/github/gh-aw-firewall/agent:0.28.70 | 586 | firewall-enabled workflows |
| ghcr.io/github/gh-aw-mcpg:v0.4.36 | 290 | mcpg-gateway workflows |
| ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70 | 193 | firewall-enabled workflows |
| ghcr.io/xberg-io/xberg:1.3.6 | 169 | xberg-based workflows |
| ghcr.io/github/gh-aw-node | 178 | node-runtime workflows |
| grafana/mcp-grafana:1.1.0-alpine | 178 | Grafana MCP workflows |
| node:lts-alpine | 165 | node-runtime workflows |
| ghcr.io/github/gh-aw-firewall/router:0.28.70 | 60 | firewall-enabled workflows |
| ghcr.io/github/github-mcp-server:v2.0.2 | 41 | GitHub MCP server workflows |
| ghcr.io/github/gh-aw-firewall/squid:0.28.70 | 63 | firewall-enabled workflows |
All 12 image digests changed since 2026-10-20 — the firewall images moved 0.28.62 → 0.28.70 and gh-aw-mcpg moved v0.4.35 → v0.4.36 (a real upstream refresh, not a rescan artifact).
Runner-Guard Taint Analysis Findings
Runner-Guard: 23 findings (0 Critical, 4 High, 19 Medium, 0 Low)
| Rule ID | Name | Severity | Count | Affected Workflows |
|---|---|---|---|---|
| RGS-005 | Excessive Permissions on Untrusted Trigger | Medium | 19 | agentic-workqueue.yml, agentic_commands.yml, ai-moderator.lock.yml, q.lock.yml, squad.lock.yml |
| RGS-018 | Suspicious Payload Execution Pattern | High | 3 | daily-workflow-security-model.lock.yml, daily-work-queue-formal-verification.lock.yml, credentials-check.yml |
| RGS-012 | Secret Exfiltration via Outbound HTTP Request | High | 1 | github-remote-mcp-auth-test.lock.yml |
Issues created: none — see Runner-Guard Analysis section below for dedup rationale.
Grype Container Vulnerability Findings
| Package / Advisory | Severity | Count | Affected Images |
|---|---|---|---|
| GHSA-ch52-4w7c-c8xp (http-cache-semantics@4.2.0) | High | 6 | agent, api-proxy, cli-proxy, gh-aw-node, node:lts-alpine, serena |
| GHSA-r292-9mhp-454m (tar@7.5.19, fix 7.5.21) | High | 6 | agent, api-proxy, cli-proxy, gh-aw-node, node:lts-alpine, serena |
| (various OS/package CVEs — see cache memory for full per-image breakdown) | Critical/High/Medium | 2,414 | all 12 images |
<b>Grype findings by image (total / critical)</b>
| Image | Total | Critical |
|---|---|---|
| ghcr.io/oraios/serena:1.7.0 | 1,472 | 15 |
| ghcr.io/xberg-io/xberg:1.3.6 | 385 | 18 |
| ghcr.io/github/gh-aw-firewall/agent:0.28.70 | 327 | 0 |
| grafana/mcp-grafana:1.1.0-alpine | 69 | 6 |
| ghcr.io/github/gh-aw-mcpg:v0.4.36 | 57 | 2 |
| node:lts-alpine | 51 | 0 |
| ghcr.io/github/github-mcp-server:v2.0.2 | 44 | 2 |
| ghcr.io/github/gh-aw-firewall/router:0.28.70 | 16 | 0 |
| ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.70 | 6 | 0 |
| ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70 | 6 | 0 |
| ghcr.io/github/gh-aw-node | 5 | 0 |
| ghcr.io/github/gh-aw-firewall/squid:0.28.70 | 4 | 0 |
Yamllint YAML Linting Findings
Clean — 0 findings across all 346 workflows.
Shellcheck Shell Linting Findings
| Code | Count | Affected Workflows |
|---|---|---|
| SC1003 | 2 | sergo.lock.yml (also reported by actionlint's embedded shellcheck pass) |
| SC2086 | 2 | daily-hippo-learn, hippo-embed |
Top Priority Issues
1. zizmor High findings open 20+ consecutive days with no fix issue filed
- Tool: zizmor
- Count: 2 (unpinned-images, bot-conditions)
- Severity: High
- Affected: smoke-service-ports.lock.yml (unpinned-images), squad.lock.yml (bot-conditions)
- Description:
unpinned-imagesflags a container image reference that is not pinned to a digest;bot-conditionsflags a spoofable bot-actor check that could let an external actor bypass intended guardrails. - Impact: Both are High severity and have remained open since before 2026-10-01 without a dedicated remediation issue. Unpinned images are subject to supply-chain tampering; a spoofable bot check can let an attacker impersonate a trusted automation actor.
- Reference: (docs.zizmor.sh/redacted), (docs.zizmor.sh/redacted)
2. actionlint: new report_failed_jobs needs-context type gap
- Tool: actionlint
- Count: 32 (new today, part of +32 total increase)
- Severity: N/A (linting / type-correctness, not a direct security vulnerability)
- Affected: Same 33 workflows already affected by the existing missing_tool/report_incomplete/noop pattern
- Description: Conclusion-job expressions now also reference
needs.<job>.outputs.report_failed_jobs, a property not declared on the generated needs-context object type. This is on top of the pre-existing missing_tool/report_incomplete/noop pattern. - Impact: Indicates the safe-outputs compiler template added a new conclusion-job tool (
report_failed_jobs) without updating the corresponding needs-context type generation, so actionlint cannot verify these expressions are valid. Risk of a silent typo or broken expression in generated workflows going undetected. - Reference: pkg/workflow compiler — needs-context type generation for safe-outputs conclusion jobs
3. zizmor secrets-outside-env (highest-volume finding, selected for fix suggestion below)
- Tool: zizmor
- Count: 12,484 (65% of all zizmor findings)
- Severity: Medium
- Affected: 341 of 346 workflows
- Description: Jobs reference
secrets.*without a dedicated GitHubenvironment:to scope and protect that access. - Impact: Any code executing in an unprotected job (including anything reachable via prompt injection in an agentic step) has ambient access to all secrets available to that job/repo, with no additional approval gate.
- Reference: (docs.zizmor.sh/redacted)
4. zizmor self-repository / undocumented-permissions disproportionate growth
- Tool: zizmor
- Count: self-repository +704 (2,379→3,083), undocumented-permissions +700 (2,100→2,800)
- Severity: Low
- Affected: all 346 workflows (unchanged workflow coverage, but per-workflow occurrence counts rose)
- Description: Both rules jumped far more than the +2 workflow-count delta would predict;
eslint-refiner.lock.ymlis now the single highest self-repository contributor (25 hits). - Impact: Likely organic (more jobs/permission blocks per workflow) but warrants a quick check next run to rule out a zizmor version or compiler-template behavior change inflating counts across the board.
- Reference: (docs.zizmor.sh/redacted), (docs.zizmor.sh/redacted)
Fix Suggestion for zizmor secrets-outside-env
Issue: Secrets referenced in a job with no dedicated environment: protection
Severity: Medium
Affected Workflows: 341 of 346 workflows (12,484 occurrences)
Prompt to Copilot Agent:
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 341 affected 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 341 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 are not 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:
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 341 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 12484 toward 0 (or to
a documented, justified residual with ignore annotations).
Runner-Guard Analysis
Runner-Guard: 23 findings total (0 Critical, 4 High, 19 Medium, 0 Low) — up 6 from 2026-10-20 (17), entirely within RGS-005 (Medium). The 4 High findings (RGS-018 ×3, RGS-012 ×1) are byte-identical to prior scans in rule, affected file, and count.
Dedup results for Critical/High findings:
| Rule | File | Status | Resolution |
|---|---|---|---|
| RGS-018 | daily-workflow-security-model.lock.yml | Previously closed | Covered by closed issue #68606 |
| RGS-018 | daily-work-queue-formal-verification.lock.yml | Previously closed | Covered by closed issue #68607 |
| RGS-018 | credentials-check.yml | Previously closed | Covered by closed issue #68608 |
| RGS-012 | github-remote-mcp-auth-test.lock.yml | Previously closed | Covered by closed issue #55652 |
All four are confirmed false positives / reviewed-and-accepted findings (checksum-verified pinned downloads for RGS-018; a pinned, reviewed api.githubcopilot.com MCP handshake for RGS-012). 0 new issues created this run. Direct re-verification via issue_read on #68606–#68608 was blocked by integrity-policy filtering in this run's tool access; the dedup decision relies on 2026-10-19/2026-10-20 cache-memory notes that confirmed closed status, combined with today's rule/file/count being unchanged from those confirmed scans.
All Findings Details
<b>Detailed Findings by Workflow (selected highlights)</b>
eslint-refiner.lock.yml
self-repository
- Severity: Low
- Description: 25 occurrences — highest in the repository this run.
- Reference: (docs.zizmor.sh/redacted)
smoke-service-ports.lock.yml
unpinned-images
- Severity: High
- Location: Line 539
- Description: Unpinned container image reference.
- Reference: (docs.zizmor.sh/redacted)
squad.lock.yml
bot-conditions
- Severity: High
- Location: Line 2858
- Description: Spoofable bot actor check.
- Reference: (docs.zizmor.sh/redacted)
windows-grower.lock.yml
secrets-inherit
- Severity: Medium
- Location: Line 2384
- Description: Secrets unconditionally inherited by a called workflow.
- Reference: (docs.zizmor.sh/redacted)
sergo.lock.yml
SC1003 (shellcheck)
- Severity: Low (linting)
- Description: Unescaped single quote inside a single-quoted shell string, reported both by shellcheck directly and actionlint's embedded shellcheck pass.
Full per-finding detail for all 346 workflows is available in /tmp/gh-aw/cache-memory/security-scans/2026-10-21.json and the raw compile output artifact for this run.
Historical Trends
- Previous Scan: 2026-10-20
- Total Findings Then: 20,377
- Total Findings Now: 21,729
- Change: +1,352 (+6.6%)
New Issues
- actionlint: new missing needs-context property
report_failed_jobs(32 occurrences) — first seen today. - grype: High npm advisories GHSA-ch52-4w7c-c8xp (http-cache-semantics) and GHSA-r292-9mhp-454m (tar) now explicitly tracked across 6 node-based images.
- zizmor: disproportionate growth in
self-repositoryandundocumented-permissionsrelative to the +2 workflow-count delta (flagged for follow-up, not yet confirmed as a regression).
Resolved Issues
- grype:
gh-aw-mcpgcritical findings dropped from 9 to 2 following the v0.4.35 → v0.4.36 image bump. - grype: overall critical/high/medium/low counts all decreased (-144 total) following a coordinated refresh of all 12 image digests.
Recommendations
- Immediate: File a dedicated fix issue for the two long-standing zizmor High findings (
unpinned-images,bot-conditions) — both have been open 20+ consecutive days with no tracking issue. - Short-term: Investigate the new actionlint
report_failed_jobsneeds-context gap (likely a compiler template change missing a type update) and apply thesecrets-outside-envfix template at the shared job-template level. - Long-term: Schedule a coordinated npm dependency bump to address GHSA-ch52-4w7c-c8xp and GHSA-r292-9mhp-454m across all affected node-based images; continue tracking whether the zizmor
self-repository/undocumented-permissionsgrowth stabilizes or keeps outpacing workflow count. - Prevention: Keep the
secrets-outside-envfix template current in cache memory and apply it at the compiler-template level rather than per-workflow; continue the container image refresh cadence that just reduced grype critical/high findings by 61/54 respectively.
Next Steps
- File a fix issue for zizmor High findings (unpinned-images, bot-conditions) — 20+ days open, no tracking issue
- Investigate actionlint's new
report_failed_jobsneeds-context gap in the safe-outputs compiler template - Apply the
secrets-outside-envfix template at the shared job-template level (12,484 occurrences, 341 workflows) - Schedule a coordinated npm bump for http-cache-semantics and tar across node-based images
- Re-check next run whether the self-repository/undocumented-permissions growth is organic or a zizmor behavior change
- Continue the container image refresh cadence (firewall 0.28.70, mcpg v0.4.36) that reduced grype findings this run
References:
Generated by 📊 Static Analysis Report · claude · agent · 224.1 AIC · ⌖ 1.01 AIC · ⊞ 7.1K · ◷
- expires on Oct 27, 2026, 9:32 PM UTC-08:00
Activity
github-actions commentedon Oct 22, 2026
This issue is being closed as outdated. A newer issue has been created: #71044
View newer issue
This action was performed automatically by the
Static Analysis Reportworkflow.