package-lock.json, Cargo.lock, or go.sum files to ensure that every build pulls down the exact same library revisions. Yet the actual automation pipelines building and deploying that code—most notably GitHub Actions workflows—have historically relied on moving Git tags like @v3 or branches like @main, or else forced DevOps teams to litter their YAML files with unreadable 40-character commit hashes.
On October 14, 2026, GitHub announced that GitHub Actions workflow dependency lockfiles have entered public preview for GitHub Enterprise Cloud (GHEC) and GitHub Enterprise Cloud with data residency. Alongside the lockfile capability itself, GitHub has launched a companion Require lockfile administrative policy in public preview, giving enterprise, organization, and repository administrators a way to enforce dependency locking across their cloud environments. According to the official github/gh-actions-lock repository, GitHub Enterprise Server (GHES) is not supported in this preview.
For DevOps engineers, Windows and cross-platform software builders, and security administrators who spend their days hardening software supply chains, this marks one of the most consequential architectural improvements to GitHub Actions in years.
The Supply Chain Problem: Why @v3 and Manual SHA Pinning Were Never Enough
To understand why a dedicated workflow lockfile matters, consider what actually happens when a GitHub Actions runner executes a job. When a workflow file includes a line such as uses: octo-org/deploy-action@v3 or uses: octo-org/deploy-action@main, GitHub Actions resolves that tag or branch dynamically at run time.
Git tags and branches are mutable. If an upstream maintainer's account is compromised, or a malicious actor gains write access to a third-party action repository, they can silently repoint the v3 tag to a brand-new commit containing credential-harvesting code. The next time your pipeline runs, it executes the attacker's payload—even though not a single line of YAML changed in your own repository.
Until now, GitHub's primary security recommendation for mitigating this risk was manual full-length commit SHA pinning directly inside workflow YAML files. While effective at stopping a moved tag on a direct dependency, manual SHA pinning came with glaring operational gaps:
- Transitive Dependency Blind Spots: If you pinned Action A to a specific commit SHA, but Action A internally called Action B using a mutable
@v2tag, your pipeline remained vulnerable to changes in Action B. - Readability Headaches: A commit hash tells a human reviewer nothing about which semantic version is running without an accompanying comment—and comments can easily drift out of sync with the hash.
- Repository Hijacking Risks: Standard workflow references rely on account and repository names, which can be subject to rename or redirect shenanigans if an upstream owner changes or deletes an account.
According to GitHub Docs, for repositories that adopt the new workflow dependency lockfile, manual SHA pinning inside workflow YAML files is no longer necessary. Teams can keep human-readable version tags or branches in their .yml workflow definitions while the runtime strictly executes the immutable commits recorded in the lockfile.
Summary: The Evolution of Action Pinning
- Mutable Tags (
@v3): Easy to read, dangerous at run time if an upstream tag moves. - In-YAML SHA Pinning: Secures direct dependencies, obscures version readability, and misses transitive dependencies.
- Workflow Lockfiles (
.github/workflows/actions.lock): Preserves readable tags in YAML, locks direct and transitive action dependencies to exact commits, and verifies numeric repository identities at run time.
Inside .github/workflows/actions.lock: How the Lockfile Works
When you onboard a repository to workflow dependency locking, a machine-generated file is created at .github/workflows/actions.lock. GitHub Docs explicitly warns that this file should never be edited by hand; instead, it is created and maintained through a new GitHub CLI extension, gh actions-lock. Additionally, GitHub maintains an open-source Go parser and schema definition in the github/actions-lockfile repository so security and auditing tools can inspect the dependency graph.
The lockfile consists of two primary sections: workflows and dependencies.
# This file is machine-generated by `gh actions-lock`.
# Do not edit by hand; run `gh actions-lock` to update.
version: 'v0.0.2'
workflows:
'.github/workflows/ci.yml':
- 'octo-org/[email][email protected][/email]'
dependencies:
'octo-org/[email][email protected][/email]':
ref: 'v3.1.0'
commit: 'sha1-...'
owner_id: 44036562
repo_id: 197814629
Here is what each recorded element enforces behind the scenes:
- Workflow-to-Dependency Mapping (
workflows): Lists each onboarded workflow file in the repository and the exact action or reusable workflow references it consumes. - Resolved Reference (
refandcommit): Records the human-readable tag or branch alongside the exact commit SHA it resolved to when the lockfile was generated. At run time, GitHub Actions ignores where the upstream tag currently points and executes the locked commit—and evaluates any "allowed actions" organizational policies against that locked commit. That commit must exist within a branch of the source repository. - Numeric Identity Verification (
owner_idandrepo_id): In addition to the commit SHA, the lockfile captures the immutable numeric IDs of the upstream repository and its owner. At run time, GitHub Actions checks these IDs to guarantee that the repository answering toocto-org/deploy-actionis still the exact same underlying repository you originally locked, blocking repository redirect or rename attacks.
The Crucial Boundary: Transitive Actions vs. Reusable Workflows
One of the most important architectural details documented in GitHub Docs is how lockfile coverage handles nested dependencies.
When an action you use calls other actions (for example, a composite action calling three sub-actions), actions.lock resolves and locks that entire transitive dependency graph inside your repository's lockfile.
However, reusable workflows follow a different boundary rule. While your calling repository's lockfile pins the exact commit of the reusable workflow file itself, the internal dependencies used inside that reusable workflow are not stored in the caller's lockfile. Instead, those dependencies are governed by the .github/workflows/actions.lock file inside the repository where the reusable workflow is defined. Consequently, GitHub Docs recommends that organizations maintaining shared, central reusable workflows onboard those shared repositories to lockfiles first.
Summary: Technical Capabilities of actions.lock
- Location:
.github/workflows/actions.lock. - Coverage: Direct actions, transitive action dependencies, and direct references to reusable workflows.
- Identity Protection: Verifies
owner_idandrepo_idat run time to prevent repo-jacking and redirect spoofing. - Shared Workflow Rule: Reusable workflows must rely on the lockfile in their defining repository to lock their internal steps.
Hands-On Guide: Setting Up and Maintaining Workflow Lockfiles
Because both the lockfile feature and the gh-actions-lock CLI extension are in public preview (and pre-1.0), GitHub notes that command flags, schema versions, and behaviors may change between releases. Before locking, remember a critical security principle emphasized in GitHub's announcement: locking does not determine whether a dependency is safe. It only freezes the revision that runs. Always review your third-party actions before locking them in place.
Step 1: Install the GitHub CLI Extension
Ensure you have the GitHub CLI (gh) installed and authenticated on your workstation, then install the official extension:
gh extension install github/gh-actions-lock
Step 2: Generate the Lockfile
Navigate to the root of your repository and run the extension:
gh actions-lock
By default, running gh actions-lock scans workflow files under .github/workflows/, resolves their dependency graphs, and writes .github/workflows/actions.lock. You can adopt locking across an entire repository at once or onboard workflows gradually one by one. Once a workflow is onboarded into the lockfile, every action dependency it uses must have a valid lockfile entry for the workflow to execute.
If you delete a workflow file later, running a full-directory gh actions-lock scan will automatically prune stale entries for the deleted file (whereas running a scoped command targeting specific workflows will only touch the named workflows).
Step 3: Verify Lockfiles in CI and Pre-Commit Hooks
A lockfile only works if developers don't accidentally commit workflow changes without updating .github/workflows/actions.lock. The CLI provides verification modes tailored for different stages of the development lifecycle:
- Full CI Verification (
gh actions-lock --verify): Checks that the lockfile is up to date without modifying any files. GitHub Docs recommends running this in a pull request CI job so stale lockfiles fail required status checks early. - Offline Pre-Commit Verification (
gh actions-lock --verify-local --no-fix): Designed for local Git pre-commit hooks. It runs offline without needing GitHub authentication, confirming quickly that every dependency in your workflows has a matching entry inactions.lock. Note that--verify-localonly checks structural completeness locally—it does not re-verify pins against GitHub's servers.
Step 4: Updating Dependencies with Dependabot
Nobody wants to manually regenerate lockfiles every time an action releases a patch. Fortunately, Dependabot natively understands .github/workflows/actions.lock out of the box.
When Dependabot opens a pull request to bump an action version in a workflow that is already onboarded to the lockfile, it automatically regenerates the corresponding lockfile entry in the exact same pull request. Keep in mind that Dependabot only maintains existing lockfile coverage; it will not automatically onboard a brand-new workflow that has no lockfile entries yet.
Enterprise Governance: Rolling Out the "Require Lockfile" Policy Safely
For IT administrators and security architects managing GitHub Enterprise Cloud, the companion Require lockfile policy turns this developer tool into an enforceable governance control. Available to repository administrators, organization owners, and enterprise owners, the policy blocks runs of targeted workflows that contain action dependencies if they have not been onboarded to the repository's lockfile.
Can you just flip the switch to Active across your entire enterprise on day one? Only if you enjoy watching every build pipeline grind to an immediate halt and hearing from very unhappy engineering teams.
GitHub Docs lays out a structured, four-stage rollout strategy to avoid breaking production pipelines:
| Rollout Phase | Recommended Action | Why It Matters |
|---|---|---|
| 1. Pilot & Evaluate | Scope the policy to selected repositories and onboarded workflows. Set enforcement to Evaluate mode (available on GitHub Enterprise) and check Policy insights. | Lets administrators see which workflow runs would have been blocked without breaking active developer builds. |
| 2. Automate Maintenance | Enable Dependabot for Actions, add pre-commit hooks, configure a Copilot skill for AI-assisted workflow edits, and deploy a dedicated GitHub Actions workflow triggered on .github/workflows/** and action.yml/action.yaml changes. | Prevents developer friction by ensuring lockfiles are regenerated on push (contents: write) and verified on pull requests (--verify). |
| 3. Enforce Code Review | Add .github/workflows/actions.lock to your repository's CODEOWNERS file and require code-owner approval via branch protection rules or rulesets. | A lockfile is only a security control if a human reads the diff. A changed commit SHA in actions.lock means executable pipeline code has changed. |
| 4. Activate Enforcement | Switch the Require lockfile policy to Active while keeping PR verification checks in place. | Blocks un-locked workflow execution at the platform level while PR checks continue to warn developers early if a lockfile is stale. |
Additionally, for organizations that already enforce GitHub's existing policy requiring actions to be pinned to a full-length commit SHA, the two policies can coexist smoothly during migration. For dependencies covered by a lockfile, GitHub evaluates the SHA-pinning requirement against the locked commit inside actions.lock, allowing teams to keep SHA enforcement active as a safety net for workflows that haven't been onboarded to lockfiles yet.
Summary: Enterprise Administration Takeaways
- Platform Support: Public preview is live on GitHub Enterprise Cloud (including data residency); GitHub Enterprise Server (GHES) is not supported.
- Evaluate Before Blocking: Use Enterprise Evaluate mode and Policy insights to audit readiness before switching the policy to Active.
- Guard the Lockfile: Put
.github/workflows/actions.lockunderCODEOWNERSreview so build-security teams approve any commit SHA changes.
The Bottom Line for DevOps and Security Teams
GitHub Actions workflow lockfiles solve a long-standing friction point between developer ergonomics and supply-chain security. By separating human-readable version intent (@v3.1.0) in .yml workflow files from immutable execution reality (commit, owner_id, and repo_id) in .github/workflows/actions.lock, GitHub brings CI/CD dependency management in line with modern application package managers—and closes the transitive dependency gap that manual SHA pinning left wide open.
If your organization runs on GitHub Enterprise Cloud, now is the time to install gh-actions-lock, test lockfile generation on a pilot repository, and inspect just how many transitive actions your pipelines are quietly pulling in behind the scenes. You might be surprised by how deep the dependency tree actually goes.
References
- GitHub Actions workflow lockfiles in public preview GitHub Changelog · 2026-10-14T13:49:15+00:00
- Workflow dependency lockfiles - GitHub Docs docs.github.com
- Enforcing lockfiles for action dependencies - GitHub Docs docs.github.com