|
| 1 | +--- |
| 2 | +title: Enforcing lockfiles for action dependencies |
| 3 | +shortTitle: Enforce workflow lockfiles |
| 4 | +intro: 'Require workflow dependency lockfiles across your repositories, and automatically keep the files up to date.' |
| 5 | +versions: |
| 6 | + feature: actions-workflow-lockfiles |
| 7 | +permissions: 'Repository administrators, organization owners, and enterprise owners' |
| 8 | +product: '{% data variables.product.prodname_ghe_cloud %}' |
| 9 | +contentType: how-tos |
| 10 | +--- |
| 11 | + |
| 12 | +> [!NOTE] {% data reusables.actions.workflow-lockfiles-preview %} |
| 13 | +
|
| 14 | +Requiring lockfiles gives you consistent, auditable assurance that every workflow runs vetted code, without asking each team to adopt the practice on its own. For an introduction, see [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). |
| 15 | + |
| 16 | +This guide helps you run a pilot in selected repositories and set up automations to keep the lockfiles up to date. When you're confident the lockfiles are working as intended and not introducing developer friction, you can enforce the **Require lockfile** policy. |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +Before you enforce workflow lockfiles and create processes to keep them up to date, the lockfile must exist in your repositories. For instructions, see [AUTOTITLE](/actions/how-tos/secure-your-work/lock-workflow-dependencies). |
| 21 | + |
| 22 | +## 1. Pilot the "require lockfile" policy |
| 23 | + |
| 24 | +>[!IMPORTANT] **Evaluate** mode for policies is only available on {% data variables.product.prodname_enterprise %}. Do not enable this policy in **Active** mode until you're confident you have systems in place to keep the lockfile up to date for all targeted workflows. |
| 25 | +
|
| 26 | +The **Require lockfile** policy blocks runs of targeted workflows that include action dependencies but are **not** onboarded to the repository's lockfile. To configure the policy, see [AUTOTITLE](/actions/how-tos/administer/control-workflow-execution). |
| 27 | + |
| 28 | +Run a pilot before enforcing this policy in all repositories. You should: |
| 29 | + |
| 30 | +* Scope the policy to specific repositories that have onboarded to lockfiles. |
| 31 | +* Target specific workflows that have been onboarded to the lockfile. Do this until all workflows are onboarded _and_ you have processes in place to ensure new workflows are onboarded automatically. |
| 32 | +* Start with the policy in **Evaluate** mode and analyze the results under **Policy insights** |
| 33 | + |
| 34 | +## 2. Keep lockfiles current |
| 35 | + |
| 36 | +Enforcement only works if lockfiles stay up to date. Add automations so that developers do not need to remember to run the lock command every time they create or edit workflows. |
| 37 | + |
| 38 | +The following sections give examples for how to prevent stale lockfiles at different points of the development lifecycle. |
| 39 | + |
| 40 | +* Keep the file up to date by enabling {% data variables.product.prodname_dependabot %} and creating a workflow to run the lock command. |
| 41 | +* Add a skill and pre-commit hook to shorten the feedback loop for developers. |
| 42 | + |
| 43 | +For ready-to-copy implementations of the workflow and the skill, see the [gh-actions-lock](https://github.com/github/gh-actions-lock) repository. |
| 44 | + |
| 45 | +### {% data variables.product.prodname_dependabot %} version updates |
| 46 | + |
| 47 | +When {% data variables.product.prodname_dependabot %} bumps an action version, it regenerates the matching lockfile entry in the same pull request. |
| 48 | + |
| 49 | +You don't need any configuration beyond having {% data variables.product.prodname_dependabot %} manage {% data variables.product.prodname_actions %} dependencies. See [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/auto-update-actions). |
| 50 | + |
| 51 | +{% data variables.product.prodname_dependabot %} will **not** onboard a workflow that has no lockfile entries yet, so this option maintains coverage rather than extending it. |
| 52 | + |
| 53 | +### A dedicated {% data variables.product.prodname_actions %} workflow |
| 54 | + |
| 55 | +When someone adds or edits a workflow, run another workflow that runs the lock command. Trigger the workflow on changes to `.github/workflows/**` and to any `action.yml` or `action.yaml` file, then give it two jobs: |
| 56 | + |
| 57 | +* An **update** job that regenerates the lockfile on push and commits the result. This job needs `contents: write` permissions, and your branch protection rules or rulesets must allow {% data variables.product.prodname_actions %} to push to the branches it runs on. |
| 58 | +* A **verify** job that runs `gh actions-lock --verify` on pull requests. This should exit with an error if the lockfile is stale, making it useful for a required check. |
| 59 | + |
| 60 | +### A {% data variables.product.prodname_copilot_short %} skill |
| 61 | + |
| 62 | +When {% data variables.product.prodname_copilot_short %} edits a workflow file, tell it to run the command to update the lockfile in the same changeset. |
| 63 | + |
| 64 | +The skill should tell {% data variables.product.prodname_copilot_short %} to regenerate the lockfile with the CLI whenever it changes a workflow or a local action, and never to edit the lockfile directly. It only covers edits made with {% data variables.product.prodname_copilot_short %}, so treat it as a convenience rather than a control. See [AUTOTITLE](/copilot/concepts/agents/about-agent-skills). |
| 65 | + |
| 66 | +### A pre-commit hook |
| 67 | + |
| 68 | +This catches a stale lockfile before a commit exists, which is the earliest feedback a developer can get. |
| 69 | + |
| 70 | +Use `gh actions-lock --verify-local --no-fix` in the hook. It works offline, doesn't need authentication, and is fast enough to run on every commit. This command confirms that every dependency has a lockfile entry, but does not re-verify the pins against {% data variables.product.github %}. |
| 71 | + |
| 72 | +## 3. Set up a review process for lockfile changes |
| 73 | + |
| 74 | +A lockfile is only a security control if someone reads the diff. A changed commit SHA tells you that the code your workflows run has changed. |
| 75 | + |
| 76 | +1. Add `.github/workflows/actions.lock` to your `CODEOWNERS` file so that the team responsible for build security is automatically requested for review. See [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). |
| 77 | +1. Configure a branch protection rule or repository ruleset to require approval from a code owner. |
| 78 | +1. Tell reviewers what to look for. For guidance, see [AUTOTITLE](/actions/how-tos/secure-your-work/lock-workflow-dependencies#reviewing-lockfile-changes). |
| 79 | + |
| 80 | +## 4. Enforce the policy |
| 81 | + |
| 82 | +When you're confident that lockfiles are in place and will stay up to date, change the enforcement status of the **Require lockfile** policy to **Active**, and ensure all onboarded repositories and workflows are targeted. |
| 83 | + |
| 84 | +Leave the verification from step 2 in place. The policy will block a workflow run that has no valid lockfile, but a verification check tells an author their lockfile is stale while they're still working on the pull request. |
0 commit comments