
15 October 2026 · 9 min
CI without surprises: GitHub Actions gets a lockfile
Workflow dependency lockfiles arrived for GitHub Actions on 14 October. Here is how tags, transitive actions and Dependabot updates become a reviewable supply chain instead of a moving target.




A green workflow can run different code tomorrow
An Action dependency often looks harmless: uses: actions/checkout@v4. It is readable, common and convenient. The catch sits behind @v4. A tag or branch can move, so the same unchanged workflow may resolve to a different commit on a later run than the code the team originally reviewed.
On 14 October 2026, GitHub released workflow dependency lockfiles in public preview. The idea is familiar from npm, pnpm and Cargo: the human-readable version stays in the workflow while a machine-maintained file records the exact commit that will execute.
This does not solve every supply-chain problem. It does close an uncomfortable gap between “we reviewed this reference” and “the runner executed this code”.
What exactly gets locked?
The new file lives at .github/workflows/actions.lock. It is generated by the gh-actions-lock GitHub CLI extension and should not be edited by hand.
For each onboarded workflow it records:
- the actions and reusable workflows the workflow uses;
- the exact commit each reference resolved to when it was locked;
- the numeric identity of the source repository and owner;
- transitive action dependencies, meaning actions loaded by another action.
GitHub executes the locked commit. Moving a tag no longer silently changes the version that runs. Recording repository identity also helps defend against name-reuse attacks after a transfer or rename.
One boundary matters: dependencies inside a called reusable workflow are covered by the lockfile of the repository that defines that workflow. The caller locks the reusable workflow itself, but does not automatically lock its entire internal world.
Why this is better than only putting a SHA in YAML
GitHub has long recommended pinning third-party actions to a full commit SHA in workflow files. That remains a sound approach. A lockfile improves three practical details:
- The workflow stays readable with @v4 or @v4.2.1.
- Transitive action dependencies are captured too.
- Repository identity is stored beside the commit.
Intent and execution become separate. YAML states the version the team wants; the lockfile records the reviewed snapshot. An update can change both layers in one visible pull request.
Adoption does not require a platform migration
Install the extension through GitHub CLI:
gh extension install github/gh-actions-lock
Running gh actions-lock then creates the lockfile and onboards workflows. A team does not have to convert every pipeline at once. GitHub supports gradual adoption per workflow. Once a workflow is onboarded, all its dependencies must be represented in the lockfile.
A sensible first pass is:
- Start with one non-critical CI workflow.
- Review the generated changes and resolved commits.
- Commit workflow and lockfile changes together.
- Add gh actions-lock --verify as a separate CI check.
- Only then onboard deployment and release pipelines.
--verify checks without modifying files that entries exist and remain trustworthy. --verify-local works offline but checks completeness only. The online verification is therefore the relevant guardrail for CI.
Updates become deliberate, not permanently frozen
A lockfile must not become a museum. When an action changes, the new commit still needs review and a new lock.
Run gh actions-lock again after normal workflow dependency changes. Existing pins remain sticky. When the team intentionally wants moving tags or branches to resolve to their current upstream commits, gh actions-lock --relock creates fresh resolutions.
Treat --accept-moved with extra care. It also accepts references whose old commit is no longer reachable from the expected upstream. That may reflect a legitimate repository change, but it can also signal tampering. It belongs in a human review, not an unattended nightly job.
Dependabot reduces the maintenance work. When it updates an action in an onboarded workflow, GitHub says it also regenerates the matching lockfile entry in the same pull request. The version reference, commit and test result can then be reviewed together.
A lockfile is a control, not a seal of approval
An exactly pinned commit can still be unsafe. Locking answers “will the same code run?”, not “is this code benign?”.
The first lock therefore still requires dependency review:
- Who maintains the action and is the project active?
- Which permissions does the job grant it?
- Which secrets can the step access?
- Does third-party code run before or after your repository is checked out?
- Is the action necessary, or would a few owned shell commands be clearer?
- Does the project publish traceable releases and a security policy?
Broad permissions, write-enabled default tokens and secrets exposed to workflows triggered by untrusted input remain especially dangerous. The lockfile reduces dependency drift; it does not reduce the blast radius of a poorly designed workflow.
How to review the first lockfile pull request
Do not wave the first PR through because the file is generated. We review it in four layers.
Workflow inventory: Were only the expected workflows onboarded? Were local actions handled correctly? The preview repository documents current limitations around local-path actions, and those findings must not be ignored.
Dependency graph: Did unexpected transitive actions appear? A small Marketplace step may load other components internally. The inventory makes that chain much easier to review.
Permissions: Does each action match the token rights of its job? Locking is not a reason to grant write access.
Operations: Does the locked pipeline run on pull requests, the default branch and scheduled triggers? Reproducibility has little value when a rare release path breaks weeks later.
Enforce policy only after a pilot
GitHub also offers a Require lockfile policy in public preview for enterprise, organisation and repository administrators. It can prevent workflows from running outside the new model.
The temptation is to enable it everywhere immediately. A staged rollout is safer:
- Choose two or three representative repositories.
- Document reusable-workflow and local-action edge cases.
- Exercise both update and incident procedures.
- Configure central CI checks and Dependabot.
- Expand policy to more teams only after the pilot holds.
The feature is explicitly a public preview. Its format, flags and behaviour may change, and the CLI extension does not currently support GitHub Enterprise Server. A pilot prevents a well-intended security rule from blocking every release.
The default we would use for new projects
For new GitHub Actions projects, the baseline is now straightforward:
- use as few external actions as practical;
- declare minimal job permissions explicitly;
- onboard critical workflows to the lockfile;
- require gh actions-lock --verify in CI;
- ship updates only through reviewable pull requests;
- assess the lockfile, workflow and test result together;
- monitor changes while the feature remains in preview.
For existing systems, prioritise pipelines that deploy, sign, publish or can read production secrets. That is where the difference between a readable version reference and a verifiable commit matters most.
The real gain is not one extra file. It is a clearer team agreement: CI dependencies are production code. They deserve an inventory, review, reproducible resolution and a controlled update path — just like the application they deliver.
Sources



