Opsio - Cloud and AI Solutions
DevOpsCI/CDSecurity7 min readΒ· 1,339 words

GitHub Actions Marketplace: Vetting Third-Party Actions for Supply-Chain Security

Published: Β·Updated: Β·Reviewed by Opsio Engineering Team
Fredrik Karlsson

Group COO & CISO

Operational excellence, governance, and information security. Aligns technology, risk, and business outcomes in complex IT environments

GitHub Actions Marketplace: Vetting Third-Party Actions for Supply-Chain Security

Every uses: some-org/some-action@v3 in your workflow is an arbitrary-code-execution dependency. The action runs on your runner, with your runner's network access, your GITHUB_TOKEN, and any environment variables in scope when it executes. The Marketplace lists 20,000+ such dependencies. Not all of them are written by GitHub. Some are written by tiny one-person side projects that get acquired, abandoned, or compromised. Vetting them is not optional β€” it is a core supply-chain security practice that belongs alongside SCA, container scanning, and dependency review.

This article documents the vetting framework we apply when selecting third-party Actions for production workflows, and the controls that go around that selection: organisation policies, SHA pinning, Dependabot, and runtime egress restrictions. It assumes you have read the basics of github actions for enterprise and you're now thinking about hardening the workflow estate.

Real Incidents That Motivate the Framework

Three publicly-disclosed incidents shape how we think about Marketplace risk:

  • tj-actions/changed-files (March 2025) β€” a maintainer's PAT was compromised; the attacker pushed a malicious commit to multiple major-version tags. Workflows using @v44 or similar floating tags executed code that exfiltrated CI secrets to a remote endpoint. Repos pinned to a SHA were unaffected
  • codecov bash uploader (April 2021) β€” not a Marketplace Action specifically, but the same shape: a popular CI helper script was modified to exfiltrate environment variables. Estimated thousands of downstream secrets exposed
  • SolarWinds (December 2020) β€” different industry, same supply-chain pattern. Trusted upstream, compromised, downstream blast radius enormous. The lesson generalised: any third-party dependency that runs in your build environment is a security boundary

The defence against this class of attack is not "use only first-party Actions." That is impractical and discards a lot of legitimate value. The defence is a vetting framework plus runtime controls that limit blast radius if a vetted dependency is later compromised.

The Vetting Checklist

Before adopting a third-party Action into a production workflow, we evaluate it against an eight-point checklist:

  1. Publisher trust β€” is the publisher a verified GitHub-creator, a known org (e.g. aws-actions, azure, docker, hashicorp), or an individual maintainer? Verified-creator badge is necessary but not sufficient
  2. Activity β€” recent commits, recent releases, multiple maintainers, response to issues. Abandoned actions are tomorrow's compromised actions
  3. Source visibility β€” is the source code in a public repo with a clear release history? JavaScript actions ship transpiled dist/ files; verify the dist matches the source by re-running the build locally
  4. Permissions footprint β€” what does the action's action.yml actually do? Does it need network access, file-system writes, secret reads? Most actions need far fewer permissions than they receive by default
  5. Pinning support β€” does the action publish stable major-version tags? Does it have a release process or just a maintainer pushing to main?
  6. Dependency tree β€” for JavaScript actions, what npm dependencies are pulled in? For container actions, what base image? An action that pulls in 80 npm packages has 80 supply-chain dependencies of its own
  7. Alternative β€” is there a first-party or verified-creator alternative that does the same job? actions/setup-node beats third-party Node setups; aws-actions/configure-aws-credentials beats third-party AWS auth wrappers
  8. Blast radius if compromised β€” what would a malicious version of this action do with the secrets and tokens it has access to? An action used in a deploy job has a much larger blast radius than one used in a lint job

Actions that fail point 1, 2, or 5 are rejected. Actions that fail point 3 are flagged for in-house re-implementation. Actions that pass all eight are added to an org-level allow-list.

Free Expert Consultation

Need expert help with github actions marketplace?

Our cloud architects can help you with github actions marketplace β€” from strategy to implementation. Book a free 30-minute advisory call with no obligation.

Solution ArchitectAI ExpertSecurity SpecialistDevOps Engineer
50+ certified engineersAWS Advanced Partner24/7 support
Completely free β€” no obligationResponse within 24h

Organisation-Level Allow-List

GitHub's organisation settings let you restrict which Actions can run across all repos:

