How to Use GitHub Actions Safely

TLDR; Review the code, pin by commit SHA, and let PRs notify you of updates. Don't auto-apply.

Why this matters: GitHub Actions run with access to your repo secrets, source code, and deployment pipelines. When an attacker compromises a popular action's maintainer account, they can inject malicious code that exfiltrates secrets, backdoors your application, or pivots into your infrastructure. Version tags are mutable. An attacker can retag v1.2.3 to point at malicious code. Only commit hashes are immutable.

What you'll learn:

  • A repeatable process for vetting third-party actions before first use

  • Actions pinned to cryptographically-verified commits that can't be altered upstream

  • A monitoring system that alerts you when updates are available

Prerequisites:

  • GitHub repository with Actions enabled

  • Permission to modify workflow YAML files

  • (Optional) Static analysis or AI tools for code review

Most teams fall into the same three anti-patterns: the convenience trap, update fatigue, and a false sense of security. Version tags like @v1.2.3 are easy to read, but they’re mutable and can be quietly remapped to malicious code. Pinning feels like extra work, so people delay it and worry they’ll miss patches. And when an action is popular, it’s tempting to assume it’s safe because “someone would have noticed.” The rest of this article shows how to beat all three: review the code you plan to run, pin it by full commit SHA, and use pull-request notifications to update on your terms.

Let's dive in.

Step 1: How do I review a GitHub Action before using it?

Answer: Navigate to the action's source repository, review the code in the exact version you plan to use, and scan it for security red flags (e.g. credential access, network calls, and filesystem operations).

Context & principles: Most GitHub Actions request broad permissions by default. They can access your secrets, modify code, and make network calls. A compromised action might look normal at first glance but contain obfuscated exfiltration code. The goal isn't to audit every lineit's to understand what the action does and verify it aligns with your risk tolerance.

Step-by-step guide:

  • Go to github.com/marketplace and search for the action (example: "zap baseline scan")

  • Click "View source code" to open the repository

  • Review the main action file (usually action.yml and the entry point script)

  • Look for red flags:

    • Unencrypted network calls to unknown domains

    • Access to GITHUB_TOKEN or other secrets beyond stated purpose

    • Obfuscated code or encoded payloads

    • Dependencies that don't match the action's stated function

    • Excessive permissions in action.yml

  • (Optional) Run static analysis or use an AI assistant to flag suspicious patterns.

    For an AI agent example, check out: Ownership: the Missing Link in Supply Chain Security

  • Document your findings and approval decision

  • Implement with least-privilege. (permissions: {} - explicitly grant the permissions you need)

Key takeaway: Popular doesn't mean safe. Vet every action like you're granting it root access.

Step 2: How do I pin a GitHub Action to a safe version?

Answer: Replace the version tag with the full SHA commit hash from the exact commit you reviewed, ensuring no one can silently swap the code.

Context & principles: GitHub Actions support three reference formats: branches (@main), tags (@v1.2.3), and commit hashes (@a1b2c3d...). Branches and tags are mutable. A compromised maintainer can reassign them. Only the full 40-character commit hash is cryptographically immutable. Pinning to a hash means you run exactly the code you vetted, until you choose to update.

Step-by-step guide:

  • In the action's repository, click "Tags" to see all versions

  • Click the version you reviewed (e.g., v0.14.0)

  • Note the commit it points to and click that commit

  • Click the copy icon next to the commit hash to copy the full 40-character SHA

  • In your workflow YAML, replace uses: owner/[email protected] with uses: owner/action@a1b2c3d4e5f6... (full hash)

  • Add a comment above the action documenting which version the hash corresponds to:

       # zaproxy/action-baseline v0.14.0
       - uses: zaproxy/action-baseline@7c4deb10e6...
  • Commit with message: "Pin zaproxy/action-baseline to v0.14.0 commit hash"

Example:

  • Before: uses: zaproxy/[email protected] (mutable tag, can be reassigned)

  • After: uses: zaproxy/action-baseline@7c4deb10e6... (immutable hash)

  • Notes: If the action's account is compromised and v0.14.0 is re-tagged, your pipeline still runs the original, vetted code

Key takeaway: Version tags are bookmarks that can be moved. Commit hashes are permanent fingerprints.

Step 3: How do I keep actions updated without reintroducing risk?

Answer: Use Dependabot or Renovate to raise pull requests when new versions are published, then re-review and re-pin only after confirming the code is trustworthy.

Context & theory: Pinning to a hash solves the trust problem but creates an update problem. You need patches and features from newer versions, but you can't auto-apply them without re-vetting. The solution is a pull-request-driven workflow: tools detect updates, you review the diff between your pinned version and the new one, and you merge only after verifying its safe.

Step-by-step guide:

  • Enable Dependabot for GitHub Actions in your repository settings (Settings > Advanced security > Dependabot > Enable version updates)

  • Configure .github/dependabot.yml:

       yaml
       version: 2
       updates:
         - package-ecosystem: "github-actions"
           directory: "/"
           schedule:
             interval: "weekly"
           open-pull-requests-limit: 5
  • When Dependabot opens a PR, review the "Commits" tab to see the diff between your pinned version and the proposed version

  • Re-apply Step 1's review process to the changes

  • If safe, approve and merge; Dependabot will update the hash automatically

  • (Optional) Set up CODEOWNERS to require security team review for workflow changes. (note: I cover this in my [DevSecOps Pro course](https://www.devsecopspro.com)

Key takeaway: Automate discovery, not approval.Let tools find updates, but run them through your standard PR approval process.

FAQ

What if I'm already using dozens of actions with version tags?

Audit them in priority order: start with actions that access secrets, deploy to production, or modify code. Use git log -p .github/workflows/ to see when each action was added, and review from newest to oldest. Budget 5-10 minutes per action for review and re-pinning.

Can I use short commit hashes (7 characters) instead of full hashes?

No. Short hashes are vulnerable to collision attacks. GitHub Actions require the full 40-character SHA hash for security.

How do I know if a new version is worth updating to?

Compare commits between your pinned hash and the proposed hash using the action's repository compare view: https://github.com/owner/action/compare/OLD_HASH...NEW_HASH. If the diff includes only dependency patches or bug fixes (no new permissions or network calls), it's usually safe. If it introduces new functionality, re-apply your full review process.

What if Dependabot doesn't support my setup?

Renovate is a more flexible alternative that supports GitHub Actions, GitLab CI, and many other ecosystems. You can also write a simple script to check for new tags and open issues manually.

Sources & Further Reading

Whenever you are ready, here are 3 ways I can help:

  • DevSecOps Pro - My flagship course for security engineers and builders. 32 lessons, 16 hands-on labs, and templates for GitHub Actions, AWS, SBOMs, and more. Learn by doing and leave with working pipelines. Learn more about DevSecOps Pro

  • Career Hacking Quest – A practical course and community to help you land security roles. Bi-weekly live resume reviews, interview strategies, and step-by-step guidance for resumes, LinkedIn, and outreach. Learn more about Career Hacking Quest

  • Lunir - My startup aimed at making breaches optional. Working on a product to automate software supply chain remediation.

Subscribe to the Newsletter

Join other product security champions getting deep dives delivered to their inbox for free every Tuesday.

Follow us:

Quick Links

Supports Links

Quick Links

© 2025 Mission InfoSec. All Rights Reserved.