Securing GitHub Actions CI Dependencies: A Recipe Card

Securing GitHub Actions CI Dependencies: A Recipe Card

Cloud Platform Engineering

Summary:

  • Pin action references to immutable SHA digests, not mutable @v1-style tags
  • Apply least privilege to GITHUB_TOKEN β€” restrict to permissions each workflow actually uses
  • Favor actions from GitHub or Marketplace-verified organizations; audit third-party actions before adoption
  • Enable Dependabot or Renovate to automate digest updates and surface security patches weekly
  • Use static analysis tools (zizmor, Scorecard, frizbee) to catch workflow misconfigurations before they ship

Purpose: A four-layer recipe for closing the supply chain attack surface in GitHub Actions CI pipelines β€” drawing on the patterns that enabled the tj-actions/changed-files compromise and the Hackerbot-claw campaign targeting Trivy and Datadog Actions.

Pre-requisites:

  • A GitHub repository with one or more Actions workflows under .github/workflows/
  • Repository admin permissions to configure Actions settings and Dependabot
  • Basic familiarity with YAML workflow syntax

Steps

  1. Audit current workflows with zizmor. Run zizmor against your workflow directory. It flags unpinned action references, overly permissive token scopes, and known vulnerable patterns before you make any changes.

    pip install zizmor
    zizmor .github/workflows/
  2. Replace mutable tag references with SHA digests. Every uses: action-owner/action-name@v1 reference is a mutable pointer β€” the upstream repo can silently change what v1 resolves to at any time. Pin to the specific commit SHA instead:

    # Before
    - uses: aquasecurity/trivy-action@v0.20.0
    
    # After
    - uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518

    Use frizbee or pinact to automate SHA pinning across all workflow files at once rather than updating manually.

  3. Restrict GITHUB_TOKEN permissions to least privilege. Add explicit permission blocks at the workflow level, then narrow further at the job level if individual jobs need different scopes:

    permissions:
      contents: read
      pull-requests: write  # only if this workflow creates PR comments

    In repository Settings β†’ Actions β†’ General, disable the ability to create or approve pull requests from Actions unless a specific workflow explicitly requires it.

  4. Evaluate third-party actions before adopting. Check for the Verified badge in GitHub Marketplace. Prefer actions maintained by GitHub itself or well-established organizations (aws-actions, docker, google-github-actions). Before adding any new action, review its action.yml to confirm it does not request unexpected permissions or execute arbitrary remote scripts fetched at runtime.

  5. Enable Dependabot for the Actions ecosystem. Add a dependabot.yml config targeting GitHub Actions:

    # .github/dependabot.yml
    version: 2
    updates:
      - package-ecosystem: "github-actions"
        directory: "/"
        schedule:
          interval: "weekly"

    Dependabot opens pull requests to update pinned SHA digests as upstream actions release new versions β€” keeping you current without manual tracking.

  6. Add Scorecard to your CI pipeline. The OpenSSF Scorecard Action runs on push and pull requests, flagging unpinned dependencies and permission issues in the pipeline itself. It surfaces regressions when new workflows are added that don’t follow pinning policy.

  7. Require approval for workflow runs from forks. In Settings β†’ Actions β†’ General, enable β€œRequire approval for all outside collaborators.” This prevents untrusted fork workflows from running in contexts where they can access repository secrets.


The Trap

Pinning only the actions you recognize. The tj-actions/changed-files compromise spread because teams pinned their primary build and test actions but left utility steps β€” changelog generators, label syncers, notification workflows β€” on mutable tags. Every uses: reference in every workflow is a supply chain vector, including the ones that seem low-risk. Audit the entire .github/workflows/ directory, not just jobs that explicitly touch secrets or deployment targets.


Cited References

Photo by RealToughCandy.com on Pexels

Source: CNCF Blog

Content created with AI assistance and reviewed for accuracy.

πŸ’¬

Join the conversation

Stack Insiders is our free community for readers who want to go deeper β€” share resources, ask questions, and connect with others across every vertical we cover.

Join Stack Insiders →

Newsletter coming soon.

Curated digests across AI, biohacking, photography, travel, and more. Be the first to know when we launch.