diff --git a/content/actions/concepts/security/index.md b/content/actions/concepts/security/index.md index f03e1f11bbf7..bd22031eee38 100644 --- a/content/actions/concepts/security/index.md +++ b/content/actions/concepts/security/index.md @@ -12,6 +12,7 @@ children: - /openid-connect - /artifact-attestations - /script-injections + - /workflow-dependency-lockfiles - /compromised-runners - /kubernetes-admissions-controller contentType: concepts diff --git a/content/actions/concepts/security/workflow-dependency-lockfiles.md b/content/actions/concepts/security/workflow-dependency-lockfiles.md new file mode 100644 index 000000000000..c5f4e6296694 --- /dev/null +++ b/content/actions/concepts/security/workflow-dependency-lockfiles.md @@ -0,0 +1,68 @@ +--- +title: Workflow dependency lockfiles +shortTitle: Dependency lockfiles +intro: 'A lockfile pins every action your workflows depend on to a verified commit, so the code you reviewed is the code that runs.' +versions: + feature: actions-workflow-lockfiles +category: + - Secure your workflows +contentType: concepts +--- + +> [!NOTE] {% data reusables.actions.workflow-lockfiles-preview %} + +## Why lock workflow dependencies? + +When a workflow references an action by a tag or branch, such as `uses: octo-org/deploy-action@v3` or `uses: octo-org/deploy-action@main`, {% data variables.product.prodname_actions %} resolves that reference to whatever commit the tag or branch points to at run time. + +Tags and branches can move, so 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 (including transitive dependencies) and reusable workflow your workflows depend on. This gives you: + +* Reproducible builds +* Reviewable dependency changes and {% data variables.product.prodname_dependabot %} version updates +* An auditable inventory of your CI/CD systems' 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 {% data variables.product.prodname_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 exist within a branch of the source repository. + +A lockfile covers the workflows in its own repository. It extends to transitive dependencies (actions that _your action dependencies_ use), **except** for dependencies of reusable workflow calls. A reusable workflow is covered by the lockfile of the repository where it is defined. + +## 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. + +```yaml +# 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/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 reference the workflow uses, such as a tag or branch. +* **`commit`**: The exact commit the reference resolved to. This is the code that will run. +* **`owner_id` and `repo_id`**: The numeric identity of the source repository. {% data variables.product.prodname_actions %} uses these to confirm at run time that the repository behind the name is still the one you locked. + +## How do lockfiles compare with SHA pinning? + +{% data variables.product.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, and records the identity of the source repository. + +## Next steps + +To create a lockfile for a repository, see [AUTOTITLE](/actions/how-tos/secure-your-work/lock-workflow-dependencies). diff --git a/content/actions/how-tos/administer/control-workflow-execution.md b/content/actions/how-tos/administer/control-workflow-execution.md index bcdc3882c6b3..656cab729e28 100644 --- a/content/actions/how-tos/administer/control-workflow-execution.md +++ b/content/actions/how-tos/administer/control-workflow-execution.md @@ -1,5 +1,5 @@ --- -title: Controlling who can execute {% data variables.product.prodname_actions %} workflows +title: Governing execution of {% data variables.product.prodname_actions %} workflows shortTitle: Control workflow execution intro: Control who can trigger {% data variables.product.prodname_actions %} workflows and which events are permitted to run them across an enterprise, organization, and repository. versions: @@ -78,6 +78,18 @@ Only the allowed actors will be able to run the specified workflows in the targe Event rules control which events are permitted, such as `push`, `pull_request`, `pull_request_target`, and `workflow_dispatch`. +{% ifversion actions-workflow-lockfiles %} + +### Require lockfile + +The **Require lockfile** protection blocks runs of workflows with `uses:` dependencies on other actions, unless the dependencies are pinned in a dependency lockfile. This ensures that the targeted workflows run predictable, vetted code, rather than whatever a tag or branch points to at run time. See [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). + +Generate and verify lockfiles in the repositories you're targeting before you set this protection to **Active**. Otherwise, you'll block workflow runs in repositories that aren't ready. For a staged rollout, see [AUTOTITLE](/actions/how-tos/administer/enforce-workflow-lockfiles). + +You can keep **Require actions to be pinned to a full-length commit SHA** enabled when adopting lockfiles. For dependencies covered by a lockfile, {% data variables.product.github %} evaluates this requirement using the locked commit SHA. Keeping the policy enabled during a staged rollout preserves SHA-pinning enforcement for workflows that have not yet adopted lockfiles. + +{% endif %} + ## Evaluating policies You can view policy insights to see workflow runs that have been blocked (for active policies) or would have been blocked (for "evaluate" policies). This is a good way to check that policies are working as intended and not causing unnecessary friction. diff --git a/content/actions/how-tos/administer/enforce-workflow-lockfiles.md b/content/actions/how-tos/administer/enforce-workflow-lockfiles.md new file mode 100644 index 000000000000..e6beb6381186 --- /dev/null +++ b/content/actions/how-tos/administer/enforce-workflow-lockfiles.md @@ -0,0 +1,84 @@ +--- +title: Enforcing lockfiles for action dependencies +shortTitle: Enforce workflow lockfiles +intro: 'Require workflow dependency lockfiles across your repositories, and automatically keep the files up to date.' +versions: + feature: actions-workflow-lockfiles +permissions: 'Repository administrators, organization owners, and enterprise owners' +product: '{% data variables.product.prodname_ghe_cloud %}' +contentType: how-tos +--- + +> [!NOTE] {% data reusables.actions.workflow-lockfiles-preview %} + +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). + +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. + +## Prerequisites + +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). + +## 1. Pilot the "require lockfile" policy + +>[!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. + +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). + +Run a pilot before enforcing this policy in all repositories. You should: + +* Scope the policy to specific repositories that have onboarded to lockfiles. +* 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. +* Start with the policy in **Evaluate** mode and analyze the results under **Policy insights** + +## 2. Keep lockfiles current + +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. + +The following sections give examples for how to prevent stale lockfiles at different points of the development lifecycle. + +* Keep the file up to date by enabling {% data variables.product.prodname_dependabot %} and creating a workflow to run the lock command. +* Add a skill and pre-commit hook to shorten the feedback loop for developers. + +For ready-to-copy implementations of the workflow and the skill, see the [gh-actions-lock](https://github.com/github/gh-actions-lock) repository. + +### {% data variables.product.prodname_dependabot %} version updates + +When {% data variables.product.prodname_dependabot %} bumps an action version, it regenerates the matching lockfile entry in the same pull request. + +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). + +{% 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. + +### A dedicated {% data variables.product.prodname_actions %} workflow + +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: + +* 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. +* 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. + +### A {% data variables.product.prodname_copilot_short %} skill + +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. + +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). + +### A pre-commit hook + +This catches a stale lockfile before a commit exists, which is the earliest feedback a developer can get. + +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 %}. + +## 3. Set up a review process for lockfile changes + +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. + +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). +1. Configure a branch protection rule or repository ruleset to require approval from a code owner. +1. Tell reviewers what to look for. For guidance, see [AUTOTITLE](/actions/how-tos/secure-your-work/lock-workflow-dependencies#reviewing-lockfile-changes). + +## 4. Enforce the policy + +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. + +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. diff --git a/content/actions/how-tos/administer/index.md b/content/actions/how-tos/administer/index.md index ee66a730fae2..109331b8f986 100644 --- a/content/actions/how-tos/administer/index.md +++ b/content/actions/how-tos/administer/index.md @@ -8,6 +8,7 @@ versions: ghec: '*' children: - /control-workflow-execution + - /enforce-workflow-lockfiles - /view-metrics - /reuse-namespaces-on-ghecom redirect_from: diff --git a/content/actions/how-tos/secure-your-work/index.md b/content/actions/how-tos/secure-your-work/index.md index 7dcb13e2e1da..5aeb158a7cb3 100644 --- a/content/actions/how-tos/secure-your-work/index.md +++ b/content/actions/how-tos/secure-your-work/index.md @@ -13,6 +13,7 @@ versions: ghes: '*' ghec: '*' children: + - /lock-workflow-dependencies - /use-artifact-attestations - /security-harden-deployments contentType: how-tos diff --git a/content/actions/how-tos/secure-your-work/lock-workflow-dependencies.md b/content/actions/how-tos/secure-your-work/lock-workflow-dependencies.md new file mode 100644 index 000000000000..c99cf8998f29 --- /dev/null +++ b/content/actions/how-tos/secure-your-work/lock-workflow-dependencies.md @@ -0,0 +1,86 @@ +--- +title: Locking action dependencies in a repository's workflows +shortTitle: Lock workflow dependencies +intro: 'Generate a lockfile that pins every action your workflows use to a verified commit, and keep it current as your dependencies change.' +versions: + feature: actions-workflow-lockfiles +permissions: 'People with write access to a repository' +product: '{% data variables.product.prodname_ghe_cloud %}' +contentType: how-tos +--- + +> [!NOTE] {% data reusables.actions.workflow-lockfiles-preview %} + +Locking your workflows' dependencies ensures that the actions you reference contain the same code that was originally reviewed. For more information, see [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). + +## 1. Check your action references + +Creating a lockfile pins your dependencies to commits based on the current branch or tag reference. Make sure these are the versions you want to lock in place. + +Check that each `uses` reference in your workflows points to a supported, current version of the action. For best practices, see [AUTOTITLE](/actions/reference/security/secure-use#using-third-party-actions). + +If any of your workflows call a reusable workflow in another repository, check those references too. Dependencies of reusable workflows are covered by the lockfile of the repository where the reusable workflow is defined. If your organization maintains shared workflows, we recommend onboarding those repositories first. See [AUTOTITLE](/actions/concepts/workflows-and-actions/reusing-workflow-configurations). + +We recommend letting {% data variables.product.prodname_dependabot %} manage your {% data variables.product.prodname_actions %} dependencies. If it's not already enabled, enable it before you create the lockfile. See [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/auto-update-actions). + +## 2. Install the `actions-lock` extension + +1. Install the [{% data variables.product.prodname_cli %}](https://cli.github.com/). + +1. Install the extension. + + ```bash copy + gh extension install github/gh-actions-lock + ``` + +> [!TIP] To update the extension later, run `gh extension upgrade gh-actions-lock`. + +## 3. Generate the lockfile + +From the root of your repository, run the extension with no arguments. It will scan every workflow under `.github/workflows/`, pin each resolvable action to a commit SHA, and write the lockfile. + +```bash copy +gh actions-lock +``` + +To onboard a single workflow instead of the whole directory, pass its path. + +```bash copy +gh actions-lock .github/workflows/ci.yml +``` + +If the extension reports that it has skipped a workflow because local path actions aren't supported, this means a `uses: ./…` reference in that workflow didn't resolve to a real action file. Local paths resolve from the repository root, **not** from the directory of the file that contains them, so a path that looks right next to its own file may not resolve. Correct the path and run the command again. + +For the full set of options, run `gh actions-lock --help`. + +## 4. Review the changes and commit + +The extension changes more than the lockfile, so review the full diff before you commit. It also rewrites your workflow `uses` references to the specific version it resolved, so a reference such as `octo-org/deploy-action@v3` can become `octo-org/deploy-action@v3.1.0`. This makes the reference more specific without changing the commit it resolves to. + +If your repository, organization, or enterprise only allows specified actions, check the allowlist before you commit. After a workflow is onboarded, the allowlist is checked against locked commit SHAs, because a tag can be moved to different code but a locked SHA can't. Entries pinned to a tag, such as `{% data reusables.actions.action-checkout %}`, no longer match. Use a wildcard or the full commit SHA instead. See [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-select-actions-and-reusable-workflows-to-run). + +References to actions in your own repository are rewritten too, from `uses: ./…` to the equivalent `uses: $/…`, in both your workflows and your in-repository `action.yml` files. A `$/…` reference always resolves to the running commit, so it's inherently pinned and needs no lockfile entry. + +## 5. Keep the lockfile current + +Keep the lockfile up to date with your repository's workflow files and security updates. + +1. **Re-run the extension when you change dependencies.** Run `gh actions-lock` again whenever you add a workflow that has `uses` dependencies, or add or remove `uses` dependencies in an existing workflow. +1. **Let {% data variables.product.prodname_dependabot %} handle version bumps.** When {% data variables.product.prodname_dependabot %} opens a version update for an action in a workflow you've onboarded, it will also regenerate the matching lockfile entry in the same pull request, so your workflow file and lockfile can't drift apart. + + {% data variables.product.prodname_dependabot %} will **not** onboard a workflow for you. If it bumps a dependency in a workflow with no lockfile entry, it just reports that onboarding is required. + +1. **Re-resolve references that have moved.** References to branches or partial versions, such as `main` or `v3`, are trusted from the lockfile and aren't re-resolved on a normal run. If the extension reports an error because a tag now points to a different upstream commit, check the upstream repository's history first. If the move was legitimate, re-resolve the reference with `gh actions-lock --relock`. If the commit you originally locked is no longer reachable at all, for example because the upstream repository force-pushed or deleted it, `--relock` will still report an error. To accept the new commit, run `gh actions-lock --relock --accept-moved`. + +### Reviewing lockfile changes + +Review changes to the lockfile like any other dependency change: + +* **A changed `commit`** is the code your workflows will run. Treat it the way you'd treat any other dependency version bump. +* **A changed `owner_id` or `repo_id`** should be rare. It means the repository behind that name is **not** the one you originally locked, so investigate before you merge. + +If a lockfile looks wrong, fix your workflow files and regenerate it. Never edit the lockfile manually. + +## Next steps + +Once you have generated a lockfile for a repository, ensure it's enforced and up to date without developers needing to remember to run commands. See [AUTOTITLE](/actions/how-tos/administer/enforce-workflow-lockfiles). diff --git a/content/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions.md b/content/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions.md index 2be224a4b6b2..c21a9ace2556 100644 --- a/content/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions.md +++ b/content/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions.md @@ -177,6 +177,12 @@ steps: - uses: actions/javascript-action@a824008085750b8e136effc585c3cd6082bd575f ``` +{% ifversion actions-workflow-lockfiles %} + +> [!TIP] A workflow dependency lockfile pins your actions to verified commits without putting SHAs in your workflow files, so your `uses` references stay readable. It also covers transitive dependencies, which SHA pinning does not. See [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). + +{% endif %} + ### Using branches Specifying a target branch for the action means it will always run the version currently on that branch. This approach can create problems if an update to the branch includes breaking changes. This example targets a branch named `@main`: diff --git a/content/actions/reference/security/secure-use.md b/content/actions/reference/security/secure-use.md index bb9b1be1e9d2..d0826bcdf725 100644 --- a/content/actions/reference/security/secure-use.md +++ b/content/actions/reference/security/secure-use.md @@ -130,33 +130,27 @@ For detailed guidance on deciding whether to use `pull_request_target`, hardenin The individual jobs in a workflow can interact with (and compromise) other jobs. For example, a job querying the environment variables used by a later job, writing files to a shared directory that a later job processes, or even more directly by interacting with the Docker socket and inspecting other running containers and executing commands in them. -This means that a compromise of a single action within a workflow can be very significant, as that compromised action would have access to all secrets configured on your repository, and may be able to use the `GITHUB_TOKEN` to write to the repository. Consequently, there is significant risk in sourcing actions from third-party repositories on {% data variables.product.prodname_dotcom %}. For information on some of the steps an attacker could take, see [AUTOTITLE](/actions/reference/security/secure-use). +This means that a compromise of a single action within a workflow can be very significant, as that compromised action would have access to all secrets configured on your repository, and may be able to use the `GITHUB_TOKEN` to write to the repository. Consequently, there is significant risk in sourcing actions from third-party repositories on {% data variables.product.prodname_dotcom %}. -You can help mitigate this risk by following these good practices: +{% ifversion actions-workflow-lockfiles %} -* **Pin actions to a full-length commit SHA** +The best measure is to **lock your workflow dependencies** with a lockfile. This records the exact commit for every action your workflows depend on, including transitive dependencies, and verifies the identity of each source repository at run time. This is the strongest protection available, and supersedes SHA pinning for repositories that adopt it. For more information, see [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). - Pinning an action to a full-length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. {% data reusables.actions.actions-pin-commit-sha %} +For repositories that **cannot** adopt a lockfile, you can: - For an example of using a full-length commit SHA in a workflow, see [AUTOTITLE](/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions#using-shas). - - {%- ifversion actions-blocklist-sha-pinning %} - - {% data variables.product.github %} offers policies at the {% ifversion ghec or ghes %}repository, organization, and enterprise{% else %}repository and organization{% endif %} level to require actions to be pinned to a full-length commit SHA: - * To configure the policy at the repository level, see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#managing-github-actions-permissions-for-your-repository). - * To configure the policy at the organization level, see [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization#managing-github-actions-permissions-for-your-organization). - {%- ifversion ghec or ghes %} - * To configure the policy at the enterprise level, see [AUTOTITLE](/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#policies). - {%- endif %} - {%- endif %} +{% endif %} -* **Audit the source code of the action** +* **Pin actions to a full-length commit SHA** - Ensure that the action is handling the content of your repository and secrets as expected. For example, check that secrets are not sent to unintended hosts, or are not inadvertently logged. + Pin references to actions to a commit SHA in your workflow files. This helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. {% data reusables.actions.actions-pin-commit-sha %} + + For an example of using a full-length commit SHA in a workflow, see [AUTOTITLE](/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions#using-shas). * **Pin actions to a tag only if you trust the creator** - Although pinning to a commit SHA is the most secure option, specifying a tag is more convenient and is widely used. If you’d like to specify a tag, then be sure that you trust the action's creators. The ‘Verified creator’ badge on {% data variables.product.prodname_marketplace %} is a useful signal, as it indicates that the action was written by a team whose identity has been verified by {% data variables.product.prodname_dotcom %}. Note that there is risk to this approach even if you trust the author, because a tag can be moved or deleted if a bad actor gains access to the repository storing the action. + If you’d like to specify a tag, then be sure that you trust the action's creators. The ‘Verified creator’ badge on {% data variables.product.prodname_marketplace %} is a useful signal, as it indicates that the action was written by a team whose identity has been verified by {% data variables.product.prodname_dotcom %}. Note that there is risk to this approach even if you trust the author, because a tag can be moved or deleted if a bad actor gains access to the repository storing the action. + +Regardless of your measures, always **audit the source code of the action**. Ensure that the action is handling the content of your repository and secrets as expected. For example, check that secrets are not sent to unintended hosts, or are not inadvertently logged. ### Reusing third-party workflows diff --git a/content/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise.md b/content/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise.md index 1b149c9cc7ac..12853d3411b1 100644 --- a/content/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise.md +++ b/content/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise.md @@ -94,6 +94,8 @@ When specifying actions{% ifversion actions-workflow-policy %} and reusable work * By default, only actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} specified in the list will be allowed. To allow all actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} while also blocking specific actions, use `*, !space-org/action@*`. {%- endif %} +{% data reusables.actions.lockfile-allowed-actions-sha %} + Policies never restrict access to local actions on the runner filesystem (where the `uses:` path start with `./`). ## Runners diff --git a/content/code-security/concepts/supply-chain-security/dependabot-version-updates.md b/content/code-security/concepts/supply-chain-security/dependabot-version-updates.md index 6f2f939f799a..c7e09c83ea10 100644 --- a/content/code-security/concepts/supply-chain-security/dependabot-version-updates.md +++ b/content/code-security/concepts/supply-chain-security/dependabot-version-updates.md @@ -63,6 +63,12 @@ For each action in the file, {% data variables.product.prodname_dependabot %} ch {% data variables.product.prodname_dependabot %} also checks workflow files for uses of reusable workflows, and updates the Git reference for these called reusable workflows. +{% ifversion actions-workflow-lockfiles %} + +If a workflow has been onboarded to a workflow dependency lockfile, {% data variables.product.prodname_dependabot %} also regenerates the matching lockfile entry in the same pull request, so the pinned commit in the lockfile always matches the updated reference in the workflow file. This needs no additional configuration. For more information, see [AUTOTITLE](/actions/how-tos/secure-your-work/lock-workflow-dependencies). + +{% endif %} + To enable this feature, see [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/auto-update-actions). ## About automatic deactivation of {% data variables.product.prodname_dependabot_updates %} diff --git a/content/code-security/tutorials/implement-supply-chain-best-practices/securing-builds.md b/content/code-security/tutorials/implement-supply-chain-best-practices/securing-builds.md index 79e7c3199a00..43929183faaf 100644 --- a/content/code-security/tutorials/implement-supply-chain-best-practices/securing-builds.md +++ b/content/code-security/tutorials/implement-supply-chain-best-practices/securing-builds.md @@ -71,6 +71,18 @@ There are many further steps you can take to additionally secure {% data variabl For more information, see [AUTOTITLE](/actions/reference/security/secure-use#writing-workflows) and [AUTOTITLE](/actions/reference/security/secure-use). +{% ifversion actions-workflow-lockfiles %} + +## Lock the dependencies your build systems run + +When a workflow references an action by a tag or branch, the code that runs is whatever that reference points to at the time of the build, which may not be the code you reviewed. + +A workflow dependency lockfile pins every action your workflows use, including transitive dependencies, to a verified commit. For more information, see [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). + +If you are responsible for multiple repositories, you can require lockfiles with an {% data variables.product.prodname_actions %} policy at the enterprise, organization, or repository level. See [AUTOTITLE](/actions/how-tos/administer/enforce-workflow-lockfiles). + +{% endif %} + ## Next steps * [AUTOTITLE](/code-security/tutorials/implement-supply-chain-best-practices/end-to-end-supply-chain-overview) diff --git a/content/communities/moderating-comments-and-conversations/archive-pull-requests.md b/content/communities/moderating-comments-and-conversations/archive-pull-requests.md index 18fd3405a5af..24c31a8e3dd4 100644 --- a/content/communities/moderating-comments-and-conversations/archive-pull-requests.md +++ b/content/communities/moderating-comments-and-conversations/archive-pull-requests.md @@ -1,6 +1,6 @@ --- title: Archive pull requests -intro: Repository administrators can archive a pull request to remove it from public view, providing a moderation option between leaving a pull request up and permanently deleting it. +intro: Archiving a pull request removes it from public view without permanently deleting it. versions: feature: archive-pull-requests category: @@ -8,20 +8,37 @@ category: redirect_from: - /communities/moderating-comments-and-conversations/archiving-pull-requests contentType: other -permissions: Repository administrators +permissions: '{% ifversion triage-archive-pull-requests %}People with triage access or higher to a repository{% else %}Repository administrators{% endif %}' --- ## About archiving pull requests -Archiving a pull request removes it from public view while preserving its history for repository administrators. This provides a safer moderation path when they need to take a pull request out of public view without permanently deleting it. +Archiving a pull request removes it from public view while preserving its history for {% ifversion triage-archive-pull-requests %}people with triage access or higher to the repository{% else %}repository administrators{% endif %}. This provides a safer moderation path when they need to take a pull request out of public view without permanently deleting it. + +{% ifversion triage-archive-pull-requests %} + +Anyone with the triage, write, maintain, or admin role in a repository can archive, unarchive, and view archived pull requests. + +{% endif %} When a pull request is archived: +{% ifversion triage-archive-pull-requests %} + +* The pull request is only visible to people with triage access or higher to the repository. Visitors without this access receive a 404 error. +* The pull request is automatically closed and its conversation becomes read-only. New comments, reactions, and automated comments are blocked, including comments from repository administrators. + +When you unarchive a pull request, it becomes visible again and people can comment and react again, but it remains closed. You can reopen it separately if needed. + +{% else %} + * The pull request is only visible to repository administrators. Visitors without administrator access to the repository receive a 404 error. * The pull request is automatically closed and locked. When you unarchive a pull request, it becomes visible again, but it remains closed and locked. You can reopen and unlock it separately if needed. +{% endif %} + ## Archiving a pull request {% data reusables.repositories.navigate-to-repo %} @@ -32,7 +49,7 @@ When you unarchive a pull request, it becomes visible again, but it remains clos ## Unarchiving a pull request -You can find the PR by using the `is:archived` qualifier. See, [AUTOTITLE](/search-github/searching-on-github/searching-issues-and-pull-requests#search-based-on-whether-a-pull-request-is-archived). +You can find archived pull requests by using the `is:archived` qualifier. See [AUTOTITLE](/search-github/searching-on-github/searching-issues-and-pull-requests#search-based-on-whether-a-pull-request-is-archived). 1. Open the pull request you want to unarchive. 1. In the right sidebar, click **{% octicon "archive" aria-hidden="true" aria-label="unarchive" %} Unarchive pull request**. diff --git a/content/copilot/concepts/models/utility-models.md b/content/copilot/concepts/models/utility-models.md index 0251c9ce0173..cee78f60592b 100644 --- a/content/copilot/concepts/models/utility-models.md +++ b/content/copilot/concepts/models/utility-models.md @@ -18,7 +18,3 @@ Utility models: * **Are** subject to per-user rate limits. These characteristics ensure that {% data variables.product.prodname_copilot_short %} features work smoothly regardless of your model policies and billing controls. - -## List of utility models - -Utility models are typically selected for being fast and lightweight. {% data reusables.copilot.utility-models %} diff --git a/content/copilot/reference/ai-models/supported-models.md b/content/copilot/reference/ai-models/supported-models.md index 6754082045c1..f1e653e48d9a 100644 --- a/content/copilot/reference/ai-models/supported-models.md +++ b/content/copilot/reference/ai-models/supported-models.md @@ -199,8 +199,6 @@ Access to evaluation models in {% data variables.copilot.copilot_auto_model_sele Utility models power background features across surfaces, and cannot be disabled or selected in the model picker. See [AUTOTITLE](/copilot/concepts/models/utility-models). -{% data reusables.copilot.utility-models %} - ## Models eligible for default enablement {% data reusables.copilot.model-autoenablement %} diff --git a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md index 1600b36770dc..2ca77854694b 100644 --- a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md +++ b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md @@ -281,6 +281,8 @@ If the workflow file is in an internal or private repository and you want to use When you add this rule to a ruleset, in your organization settings, you specify the source repository and the workflow you want to enforce. +Ruleset workflows can't use most {% data variables.product.prodname_codeql %} actions, such as `github/codeql-action/init` and `github/codeql-action/analyze`; the only exception is `github/codeql-action/upload-sarif`. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/troubleshooting-rules#using-codeql-in-a-ruleset-workflow). + ### Using "Evaluate" mode for ruleset workflows If a ruleset workflow runs in "Evaluate" mode and passes, you can set the ruleset workflow to "Active" mode and merge your pull request without triggering a new workflow run. diff --git a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/troubleshooting-rules.md b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/troubleshooting-rules.md index 2bfb95fd9b31..5654b2e10e96 100644 --- a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/troubleshooting-rules.md +++ b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/troubleshooting-rules.md @@ -64,6 +64,16 @@ For more information, see [AUTOTITLE](/actions/reference/workflows-and-actions/e Ruleset workflows do not run on events triggered by the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/tutorials/authenticate-with-github_token#using-the-github_token-in-a-workflow). +### Using {% data variables.product.prodname_codeql %} in a ruleset workflow + +Ruleset workflows can't use the {% data variables.product.prodname_codeql %} actions, except `github/codeql-action/upload-sarif`. This also applies to {% data variables.product.prodname_codeql %} actions in a reusable workflow that the ruleset workflow calls. If a ruleset workflow uses them, the workflow run fails to start with an error such as: + +```text +The following actions are not allowed to be used inside a required workflow: {% data reusables.actions.action-codeql-action-analyze %}, {% data reusables.actions.action-codeql-action-init %} +``` + +To run {% data variables.product.prodname_code_scanning %} with {% data variables.product.prodname_codeql %} across many repositories, use default setup, or add an advanced setup workflow to each repository. To block pull requests until {% data variables.product.prodname_code_scanning %} results are available, use the "Require {% data variables.product.prodname_code_scanning %} results" rule instead of a ruleset workflow. See [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-organization-security/configure-specific-tools/code-scanning-at-scale), [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-organization-security/configure-specific-tools/configuring-advanced-setup-for-code-scanning-with-codeql-at-scale), and [AUTOTITLE](/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration/set-merge-protection). + ### Blocking repository creation A required workflow can block people from creating a repository, since a workflow can't run against a repository that's being initialized. To get around this, the ruleset either needs to have "Evaluate" as the enforcement status, or someone with bypass permissions needs to create the repository and bypass the branch protection. diff --git a/content/search-github/searching-on-github/searching-issues-and-pull-requests.md b/content/search-github/searching-on-github/searching-issues-and-pull-requests.md index 483ffa74a0a5..1be1dad02f68 100644 --- a/content/search-github/searching-on-github/searching-issues-and-pull-requests.md +++ b/content/search-github/searching-on-github/searching-issues-and-pull-requests.md @@ -72,11 +72,11 @@ You can filter issues and pull requests based on whether they're open or closed ## Search based on whether a pull request is archived -Repository administrators can archive a pull request to remove it from public view. You can search for archived pull requests using the `is:archived` qualifier. For more information, see [AUTOTITLE](/communities/moderating-comments-and-conversations/archive-pull-requests). +{% ifversion triage-archive-pull-requests %}People with triage access or higher to a repository can archive, unarchive, and view archived pull requests. Archiving removes a pull request from public view.{% else %}Repository administrators can archive a pull request to remove it from public view.{% endif %} You can search for archived pull requests using the `is:archived` qualifier. For more information, see [AUTOTITLE](/communities/moderating-comments-and-conversations/archive-pull-requests). | Qualifier | Example | ------------- | ------------- -| `is:archived` | [**is:archived is:pr spam**](https://github.com/search?q=is%3Aarchived+is%3Apr+spam&ref_product=github&ref_type=engagement&ref_style=text) matches archived pull requests that contain the word "spam" in repositories where you are a repository administrator. +| `is:archived` | [**is:archived is:pr spam**](https://github.com/search?q=is%3Aarchived+is%3Apr+spam&ref_product=github&ref_type=engagement&ref_style=text) matches archived pull requests that contain the word "spam" in repositories where you {% ifversion triage-archive-pull-requests %}have triage access or higher{% else %}are a repository administrator{% endif %}. {% endif %} diff --git a/data/features/actions-workflow-lockfiles.yml b/data/features/actions-workflow-lockfiles.yml new file mode 100644 index 000000000000..ab1dca886d6b --- /dev/null +++ b/data/features/actions-workflow-lockfiles.yml @@ -0,0 +1,6 @@ +# Issue 21194 +# Versioning for GitHub Actions workflow dependency lockfiles +# Not currently scheduled for GHES +versions: + fpt: '*' + ghec: '*' diff --git a/data/features/triage-archive-pull-requests.yml b/data/features/triage-archive-pull-requests.yml new file mode 100644 index 000000000000..bcbaf71bc5cc --- /dev/null +++ b/data/features/triage-archive-pull-requests.yml @@ -0,0 +1,5 @@ +# Reference: https://github.blog/changelog/2026-10-08-triage-role-users-or-higher-can-now-archive-pull-requests/ +# Expanded permissions and read-only conversations for archived pull requests +versions: + fpt: '*' + ghec: '*' diff --git a/data/reusables/actions/allow-specific-actions-intro.md b/data/reusables/actions/allow-specific-actions-intro.md index 744cf7edb5f3..235f9c923e6f 100644 --- a/data/reusables/actions/allow-specific-actions-intro.md +++ b/data/reusables/actions/allow-specific-actions-intro.md @@ -26,4 +26,6 @@ When you choose {% data reusables.actions.policy-label-for-select-actions-workfl Use the `!` prefix to block patterns. For example, to allow all actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} from the `space-org` organization, but block a specific action like `space-org/action`, you can specify `space-org/*, !space-org/action@*`. By default, only actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} specified in the list will be allowed. To allow all actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} while also blocking specific actions, you can specify `*, !space-org/action@*`. {% endif %} +{% data reusables.actions.lockfile-allowed-actions-sha %} + This procedure demonstrates how to add specific actions{% ifversion actions-workflow-policy %} and reusable workflows{% endif %} to the list. diff --git a/data/reusables/actions/lockfile-allowed-actions-sha.md b/data/reusables/actions/lockfile-allowed-actions-sha.md new file mode 100644 index 000000000000..ef4c622054eb --- /dev/null +++ b/data/reusables/actions/lockfile-allowed-actions-sha.md @@ -0,0 +1,11 @@ +{% ifversion actions-workflow-lockfiles %} + +> [!NOTE] +> For workflows covered by a dependency lockfile, this policy checks each locked dependency by its commit SHA instead of the tag or branch in the workflow file. Tags and branches are mutable, so they can't identify the code that runs. The locked SHA can. This has two effects: +> +> * Allowlist entries pinned to a tag or branch, such as `{% data reusables.actions.action-checkout %}`, don't match, even when the workflow uses `{% data reusables.actions.action-checkout %}`. A locked SHA can't be reliably matched back to a tag, because the tag may have moved since you locked it, and a tag's history includes every earlier release. To allow a locked dependency, use a wildcard such as `actions/checkout@*` or `actions/*`, or the full commit SHA. +> * Locked dependencies satisfy **Require actions to be pinned to a full-length commit SHA** without changes to the workflow file. Dependencies that aren't in the lockfile still need a full-length SHA. +> +> For more information, see [AUTOTITLE](/actions/concepts/security/workflow-dependency-lockfiles). + +{% endif %} diff --git a/data/reusables/actions/workflow-lockfiles-preview.md b/data/reusables/actions/workflow-lockfiles-preview.md new file mode 100644 index 000000000000..94934b6d1900 --- /dev/null +++ b/data/reusables/actions/workflow-lockfiles-preview.md @@ -0,0 +1 @@ +Workflow dependency lockfiles are in {% data variables.release-phases.public_preview %} and subject to change. diff --git a/data/reusables/copilot/utility-models.md b/data/reusables/copilot/utility-models.md deleted file mode 100644 index ed799f88dfc4..000000000000 --- a/data/reusables/copilot/utility-models.md +++ /dev/null @@ -1,6 +0,0 @@ -The following models are currently used as utility models: - -* {% data variables.copilot.copilot_gpt_4o_mini %} -* {% data variables.copilot.copilot_gpt_4o %} -* {% data variables.copilot.copilot_gpt_41 %} -* {% data variables.copilot.copilot_gpt_54_nano %}