FR
live

GitHub Actions locks workflow dependencies and scopes secrets to break supply chain attacks

After the tag-repositioning attacks that hit tj-actions and 23,000 repositories, GitHub is rolling out a security roadmap for Actions: dependency lockfiles, scoped secrets, and an egress firewall. Two measures are available today: SHA pinning and OIDC.

A train of identical dark gears where a single amber gear sits slightly out of mesh.

March 2025. The tj-actions attack repositioned a version tag onto a malicious commit: 23,000 repositories ran credential-harvesting code, and 14 secondary breaches were confirmed. March 26, 2026. GitHub published its security roadmap for Actions. Between the two, the conclusion is blunt: this is not a configuration mistake, it is an architectural flaw.

The tj-actions vector is disarmingly simple. When a workflow writes uses: actions/checkout@v4, GitHub resolves the tag at runtime — and v4 can point to a different commit tomorrow than it does today. SHA pinning (the full 40-character hash) seals the top level, but not the transitive dependencies: a composite action calls other actions internally, and those references stay mutable. That is exactly the gap the roadmap sets out to close.

A vector that spreads at the speed of a tag

The tj-actions case is not isolated. Over the past year, incidents targeting Nx and trivy-action followed the same script: a compromised dependency propagates upstream, workflows run without observability or control, and over-permissioned credentials leave through unrestricted network access. The constant is not attack sophistication — repositioning a tag is trivial — but propagation speed: a single malicious commit reaches thousands of repositories within hours, and none of them will ever know what ran in their pipeline.

That observation explains the roadmap’s three-layer structure: ecosystem (deterministic dependencies), attack surface (policies and scoped secrets), infrastructure (observability and egress firewall). The goal is not to make attacks impossible, but to make them visible and bounded — so that a compromised dependency stops being a compromise of the whole chain. That is the architectural fix the title promises: moving responsibility from every developer’s YAML file to a central, enforceable policy layer.

The workflow lockfile, the central change

The headline piece is a dependencies: block in workflow YAML. Like a go.sum or package-lock.json, it records the full dependency tree — direct and transitive — with their commit SHAs. The behavior is that of a lock: if a hash does not match, the job fails before any code runs.

yaml
dependencies:
  actions/checkout:
    version: v4.2.2
    sha: 11bd71901bbe5b1630ceea73d27597364c9af683
  actions/setup-node:
    version: v4.1.0
    sha: 39370e3970a6d050c480ffad4ff0ed4d3fdee5af

The payoff goes beyond security: dependency updates become pull-request diffs, subject to code review, instead of silently propagating on the next run. Resolution happens through the GitHub CLI, which regenerates the lockfile. The feature enters preview in Q2–Q3 2026, with general availability toward year-end.

Scoped secrets and the end of implicit inheritance

The second workstream attacks the credential problem. Today, Actions secrets are scoped at the repository or organization level, and they flow broadly by default — especially through reusable workflows. The coming model, scoped secrets, binds each credential to an explicit execution context: a repository, branch, environment, workflow identity, or trusted reusable workflow.

A structural break accompanies the change: write access to a repository will no longer grant secret-management permissions. That capability moves to a dedicated role. It is a shift to least privilege by default: a secret is issued only when both the workflow and the execution context are explicitly trusted.

Execution policies and the egress firewall

Two more pieces complete the picture. Execution policies extend GitHub’s ruleset framework to workflow triggers: who can run a workflow and which events are allowed — for example, restricting workflow_dispatch to maintainers, or banning pull_request_target for external contributions. An evaluate mode lets you see what would have been blocked before turning on enforcement.

The native egress firewall, the most ambitious and farthest out (preview late 2026, GA 2027), operates at layer 7, outside the runner VM. It stays effective even if an attacker gains root inside the runner. Two modes: monitor, which audits all outbound traffic correlated to workflow, job, and step, then enforce, which blocks anything not on the allowlist.

The reusable workflow trap

The scoped-secrets change targets a specific, widespread pattern: reusable workflows. Today, when a caller invokes a reusable workflow, secrets flow into it implicitly and broadly. Platform teams compose workflows to avoid duplication, but that composition silently widens the blast radius of every credential. A reusable workflow that gets compromised inherits every secret its callers passed — including ones it never needed.

The new model inverts the direction: secrets are bound directly to trusted workflows, callers no longer pass credentials automatically, and trust boundaries become explicit. For a platform team, that is the difference between auditing every caller and auditing one trusted workflow — a meaningful reduction in the surface a single compromised action can reach.

The missing telemetry: Actions Data Stream

Alongside the firewall, GitHub is preparing Actions Data Stream, a telemetry feed that exposes runner execution signals — processes, filesystem, network behavior — in near real time. Today, a compromised workflow runs inside a black box; tomorrow, the platform promises to make what happens inside visible, correlated to the workflow, job, and step that triggered it.

It is the essential counterpart to the rest of the roadmap: a firewall without visibility only blocks blind, and a lockfile without telemetry does not catch what was already compromised before locking. For teams running self-hosted runners, telemetry is also the only way to know what a disposable runner actually executed.

What to do right now

Two measures are available today, and they are the ones that matter now.

SHA-pin your actions. It does not solve transitive dependencies, but it closes the “repositioned tag” vector. An audit is one command:

bash
grep -rn 'uses:' .github/workflows/ | grep -v '@[a-f0-9]\{40\}'

Any line returned is a potential exposure: replace actions/checkout@v4 with the full commit hash, keeping the tag in a comment for readability.

Switch to OIDC with custom property claims. Generally available since April 2026, OIDC issues short-lived, scoped tokens instead of storing long-lived credentials like AWS_ACCESS_KEY_ID in repository secrets. Custom property claims let you define cloud IAM policies from organization metadata — a repository added to the backend team inherits the right role automatically, with no workflow YAML changes.

The timeline matters: most pieces enter preview this quarter and reach general availability by year-end. Waiting for GA to engage means discovering a changed trust model in production all at once. Starting now — SHA-pinning and mapping your workflow triggers — turns a forced migration into a prepared one, and gives platform teams a head start before the lockfile and scoped secrets become the default. The supply chain is only as strong as its loosest tag, and most pipelines still run on loose tags.

Verdict

If you maintain GitHub Actions workflows, SHA-pin your actions and move your cloud credentials to OIDC this week — those are the two immediate, free levers. If you run an organization, prepare the move to scoped secrets and execution policies by first mapping who can trigger what: the rules’ evaluate mode will help without breaking anything. The dependency lockfile, arriving with the preview, will be the real break — but until then, SHA pinning is the net between you and the next tj-actions. Every day on mutable tags is a day the next compromise may already be running in your pipeline.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

GitHub cuts Actions check and run retention from 400+ days to 90 on 1 October

From 1 October 2026, GitHub applies the same retention setting to checks, workflow runs and statuses that already governs artifacts and logs — 90 days by default instead of more than 400. Teams that rely on that history must review their setting and export what they want to keep.

← Back to the feed

Type at least two characters.

navigate open esc dismiss