PolicyEffectWhen to use
Disable ActionsNo workflows run anywhereInactive orgs, decommissioned
Allow only this org's actions and reusable workflowsOnly Actions from your own orgHighly regulated estates with strict third-party-software policies
Allow this org plus verified creatorsOrg plus actions from GitHub-verified publishersCommon default for security-conscious customers
Allow specified actionsCurated allow-list of action pathsProduction-grade default for most enterprises
Allow all actions and reusable workflowsAnything from MarketplaceDevelopment orgs, sandbox environments only

The "Allow specified actions" mode takes a comma-separated list of patterns: actions/*, aws-actions/*, docker/build-push-action@*, hashicorp/setup-terraform@v3. Wildcards are powerful but risky β€” foo/* trusts every action that publisher might add later, including new actions you have not vetted. Prefer specific paths plus version constraints.

SHA Pinning Plus Dependabot

The SHA-pinning argument is straightforward: tags are mutable, commit SHAs are not. actions/checkout@v4 can be repointed to a malicious commit by anyone who controls the v4 tag. actions/checkout@a81bbbf6f6e74d8f4e8b7b8b8b8b8b8b8b8b8b8b cannot. The downside of SHA pinning is that you have to update SHAs as upstream actions release fixes. Dependabot solves this:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: weekly
    groups:
      github-actions:
        patterns: ['*']

Dependabot scans your workflow files weekly, opens PRs for SHA updates, and (with the new groups syntax) bundles them so you review one PR per week instead of fifty. Pair this with branch protection requiring CI to pass before merge, and you have a sustainable model: SHA-pinned safety with weekly maintenance overhead.

Runtime Controls: Limit Blast Radius

Even with a vetted, pinned action, you should treat its execution context as hostile. The four runtime controls:

  1. Minimal permissions β€” every workflow declares permissions: at the top level, scoped to the smallest set of GITHUB_TOKEN rights needed. Default to permissions: read-all at the org level and let workflows escalate explicitly
  2. OIDC, not static secrets β€” short-lived federated credentials with environment-bound trust policies (see our deep-dive on OIDC federation). A compromised action without long-lived secrets has nothing to steal
  3. Egress restrictions on self-hosted runners β€” runners that only need to talk to your container registry, package mirror, and cloud APIs should not have wildcard internet egress. Put runners on a network that allow-lists egress destinations
  4. Secret scanning post-incident β€” if a third-party action is later disclosed as compromised, every secret that ever ran through that action's job needs rotation. Tag jobs with the actions they invoke so post-incident sweeps are mechanical

The Process: How New Actions Enter the Allow-List

The vetting framework is only useful if it is a process, not a one-time exercise. The pipeline we deploy in customer engagements:

  1. Engineer files an "Action proposal" issue with the action path, intended use, and a link to alternative options considered
  2. Security engineer applies the eight-point checklist; documents findings on the issue
  3. If accepted, the action is added to the org allow-list with a SHA pin; Dependabot configuration is updated
  4. Engineer's PR using the new action references the issue; review verifies the SHA matches the approved one
  5. Quarterly review: every approved action is re-evaluated against the checklist (mostly a check on activity and known-vuln status)

The cycle time on a typical proposal is 2-5 business days. The cost is real but not crippling, and it pays for itself the first time a popular action gets compromised β€” which, as the tj-actions incident showed, happens.

How Opsio Helps

Opsio's security practice runs Marketplace-vetting frameworks for customers as part of broader CI/CD security engagements. We typically deliver the org allow-list policy, SHA-pinning sweep, Dependabot rollout, and the proposal-and-review process in 4-6 weeks alongside our wider end-to-end cloud security work. For organisations also operating end-to-end managed detection, we wire the workflow audit logs into the SOC pipeline so anomalous Action invocations surface as detection signals. Customers running broader CI/CD security programmes use our zero-downtime github actions as the integration point for vetting, OIDC, and runner-fleet hardening.

For hands-on delivery, see managed iot supply.

About the Author

Fredrik Karlsson
Fredrik Karlsson

Group COO & CISO at Opsio

Operational excellence, governance, and information security. Aligns technology, risk, and business outcomes in complex IT environments

Editorial standards: This article was written by a certified practitioner and peer-reviewed by our engineering team. We update content quarterly to ensure technical accuracy. Opsio maintains editorial independence β€” we recommend solutions based on technical merit, not commercial relationships.