Why lock workflow dependencies?
Workflows often reference an action by a tag or branch, such as uses: octo-org/deploy-action@v3 or uses: octo-org/deploy-action@main. GitHub Actions resolves that reference to whatever commit the tag or branch points to at run time.
Tags and branches can move. As a result, the code that runs is not guaranteed to be the code that the workflow author originally reviewed. If an upstream maintainer's account is compromised and a tag is repointed, your repositories could run malicious code.
A workflow dependency lockfile pins a commit SHA to every action your workflows depend on, including transitive dependencies. It doesn't pin calls to reusable workflows (jobs.<job_id>.uses). To pin a reusable workflow, reference it by its full commit SHA. A lockfile controls which action code runs on the runner. It doesn't control other build inputs, such as input parameters, secrets, or the runner image. A lockfile gives you the following for the action code it covers:
- Reproducible resolution of action dependencies
- Reviewable dependency changes and Dependabot version updates
- An auditable inventory of your CI/CD systems' action dependencies
How does the lockfile work?
The lockfile is defined in a repository at .github/workflows/actions.lock. It's generated by gh actions-lock, a GitHub CLI extension, and should never be edited by hand.
You can onboard a repository's workflows to the lockfile one at a time or all at once. After a workflow is onboarded:
- Every action dependency the workflow uses must be present in the lockfile.
- The locked commit is what runs when the workflow executes, and what allowed actions policies check.
- This commit must be reachable from the branch or tag recorded for it in the lockfile, in the action's own repository. A commit that exists only in a fork, or that's no longer reachable from that branch or tag, is rejected when the workflow runs.
A lockfile covers the workflows in its own repository, including transitive dependencies (actions that your action dependencies use), except for dependencies of reusable workflow calls. Reusable workflows can have their own lockfiles too. A reusable workflow's dependencies are covered by the lockfile of the repository where it's defined, not by the lockfile of the repository that calls it.
What does the lockfile record?
The lockfile has two sections. workflows records which dependencies each onboarded workflow uses, and dependencies records which commit each of those references resolves to.
# This file is machine-generated by `gh actions-lock`.
# Do not edit by hand; run `gh actions-lock` to update.
# Docs: https://gh.io/actions-lockfile
version: 'v0.0.3'
workflows:
'.github/workflows/ci.yml':
- 'octo-org/deploy-action@v3.1.0'
dependencies:
'octo-org/deploy-action@v3.1.0':
ref: 'v3.1.0'
commit: 'sha1-...'
owner_id: 44036562
repo_id: 197814629
Each dependency records:
ref: The tag or branch the commit was resolved from.commit: The exact commit the reference resolved to. This is the code that will run.owner_idandrepo_id: The numeric identity of the source repository. GitHub Actions uses these to confirm at run time that the repository behind the name is still the one you locked.
This structured format gives tools like Dependabot a machine-readable record they can use to manage dependency updates, without relying on YAML comments as version annotations.
How do lockfiles compare with SHA pinning?
GitHub has historically recommended pinning third-party actions to a full-length commit SHA in your workflow files. For repositories that adopt a lockfile, SHA pinning within workflow files is no longer necessary. The lockfile is the better option because it:
- Supports transitive dependencies
- Makes workflow files easier to read
- Records the identity of the source repository
A lockfile also satisfies the separate Require actions to be pinned to a full-length commit SHA policy for workflows that are onboarded to it. See Governing execution of GitHub Actions workflows.
Next steps
To create a lockfile for a repository, see Locking action dependencies in a repository's workflows.