Repository navigation
Description
Analysis Summary
- Tools Used: zizmor, poutine, actionlint, runner-guard, syft, grype, yamllint, shellcheck
- Total Findings: 2,091
- Workflows Scanned: 287
- Workflows Affected: 275 (shellcheck) / 29 (zizmor) / 4 (runner-guard) / 1 (actionlint)
This is the first recorded scan in cache memory — no historical baseline exists yet for trend comparison.
Findings by Tool
| Tool | Total | Critical | High | Medium | Low |
|---|---|---|---|---|---|
| zizmor (security) | 30 | 0 | 0 | 0 | 1 (+29 info) |
| poutine (supply chain) | 0 | 0 | 0 | 0 | 0 |
| actionlint (linting) | 1 | - | - | - | - |
| runner-guard (taint analysis) | 4 unique (12 raw) | 0 | 0 | 4 | 0 |
| syft (SBOM inventory) | 10 images / 3,694 packages | - | - | - | - |
| grype (container CVEs) | 1,498 | 51 | 179 | 478 | 104 (+645 negligible, 41 unknown) |
| yamllint (yaml linting) | 0 | - | - | - | - |
| shellcheck (shell linting) | 550 | - | - | - | - |
Clustered Findings by Tool and Type
Zizmor Security Findings
| Issue Type | Severity | Count | Affected Workflows |
|---|---|---|---|
github_action_from_unverified_creator_used |
info | 29 | 27 workflows (e.g. copilot-pr-nlp-analysis, prompt-clustering-analysis, super-linter, hippo-embed, smoke-codex, daily-elixir-credo-snippet-audit) — all already have inline # zizmor: ignore[...] suppressions in source, so these are expected/acknowledged |
pr_runs_on_self_hosted |
warning | 1 | smoke-copilot-arm.lock.yml (uses ubuntu-24.04-arm runner) |
Poutine Supply Chain Findings
No findings — poutine scanned all 287 files cleanly.
Actionlint Linting Issues
| Issue Type | Count | Affected Workflows |
|---|---|---|
shellcheck:SC2129 (style) |
1 | pr-sous-chef.lock.yml (line 551) — suggests grouping redirects with { cmd1; cmd2; } >> file |
Syft SBOM Inventory
Container image package inventory (10 images, 3,694 packages)
| Image | Packages | Affected Workflows |
|---|---|---|
ghcr.io/oraios/serena:latest |
1,711 | workflows using the Serena MCP server |
ghcr.io/github/gh-aw-firewall/agent:0.28.4 |
531 | all firewall-enabled workflows |
ghcr.io/github/gh-aw-mcpg:v0.4.10 |
288 | workflows using the MCP gateway |
ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.4 |
348 | CLI-proxy firewall topology |
ghcr.io/github/gh-aw-node |
177 | Node-based agent workflows |
grafana/mcp-grafana:1.1.0-alpine |
178 | Grafana MCP workflows |
node:lts-alpine |
165 | Node-based tooling steps |
ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4 |
193 | firewall-enabled workflows |
ghcr.io/github/gh-aw-firewall/squid:0.28.4 |
63 | Squid-proxy firewall topology |
ghcr.io/github/github-mcp-server:v1.10.0 |
40 | GitHub MCP server workflows |
Runner-Guard Taint Analysis Findings
Runner-Guard Score: not reported in this run's output (no score/grade line emitted).
| Rule ID | Name | Severity | Affected Workflows |
|---|---|---|---|
| RGS-005 | Excessive Permissions on Untrusted Trigger | medium | agentic_commands.yml, ai-moderator.lock.yml, q.lock.yml, squad.lock.yml |
All four are jobs with write-level permissions: combined with an externally-triggerable event (e.g. pull_request_target, issue_comment). No Critical/High runner-guard findings were detected this run, so no new issues were opened per the dedup policy (only Critical/High findings trigger issue creation).
Issues created: none (all findings are medium severity)
Grype Container Vulnerability Findings
Full severity/package breakdown
| Package | Severity | Count | Affected Image(s) |
|---|---|---|---|
binutils family (binutils, binutils-common, binutils-x86-64-linux-gnu, libbinutils, libctf0, libctf-nobfd0, libgprofng0, libsframe1) |
mixed | 57 each | ghcr.io/oraios/serena:latest |
tar |
critical/high | 50 | ghcr.io/oraios/serena:latest, node:lts-alpine (GHSA-23hp-3jrh-7fpw, fix: 7.5.19) |
perl / perl-base / perl-modules-5.40 / libperl5.40 |
critical | 32 each | ghcr.io/oraios/serena:latest |
bind9-libs |
medium | 29 | ghcr.io/github/gh-aw-firewall/agent:0.28.4 |
libexpat1 |
mixed | 28 | ghcr.io/oraios/serena:latest |
node |
high/critical | 26 | multiple images (CVE-2025-55130 on node@22.18.0, fix ≥20.20.0/22.22.0/24.13.0/25.3.0) |
libc6 |
critical | 26 | ghcr.io/oraios/serena:latest (CVE-2026-5450) |
ssh / openssh-server / openssh-client / openssh-sftp-server |
critical | 21 each | ghcr.io/oraios/serena:latest (CVE-2026-60002) |
curl / libcurl4t64 / libcurl3t64-gnutls |
critical | multiple | ghcr.io/oraios/serena:latest (CVE-2026-9079, -8927, -8926, -8924, -11856, -10536) |
undici |
high | 19 | Node-based images |
51 Critical findings — nearly all concentrated in ghcr.io/oraios/serena:latest (a third-party MCP server image), covering 15 unique CVE/GHSA IDs across curl, perl, openssh, libc6, tar, and node components. node:lts-alpine also carries the tar GHSA (fixed in 7.5.19).
Yamllint YAML Linting Findings
No findings — all 287 files passed yamllint cleanly.
Shellcheck Shell Linting Findings
| Code | Count | Affected Workflows |
|---|---|---|
| SC2015 | 550 (2 per workflow) | 275 of 287 workflows |
Every occurrence is in the auto-generated "Copy detection firewall logs" step, in the exact same two lines, on every workflow with the firewall/threat-detection feature enabled. This is a single root cause in the compiler template, not 275 independent issues.
Top Priority Issues
1. shellcheck SC2015 — ambiguous A && B || C in generated firewall-log-copy step
- Tool: shellcheck
- Count: 550 occurrences across 275 workflows
- Severity: style/note (but represents a real correctness ambiguity)
- Affected: 275/287 compiled workflows (any workflow with firewall detection enabled)
- Description:
pkg/workflow/threat_detection_steps.go:230-231generates[ -d X ] && mkdir -p Y && cp -r X/. Y/ || true. Ifmkdir -porcpfails,|| truesilently swallows the error, and it's ambiguous whether-d Xwas false or the following commands failed. - Impact: Low security impact (log-copy step already has
continue-on-error: true), but it can silently hide a broken log path, meaning firewall/audit log data loss goes unnoticed. Because it's compiler-generated, it's the single highest-leverage fix in this scan — one source change resolves all 275 instances. - Reference: (www.shellcheck.net/redacted)
2. grype Critical CVEs in ghcr.io/oraios/serena:latest
- Tool: grype
- Count: 51 critical findings (15 unique CVEs/GHSAs)
- Severity: Critical
- Affected: Serena MCP server container image
- Description: Outdated curl, perl, openssh, libc6, and tar packages with known critical vulnerabilities in the upstream
oraios/serena:latestimage. - Impact: This is a third-party image (not built by gh-aw), so remediation depends on upstream updating their base image. Consider pinning to a digest of a patched release once available, or evaluating whether the Serena MCP server needs all these packages.
- Reference: GHSA-23hp-3jrh-7fpw
3. runner-guard RGS-005 — Excessive Permissions on Untrusted Trigger
- Tool: runner-guard
- Count: 4 workflows
- Severity: Medium
- Affected:
agentic_commands.yml,ai-moderator.lock.yml,q.lock.yml,squad.lock.yml - Description: Jobs specify write-level
permissions:while triggered by events that can be initiated by external users (e.g.issue_comment,pull_request_target). - Impact: Combined with any injection vulnerability, these permissions would let an external actor modify repo contents or assume elevated identities. Worth a manual review to confirm the write scope is actually required for these triggers.
- Reference: https://github.com/Vigilant-LLC/runner-guard
Fix Suggestion for shellcheck SC2015
Issue: Ambiguous [ -d X ] && mkdir -p Y && cp -r X/. Y/ || true pattern in generated workflow step
Severity: Style/Note (correctness ambiguity, not a direct security vulnerability)
Affected Workflows: 275 compiled workflows (single source fix)
Prompt to Copilot Agent:
You are fixing a shellcheck SC2015 finding in the gh-aw compiler.
**Vulnerability/Issue**: SC2015 - "Note that A && B || C is not if-then-else. C may run when A is true."
**Rule**: SC2015 - (www.shellcheck.net/redacted)
**Current Issue**:
pkg/workflow/threat_detection_steps.go (function buildCopyDetectionFirewallLogsStep, lines 230-231)
generates two shell lines of the form:
[ -d X ] && mkdir -p Y && cp -r X/. Y/ || true
If `mkdir -p` or `cp -r` fails (e.g. disk full, permission error), the `|| true`
silently swallows that failure and makes it indistinguishable from the `-d X`
test simply being false. This masks real errors in a step whose whole purpose
is to preserve firewall/audit log data for the threat-detection job.
**Required Fix**:
Rewrite both lines as explicit if/then blocks so the truth-test and the
copy operation are not conflated by `&&`/`||` chaining:
if [ -d X ]; then mkdir -p Y && cp -r X/. Y/; fi
This preserves the "do nothing if the directory doesn't exist" behavior
without using `|| true` to blanket-suppress errors from the commands that
run when it does exist.
**Example**:
Before:
```go
fmt.Sprintf(" [ -d %s ] && mkdir -p %s/logs && cp -r %s/. %s/logs/ || true\n", proxyLogsDir, detectionFirewallLogsDir, proxyLogsDir, detectionFirewallLogsDir),
fmt.Sprintf(" [ -d %s ] && mkdir -p %s/audit && cp -r %s/. %s/audit/ || true\n", auditDir, detectionFirewallLogsDir, auditDir, detectionFirewallLogsDir),
After:
fmt.Sprintf(" if [ -d %s ]; then mkdir -p %s/logs && cp -r %s/. %s/logs/; fi\n", proxyLogsDir, detectionFirewallLogsDir, proxyLogsDir, detectionFirewallLogsDir),
fmt.Sprintf(" if [ -d %s ]; then mkdir -p %s/audit && cp -r %s/. %s/audit/; fi\n", auditDir, detectionFirewallLogsDir, auditDir, detectionFirewallLogsDir),Please apply this fix in pkg/workflow/threat_detection_steps.go, then run
make recompile (or the project's equivalent) to regenerate all affected
.lock.yml files so the fix propagates to all 275 workflows in one change.
### All Findings Details
<details>
<summary><b>Zizmor: unverified-creator actions flagged despite inline ignores</b></summary>
29 workflows use one of `astral-sh/setup-uv`, `erlef/setup-beam`, `safedep/pmg`, `super-linter/super-linter`, `actions-ecosystem/action-add-labels`, or `gaurav-nelson/github-action-markdown-link-check`, each already annotated with `# zizmor: ignore[github_action_from_unverified_creator_used]` in the source `.md`/`.yml`. Zizmor still surfaces them as `info`-level notes in this scan mode; no action needed unless the ignore annotations should be tightened per-action.
`smoke-copilot-arm.lock.yml` additionally triggers `pr_runs_on_self_hosted` (warning) because it runs on `ubuntu-24.04-arm`, which is treated as a non-standard/self-hosted-like runner class by zizmor's heuristic — expected for this ARM smoke-test workflow.
</details>
<details>
<summary><b>Grype: images with no critical/high findings</b></summary>
`ghcr.io/github/gh-aw-firewall/api-proxy`, `cli-proxy`, `squid`, `gh-aw-mcpg`, `gh-aw-node`, `github-mcp-server`, and `grafana/mcp-grafana` contribute only medium/low/negligible findings (mostly `bind9-libs`, `libexpat1`, and similar base-OS packages in the firewall agent image). No action recommended beyond routine base-image refresh cadence.
</details>
### Historical Trends
- **Previous Scan**: none found in cache memory (`/tmp/gh-aw/cache-memory/security-scans/index.json` was empty before this run)
- **Total Findings Then**: N/A
- **Total Findings Now**: 2,091
- **Change**: N/A (baseline established)
#### New Issues
All findings are new since this is the first recorded scan.
#### Resolved Issues
None (no prior scan to compare against).
### Recommendations
1. **Immediate**: Review the 4 `RGS-005` (medium) findings — confirm write permissions are actually required for `agentic_commands.yml`, `ai-moderator.lock.yml`, `q.lock.yml`, and `squad.lock.yml` given their externally-triggerable events.
2. **Short-term**: Apply the SC2015 fix in `pkg/workflow/threat_detection_steps.go` (single source change, fixes 275 workflows) and recompile.
3. **Long-term**: Track `ghcr.io/oraios/serena:latest`'s upstream release cadence for the 51 critical CVEs; consider pinning to a patched digest once upstream updates, or evaluate whether a slimmer base image is feasible.
4. **Prevention**: Add a scan of the generated "Copy detection firewall logs" step (or similar shared step-builders) to a pre-commit/CI shellcheck pass on the compiler's Go string templates, so future template changes catch SC-series issues before 275 workflows inherit them at once.
### Next Steps
- [ ] Apply the SC2015 fix in `pkg/workflow/threat_detection_steps.go` and recompile all workflows
- [ ] Review the 4 medium-severity RGS-005 permission findings
- [ ] Monitor `ghcr.io/oraios/serena:latest` upstream for patched critical CVEs
- [ ] Confirm zizmor's 29 unverified-creator-action notes are intentionally accepted (they already carry inline ignores)
- [ ] Consider adding all eight tools to pre-commit hooks
> Generated by [📊 Static Analysis Report](https://github.com/github/gh-aw/actions/runs/32552694294) · agent · 125.4 AIC · ⌖ 13.4 AIC · ⊞ 11.9K · [◷](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-08-29T05:14:52.955Z --> on Aug 28, 2026, 9:14 PM UTC-08:00
<!-- gh-aw-agentic-workflow: Static Analysis Report, engine: claude, model: agent, id: 32552694294, workflow_id: static-analysis-report, run: https://github.com/github/gh-aw/actions/runs/32552694294 -->
<!-- gh-aw-workflow-id: static-analysis-report -->
<!-- gh-aw-workflow-call-id: github/gh-aw/static-analysis-report -->
Activity
github-actions commentedon Aug 22, 2026
🍪 Issue Monster selected this for Copilot
I've identified this issue as a good candidate for automated resolution and requested assignment to the Copilot coding agent.
If assignment succeeds, the Copilot coding agent will analyze the issue and create a pull request with the fix.
Om nom nom! 🍪