Sample report — fictional repository "acme/webapp"
Scope: 4 workflow files · Result: FAIL (2 high, 3 medium, 1 low) · Est. CI saving: ~$38/month
| # | Check | Result | Where | Fix |
|---|---|---|---|---|
| 1 | Third-party actions pinned to commit SHA | FAIL | deploy.yml:14 some-org/deploy-action@v2 | Pin to full SHA with a # v2 comment; enable Dependabot for actions. |
| 2 | GitHub-owned actions pinned | WARN | ci.yml:9 actions/checkout@v4 | Pin to SHA (low risk, recommended). |
| 3 | Least-privilege GITHUB_TOKEN | FAIL | ci.yml, release.yml — no permissions: | Add top-level permissions: contents: read; grant writes per job. |
| 4 | No write-all | PASS | — | — |
| 5 | pull_request_target safe | FAIL (high) | labeler.yml:3,18 checks out PR head | Switch to pull_request, or never check out / run PR code in this workflow. |
| 6 | No script injection | FAIL (high) | triage.yml:22 echo "${{ github.event.issue.title }}" | Pass via env: TITLE: and use "$TITLE". |
| 7 | Cloud credentials via OIDC | WARN | deploy.yml uses AWS access keys | Use aws-actions/configure-aws-credentials with OIDC role. |
| 8 | Secrets not exposed to forks | PASS | — | — |
| 9 | Concurrency cancels stale runs | WARN | ci.yml | Add concurrency: {group: ci-${{ github.ref }}, cancel-in-progress: true}. |
| 10 | Dependency caching | PASS | — | — |