Skip to content

Back to the catalog

A trust checklist for GitHub Actions
jessehouwing.netwriteup

A trust checklist for GitHub Actions

Presents a tiered trust checklist for evaluating third-party GitHub Actions before referencing them in a workflow, covering maintenance/tooling signals, unpinned transitive dependencies, release attestations, and governance, with weaker popularity-based signals separated into a second tier. It then argues that any point-in-time trust assessment only holds if the referenced commit is immutable, and compares raw SHA pinning against GitHub's immutable releases and the new gh-actions-lock CLI extension, which verifies commit reachability to defeat impostor-commit attacks. It closes by noting StepSecurity's GitHub Action Advisor automates some of the checklist's queryable signals using Harden-Runner telemetry.

TL;DR A practical, tiered checklist for deciding whether to trust a third-party GitHub Action, plus why SHA pinning alone isn't enough and how gh-actions-lock and immutable releases close the gap.
Document

What it is

A practitioner's trust checklist for third-party GitHub Actions, plus the concrete commands and verification model behind gh-actions-lock. The summary names the checklist and tools; it omits the commands, the triage-by-effort model, and several sharp operational caveats that determine whether any of it actually protects you.

What to do

Lock every resolved commit regardless of your trust decision. The page's tool is gh-actions-lock, a gh CLI extension from GitHub's Workflow Dependency Pinning effort that writes .github/workflows/actions.lock:

gh extension install github/gh-actions-lock
gh actions-lock              # scan workflows, pin, write the lockfile
gh actions-lock --relock     # re-resolve refs that have legitimately moved

Pair locking with dependency automation (Renovate or Dependabot) configured with a cooldown period, so a compromised release has time to be discovered before it reaches your pipelines.

How the lockfile beats a raw SHA

This is the reader-actionable core the summary compresses. A raw SHA in a uses: line gives no proof the commit belongs to the repository's history. The classic bypass: a commit pushed to a fork remains reachable through the upstream repo's object store, so it resolves successfully and looks legitimate — an impostor commit. The lockfile's checks close this:

  • The SHA must exist in the refs it claims to exist in (forgery check).
  • A locked action must have a branch containing the locked commit (reachability — this defeats the fork/impostor case).
  • Repository identity is recorded; redirects or mismatches are blocked at runtime.
  • Onboarded workflows enforce that the locked commit is what executes on the runner.

Triage by effort (how to actually work the list)

The signals split by cost to check, which tells you what to automate versus reserve human/AI time for:

  • Automatable/queryable: policy files, licence, Node handler version, action.yml contents, immutable-release status, marketplace presence, advisory status, maintainer count, update recency.
  • Needs AI assistance: unpinned transitive dependencies (e.g. npx some-tool at runtime), floating Docker tags in shell invocations, unvalidated remote downloads — the author prioritises the unpinned-dependency category above all.
  • Needs manual review: versioning history, artefact validation logic, whether an egress firewall is actually enforcing, and whether the action does what it claims.

Caveats the page states

  • Attestations do not transfer. They bind to the source repository. If you mirror actions internally, validation must run against the original source, not the mirror.
  • Firewall audit mode ≠ containment. Audit mode records egress without blocking it; check it is actually enforcing.
  • Immutable releases cover only release-specific tags (e.g. v1.0.0). Floating convenience tags like v1/v1.1 are deliberately movable and unprotected — hence you still need your own lock.
  • gh-actions-lock is a pre-1.0 technical preview; format and flags may change.

Organisations named here

  • impostor commit
  • Workflow Dependency Pinning

Technologies named here

  • gh-actions-lock
  • GitHub Actions
  • Renovate
  • Dependabot
  • StepSecurity GitHub Action Advisor
  • Harden-Runner
  • StepSecurity

Techniques named here

  • Unpinned transitive/runtime dependencies
  • Floating tag force-push / mutable reference
  • Impostor-commit attack
  • Floating Docker tags in shell invocations
  • Unvalidated remote downloads
  • Audit-mode-only egress firewall
  • Attestation mirroring gap