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-231 generates [ -d X ] && mkdir -p Y && cp -r X/. Y/ || true. If mkdir -p or cp fails, || true silently swallows the error, and it's ambiguous whether -d X was 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:latest image.
- 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 -->
Analysis Summary
This is the first recorded scan in cache memory — no historical baseline exists yet for trend comparison.
Findings by Tool
Clustered Findings by Tool and Type
Zizmor Security Findings
github_action_from_unverified_creator_usedcopilot-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/acknowledgedpr_runs_on_self_hostedsmoke-copilot-arm.lock.yml(usesubuntu-24.04-armrunner)Poutine Supply Chain Findings
No findings — poutine scanned all 287 files cleanly.
Actionlint Linting Issues
shellcheck:SC2129(style)pr-sous-chef.lock.yml(line 551) — suggests grouping redirects with{ cmd1; cmd2; } >> fileSyft SBOM Inventory
Container image package inventory (10 images, 3,694 packages)
ghcr.io/oraios/serena:latestghcr.io/github/gh-aw-firewall/agent:0.28.4ghcr.io/github/gh-aw-mcpg:v0.4.10ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.4ghcr.io/github/gh-aw-nodegrafana/mcp-grafana:1.1.0-alpinenode:lts-alpineghcr.io/github/gh-aw-firewall/api-proxy:0.28.4ghcr.io/github/gh-aw-firewall/squid:0.28.4ghcr.io/github/github-mcp-server:v1.10.0Runner-Guard Taint Analysis Findings
Runner-Guard Score: not reported in this run's output (no score/grade line emitted).
agentic_commands.yml,ai-moderator.lock.yml,q.lock.yml,squad.lock.ymlAll 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
binutilsfamily (binutils, binutils-common, binutils-x86-64-linux-gnu, libbinutils, libctf0, libctf-nobfd0, libgprofng0, libsframe1)ghcr.io/oraios/serena:latesttarghcr.io/oraios/serena:latest,node:lts-alpine(GHSA-23hp-3jrh-7fpw, fix: 7.5.19)perl/perl-base/perl-modules-5.40/libperl5.40ghcr.io/oraios/serena:latestbind9-libsghcr.io/github/gh-aw-firewall/agent:0.28.4libexpat1ghcr.io/oraios/serena:latestnodelibc6ghcr.io/oraios/serena:latest(CVE-2026-5450)ssh/openssh-server/openssh-client/openssh-sftp-serverghcr.io/oraios/serena:latest(CVE-2026-60002)curl/libcurl4t64/libcurl3t64-gnutlsghcr.io/oraios/serena:latest(CVE-2026-9079, -8927, -8926, -8924, -11856, -10536)undici51 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-alpinealso carries thetarGHSA (fixed in 7.5.19).Yamllint YAML Linting Findings
No findings — all 287 files passed yamllint cleanly.
Shellcheck Shell Linting Findings
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 || Cin generated firewall-log-copy steppkg/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.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.2. grype Critical CVEs in
ghcr.io/oraios/serena:latestoraios/serena:latestimage.3. runner-guard RGS-005 — Excessive Permissions on Untrusted Trigger
agentic_commands.yml,ai-moderator.lock.yml,q.lock.yml,squad.lock.ymlpermissions:while triggered by events that can be initiated by external users (e.g.issue_comment,pull_request_target).Fix Suggestion for shellcheck SC2015
Issue: Ambiguous
[ -d X ] && mkdir -p Y && cp -r X/. Y/ || truepattern in generated workflow stepSeverity: Style/Note (correctness ambiguity, not a direct security vulnerability)
Affected Workflows: 275 compiled workflows (single source fix)
Prompt to Copilot Agent:
After:
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.