CI Hardening

Sample report — fictional repository "acme/webapp"

GitHub Actions security review

Scope: 4 workflow files · Result: FAIL (2 high, 3 medium, 1 low) · Est. CI saving: ~$38/month

#CheckResultWhereFix
1Third-party actions pinned to commit SHAFAILdeploy.yml:14 some-org/deploy-action@v2Pin to full SHA with a # v2 comment; enable Dependabot for actions.
2GitHub-owned actions pinnedWARNci.yml:9 actions/checkout@v4Pin to SHA (low risk, recommended).
3Least-privilege GITHUB_TOKENFAILci.yml, release.yml — no permissions:Add top-level permissions: contents: read; grant writes per job.
4No write-allPASS——
5pull_request_target safeFAIL (high)labeler.yml:3,18 checks out PR headSwitch to pull_request, or never check out / run PR code in this workflow.
6No script injectionFAIL (high)triage.yml:22 echo "${{ github.event.issue.title }}"Pass via env: TITLE: and use "$TITLE".
7Cloud credentials via OIDCWARNdeploy.yml uses AWS access keysUse aws-actions/configure-aws-credentials with OIDC role.
8Secrets not exposed to forksPASS——
9Concurrency cancels stale runsWARNci.ymlAdd concurrency: {group: ci-${{ github.ref }}, cancel-in-progress: true}.
10Dependency cachingPASS——

Priority order

  1. Fix #6 and #5 today — anyone who can open an issue or PR could run code with your token.
  2. Add permissions blocks (#3) and pin third-party actions (#1).
  3. Move to OIDC (#7) and add concurrency (#9) to cut ~20% of minutes.

Get this for your repo