Every major open source supply chain incident in the past 18 months traces back to a .github/workflows YAML file exploiting documented GitHub Actions features.
Key Takeaways
Five recurring primitives drive every incident: pull_request_target and issue_comment triggers handing write tokens to untrusted workflows, ${{ }} template injection into shell, mutable action tags resolvable across the shared fork object pool, and a cache that silently crosses trust boundaries.
The tj-actions compromise exposed 23,000 repos because action versions are mutable git refs – a force-pushed tag pointing at a dangling object in the fork network is executable without any upstream branch ever holding it.
GitHub’s published security roadmap includes a workflow lockfile, scoped secrets, and an egress firewall – all opt-in, all 3-6 months out, arriving three years after the lockfile issue was closed as “not planned.”
zizmor catches dangerous-triggers, cache-poisoning, unpinned-uses, template-injection, and excessive-permissions; the elementary-data incident was flagged High/High three weeks before it fired.
Hacker News Comment Review
Consensus is that pinning actions to full commit SHAs rather than tags is the correct baseline, but even SHA pins are insufficient without verifying the SHA is reachable from a canonical branch – the fork object pool loophole means a “pinned” SHA can still resolve to unreviewed attacker code.
Several commenters pointed to zizmor, ratchet, and runtime sandboxes like hasp as practical mitigations today, while others argued the root cause is YAML-as-programming-language and pushed for first-class scripting runtimes or Dagger-style portable CI.
There is frustration that GitHub/Microsoft appear slow relative to the severity: one commenter called the product “asleep at the wheel” given the number of mature alternatives and acquisition targets already available.
Notable Comments
@electricapps: Built hasp, an open-source GHA runtime sandbox; first check enforces SHA pinning and verifies the SHA is reachable from a real upstream branch, directly closing the fork-pool loophole.
@pimeys: Sidesteps the problem by using GHA only as a thin caller with all logic in Nix scripts, making CI runs reproducible locally.