Uncategorized

GitHub Actions Package Manager Has 5 Critical Flaws

GitHub Actions executes 5 million workflows daily, making it the dominant CI/CD platform. Yet it has the worst package management system in modern software development. A December 6 analysis by Andrew Nesbitt exposed five fundamental flaws: no lockfiles, no version constraints, no deduplication, no integrity checks, and no central registry. While every package manager from npm to Cargo learned these lessons decades ago, GitHub Actions treats dependency management as a git problem, exposing millions of developers to supply chain attacks and non-reproducible builds.

The Five Fundamental Flaws

GitHub Actions lacks every feature that defines a secure package manager. First, there are no lockfiles to record resolved versions – every workflow re-resolves dependencies at runtime with no memory of what it used last time. Second, version constraints don’t exist because tags are mutable. That @v4 reference can be force-pushed to point to entirely different code tomorrow. Third, there’s no deduplication – reference the same action twice and GitHub downloads it twice. Fourth, integrity verification is absent – no checksums, no hashes, just blind trust that GitHub serves the right bytes. Fifth, there’s no central registry with security scanning, malware detection, or typosquatting prevention.

This isn’t nitpicking. These are security fundamentals that npm, Cargo, NuGet, and even GitLab CI (which added SHA256 hash verification in version 17.9) implement as standard features. GitHub Actions deliberately chose not to, treating dependencies as git refs instead of packages. The result: 97% of workflows use unverified third-party actions, and 54% of JavaScript actions contain security weaknesses.

Why SHA Pinning Doesn’t Save You

GitHub’s recommended solution is SHA pinning: use actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 instead of @v4. Looks secure, right? However, it’s not.

SHA pinning only protects the outer action. When that action internally references other actions (transitive dependencies), those remain unpinned and vulnerable. The March 2025 tj-actions/changed-files incident demonstrated this perfectly: a compromised action updated its transitive dependencies to exfiltrate secrets. Users who SHA-pinned the outer action were still vulnerable because the inner dependencies weren’t pinned. Palo Alto’s “Unpinnable Actions” research documented this systemic gap – 54% of JavaScript actions contain security weaknesses, mostly from indirect dependencies that SHA pinning can’t touch.

Moreover, GitHub pushes security responsibility onto users while knowing their recommended solution doesn’t actually work. A lockfile would make transitive dependencies visible and pinnable. GitHub’s response to Issue #2195 requesting this feature: “not planned.”

Real-World Security Incidents

These aren’t theoretical concerns – they’re active threats. Researchers from Orca Security registered GitHub organizations with typosquatting names: “actons” instead of “actions”, “circelci” instead of “circleci”, “google-github-actons” instead of “google-github-actions”. Within days, 12 repositories were executing malicious workflows. The npm package “@acitons/artifact” (typo of “@actions/artifact”) accumulated over 206,000 downloads before detection.

Furthermore, the March 2025 tj-actions/changed-files compromise went even further. A malicious commit manipulated transitive dependencies to steal repository secrets. Because GitHub Actions has no central registry for security scanning and no integrity verification, the attack succeeded against even security-aware organizations. Research has identified over 4,300 workflows containing code injection vulnerabilities, all exploitable because the package management system lacks basic safeguards.

With no lockfile, developers don’t even know their workflows changed. That failed job you re-ran? It might be executing different code than the original run if someone force-pushed a tag.

The “It’s Just Git” Defense Doesn’t Hold

Defenders argue “GitHub Actions is just git, use SHA pinning.” This misunderstands why package managers exist in the first place. Git is version control, not package management – they solve different problems.

Git doesn’t verify integrity. Package managers do, using checksums in lockfiles. Git doesn’t prevent typosquatting. Package managers do, using central registries with verification. Git doesn’t record what version a tag resolved to. Lockfiles do. Git doesn’t track transitive dependencies. Lockfiles do.

The entire reason npm evolved package-lock.json, Cargo uses Cargo.lock, and NuGet implements package signing is because git refs alone are insufficient for dependency management. Consequently, these tools learned through decades of supply chain attacks that reproducibility, integrity, and visibility are non-negotiable. GitHub Actions ignored these lessons, and developers are paying the price.

Breaking Changes Expose the Fragility

GitHub announced breaking changes that will fail thousands of workflows in early 2025. On January 30, artifacts v3 retires – any job using actions/upload-artifact@v3 will break. On March 1, cache v1-v2 retires – workflows using actions/cache@v1 or @v2 will fail. With 263 million jobs executed monthly, the impact will be massive.

A lockfile would make it trivial to identify affected workflows and plan migrations. Developers could run a simple check: “show me all workflows using artifacts v3.” Instead, teams will discover breakage at runtime. “Worked yesterday, broken today” shouldn’t be the norm for a platform executing 5 million workflows daily. This is precisely why reproducible builds matter – and why every mature package manager implements lockfiles.

What GitHub Should Do (But Won’t)

The solution is well-understood. Implement a lockfile that records resolved SHAs for every action including transitives, integrity hashes for verification, and the complete dependency tree. Make it optional at first – don’t break existing workflows. GitLab CI added integrity verification in version 17.9. Every mature package manager uses lockfiles. This is solved technology.

GitHub closed Issue #2195 requesting lockfile support as “not planned.” The git-first philosophy wins over security and reproducibility. Until pressure mounts – likely after the January-March breaking changes cause widespread failures – developers are stuck with inadequate workarounds.

The question isn’t whether GitHub has the resources and expertise to fix this. They do. The question is whether they’ll prioritize developer security over their architectural comfort zone. Based on the “not planned” response, the answer is no.

Key Takeaways

  • GitHub Actions lacks lockfiles, making builds non-reproducible
  • SHA pinning doesn’t protect transitive dependencies from attacks
  • 97% of workflows use unverified actions with no security scanning
  • Breaking changes in Jan-Mar 2025 will expose the ecosystem’s fragility
  • GitHub rejected lockfile requests as “not planned” despite clear need
ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to simplify complex tech concepts, breaking them down into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *