From 6b2352751edcd4acb3b13a135682f93becbb8419 Mon Sep 17 00:00:00 2001 From: Sarah Edwards Date: Mon, 1 May 2023 14:13:05 -0700 Subject: [PATCH] Authenticating to Actions workflow with GitHub App (#36649) Co-authored-by: Siara <108543037+SiaraMist@users.noreply.github.com> Co-authored-by: James Martin --- .../automatic-token-authentication.md | 5 +- .../security-guides/encrypted-secrets.md | 6 +- .../security-hardening-for-github-actions.md | 2 +- .../using-workflows/triggering-a-workflow.md | 6 +- .../workflow-syntax-for-github-actions.md | 2 + .../apps/creating-github-apps/guides/index.md | 1 + ...github-app-in-a-github-actions-workflow.md | 58 +++++++++++++++++++ .../about-creating-github-apps.md | 6 +- .../automating-projects-using-actions.md | 6 +- 9 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 content/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow.md diff --git a/content/actions/security-guides/automatic-token-authentication.md b/content/actions/security-guides/automatic-token-authentication.md index 21ef878ce6..58ed864616 100644 --- a/content/actions/security-guides/automatic-token-authentication.md +++ b/content/actions/security-guides/automatic-token-authentication.md @@ -125,10 +125,7 @@ The permissions for the `GITHUB_TOKEN` are initially set to the default setting ### 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.pat_generic %} and set it as a secret in your repository: - -1. Use or create a token with the appropriate permissions for that repository. For more information, see "[AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)." -1. Add the token as a secret in your workflow's repository, and refer to it using the {%raw%}`${{ secrets.SECRET_NAME }}`{% endraw %} syntax. For more information, see "[AUTOTITLE](/actions/security-guides/encrypted-secrets)." +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 workfow 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/encrypted-secrets)." ### Further reading diff --git a/content/actions/security-guides/encrypted-secrets.md b/content/actions/security-guides/encrypted-secrets.md index 8c86ab79e3..9c5c5dad39 100644 --- a/content/actions/security-guides/encrypted-secrets.md +++ b/content/actions/security-guides/encrypted-secrets.md @@ -62,7 +62,11 @@ You can also manage secrets using the REST API. For more information, see "[AUTO ### Limiting credential permissions -When generating credentials, we recommend that you grant the minimum permissions possible. For example, instead of using personal credentials, use [deploy keys](/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys) or a service account. Consider granting read-only permissions if that's all that is needed, and limit access as much as possible. When generating a {% data variables.product.pat_v1 %}, select the fewest scopes necessary.{% ifversion pat-v2 %} When generating a {% data variables.product.pat_v2 %}, select the minimum repository access required.{% endif %} +When generating credentials, we recommend that you grant the minimum permissions possible. For example, instead of using personal credentials, use [deploy keys](/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys) or a service account. Consider granting read-only permissions if that's all that is needed, and limit access as much as possible. + +When generating a {% data variables.product.pat_v1 %}, select the fewest scopes necessary.{% ifversion pat-v2 %} When generating a {% data variables.product.pat_v2 %}, select the minimum permissions and repository access required.{% endif %} + +Instead of using a {% data variables.product.pat_generic %}, consider using a {% data variables.product.prodname_github_app %}, which uses fine-grained permissions and short lived tokens{% ifversion pat-v2 %}, similar to a {% data variables.product.pat_v2 %}{% endif %}. Unlike a {% data variables.product.pat_generic %}, a {% data variables.product.prodname_github_app %} is not tied to a user, so the workflow will continue to work even if the user who installed the app leaves your organization. For more information, see "[AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow)." {% note %} diff --git a/content/actions/security-guides/security-hardening-for-github-actions.md b/content/actions/security-guides/security-hardening-for-github-actions.md index f7623e31a4..4c58877154 100644 --- a/content/actions/security-guides/security-hardening-for-github-actions.md +++ b/content/actions/security-guides/security-hardening-for-github-actions.md @@ -289,7 +289,7 @@ This list describes the recommended approaches for accessing repository data wit - 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. 3. **{% 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. + - {% 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)." 4. **{% 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 {% ifversion pat-v2%}{% data variables.product.pat_v2 %}s{% else %}{% data variables.product.pat_generic %}s{% endif %} 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. diff --git a/content/actions/using-workflows/triggering-a-workflow.md b/content/actions/using-workflows/triggering-a-workflow.md index eba1a82d6d..a8685d6722 100644 --- a/content/actions/using-workflows/triggering-a-workflow.md +++ b/content/actions/using-workflows/triggering-a-workflow.md @@ -35,7 +35,11 @@ The following steps occur to trigger a workflow run: {% data reusables.actions.actions-do-not-trigger-workflows %} For more information, see "[AUTOTITLE](/actions/security-guides/automatic-token-authentication)." -If you do want to trigger a workflow from within a workflow run, you can use a {% data variables.product.pat_generic %} instead of `GITHUB_TOKEN` to trigger events that require a token. You'll need to create a {% data variables.product.pat_generic %} and store it as a secret. To minimize your {% data variables.product.prodname_actions %} usage costs, ensure that you don't create recursive or unintended workflow runs. For more information about creating a {% data variables.product.pat_generic %}, see "[AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)." For more information about storing a {% data variables.product.pat_generic %} as a secret, see "[AUTOTITLE](/actions/security-guides/encrypted-secrets)." +If you do want to trigger a workflow from within a workflow run, you can use a {% data variables.product.prodname_github_app %} installation access token or a {% data variables.product.pat_generic %} instead of `GITHUB_TOKEN` to trigger events that require a token. + +If you use a {% data variables.product.prodname_github_app %}, you'll need to create a {% data variables.product.prodname_github_app %} and store the app ID and private key as secrets. For more information, see "[AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow)." If you use a {% data variables.product.pat_generic %}, you'll need to create a {% data variables.product.pat_generic %} and store it as a secret. For more information about creating a {% data variables.product.pat_generic %}, see "[AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)." For more information about storing secrets, see "[AUTOTITLE](/actions/security-guides/encrypted-secrets)." + +To minimize your {% data variables.product.prodname_actions %} usage costs, ensure that you don't create recursive or unintended workflow runs. For example, the following workflow uses a {% data variables.product.pat_generic %} (stored as a secret called `MY_TOKEN`) to add a label to an issue via {% data variables.product.prodname_cli %}. Any workflows that run when a label is added will run once this step is performed. diff --git a/content/actions/using-workflows/workflow-syntax-for-github-actions.md b/content/actions/using-workflows/workflow-syntax-for-github-actions.md index 4cfe617aaf..b6404deb2d 100644 --- a/content/actions/using-workflows/workflow-syntax-for-github-actions.md +++ b/content/actions/using-workflows/workflow-syntax-for-github-actions.md @@ -550,6 +550,8 @@ jobs: uses: ./.github/actions/my-private-repo/my-action ``` +Alternatively, use a {% data variables.product.prodname_github_app %} instead of a {% data variables.product.pat_generic %} in order to ensure your workflow continues to run even if the {% data variables.product.pat_generic %} owner leaves. For more information, see "[AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow)." + ### `jobs..steps[*].run` Runs command-line programs using the operating system's shell. If you do not provide a `name`, the step name will default to the text specified in the `run` command. diff --git a/content/apps/creating-github-apps/guides/index.md b/content/apps/creating-github-apps/guides/index.md index 9430dce64a..1797472fbc 100644 --- a/content/apps/creating-github-apps/guides/index.md +++ b/content/apps/creating-github-apps/guides/index.md @@ -16,6 +16,7 @@ children: - /using-the-github-api-in-your-app - /building-a-login-with-github-button-with-a-github-app - /building-a-cli-with-a-github-app + - /making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow - /creating-ci-tests-with-the-checks-api - /migrating-oauth-apps-to-github-apps --- diff --git a/content/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow.md b/content/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow.md new file mode 100644 index 0000000000..87a082fc76 --- /dev/null +++ b/content/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow.md @@ -0,0 +1,58 @@ +--- +title: Making authenticated API requests with a GitHub App in a GitHub Actions workflow +shortTitle: Use with Actions +intro: "You can use an installation access token from a {% data variables.product.prodname_github_app %} to make authenticated API requests in a {% data variables.product.prodname_actions %} workflow. You can also pass the token to a custom action to enable the action to make authenticated API requests." +versions: + fpt: '*' + ghes: '*' + ghae: '*' + ghec: '*' +topics: + - GitHub Apps + - Actions +--- + +## About {% data variables.product.prodname_actions %} authentication + +If you need to make authenticated API requests in a {% data variables.product.prodname_actions %} workflow or need to execute a custom action that requires a token, you should use the built-in `GITHUB_TOKEN` if possible. However, the `GITHUB_TOKEN` can only access resources within the workflow's repository. If you need to access additional resources, such as resources in an organization or in another repository, you can use a {% data variables.product.prodname_github_app %}. For more information about why you might use a {% data variables.product.prodname_github_app %} over a {% data variables.product.pat_generic %}, see "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps#choosing-between-a-github-app-or-a-personal-access-token)." + +## Authenticating with a {% data variables.product.prodname_github_app %} + +In order to use a {% data variables.product.prodname_github_app %} to make authenticated API requests, you must create a {% data variables.product.prodname_github_app %}, store your app's credentials, and install your app. Once this is done, you can use your app to create an installation access token, which can be used to make authenticated API requests in a {% data variables.product.prodname_actions %} workflow. You can also pass the installation access token to a custom action that requires a token. + +1. Create a {% data variables.product.prodname_github_app %}. Give your {% data variables.product.prodname_github_app %} the necessary permissions to access the desired resources. For more information, see "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app)" and "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/choosing-permissions-for-a-github-app)." +1. Store the app ID of your {% data variables.product.prodname_github_app %} as a {% data variables.product.prodname_actions %} secret. You can find the app ID on the settings page for your app. The app ID is different from the client ID. For more information about storing secrets, see "[AUTOTITLE](/actions/security-guides/encrypted-secrets)." +1. Generate a private key for your app. Store the contents of the resulting file as a secret. (Store the entire contents of the file, including `-----BEGIN RSA PRIVATE KEY-----` and `-----END RSA PRIVATE KEY-----`.) For more information, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)." +1. Install the {% data variables.product.prodname_github_app %} on your user account or organization and grant it access to any repositories that you want your workflow to access. For more information, see "[AUTOTITLE](/apps/maintaining-github-apps/installing-github-apps#installing-your-private-github-app-on-your-repository)." +1. In your {% data variables.product.prodname_actions %} workflow, create an installation access token, which you can use to make API requests. + + To do this, you can use a pre-made action as demonstrated in the following example. If you prefer to not use a third party action, you can fork and modify the `tibdex/github-app-token` action, or you can write a script to make your workflow create an installation token manually. For more information, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation)." + + The following example workflow uses the `tibdex/github-app-token` action to generate an installation access token. Then, the workflow uses the token to make an API request via the {% data variables.product.prodname_cli %}. + + In the following workflow, replace `APP_ID` with the name of the secret where you stored your app ID. Replace `APP_PRIVATE_KEY` with the name of the secret where you stored your app private key. + +```yaml{:copy} +{% data reusables.actions.actions-not-certified-by-github-comment %} + +{% data reusables.actions.actions-use-sha-pinning-comment %} + +on: + workflow_dispatch: +jobs: + demo_app_authentication: + runs-on: ubuntu-latest + steps: + - name: Generate a token + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: {% raw %}${{ secrets.APP_ID }}{% endraw %} + private_key: {% raw %}${{ secrets.APP_PRIVATE_KEY }}{% endraw %} + + - name: Use the token + env: + GITHUB_TOKEN: {% raw %}${{ steps.generate_token.outputs.token }}{% endraw %} + run: | + gh api octocat +``` diff --git a/content/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps.md b/content/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps.md index 6b98547e44..446f0bc96d 100644 --- a/content/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps.md +++ b/content/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps.md @@ -97,7 +97,7 @@ For more information about the REST API endpoints that are available to {% data If you want to access {% data variables.product.prodname_dotcom %} resources on behalf of a user or in an organization, or you anticipate a long-lived integration, we recommend building a {% data variables.product.prodname_github_app %}. - You can use {% data variables.product.pat_generic_plural %} for API testing or short-lived scripts. It is important to note that since a {% data variables.product.pat_generic %} is associated to a user, your automation could break if the user no longer has access to the resources you need. A {% data variables.product.prodname_github_app %} installed in an organization is not dependent on a user. + You can use {% data variables.product.pat_generic_plural %} for API testing or short-lived scripts. Since a {% data variables.product.pat_generic %} is associated with a user, your automation could break if the user no longer has access to the resources you need. A {% data variables.product.prodname_github_app %} installed in an organization is not dependent on a user. Additionally, unlike a user, a {% data variables.product.prodname_github_app %} does not consume a {% data variables.product.company_short %} seat. {% data variables.product.company_short %} supports two types of {% data variables.product.pat_generic_plural %}, but recommends that you use {% data variables.product.pat_v2 %}s instead of {% data variables.product.pat_v1_plural %} whenever possible. For more information about {% data variables.product.pat_generic_plural %}, see "[AUTOTITLE](/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#types-of-personal-access-tokens)." @@ -111,8 +111,8 @@ For more information about the REST API endpoints that are available to {% data For more information about comparing {% data variables.product.prodname_actions %} to {% data variables.product.prodname_github_apps %}, see "[AUTOTITLE](/actions/creating-actions/about-custom-actions#comparing-github-actions-to-github-apps)." -{% ifversion projects-v2 %}You can use a {% data variables.product.prodname_github_app %} to authenticate in a {% data variables.product.prodname_actions %} -workflow if the built in `GITHUB_TOKEN` does not have sufficient permissions. For an example workflow that authenticates with a {% data variables.product.prodname_github_app %}, see "[AUTOTITLE](/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions#example-workflow-authenticating-with-a-github-app)."{% endif %} +You can use a {% data variables.product.prodname_github_app %} to authenticate in a {% data variables.product.prodname_actions %} +workflow if the built in `GITHUB_TOKEN` does not have sufficient permissions. For more information, see "[AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow)." ## Understanding what type of {% data variables.product.prodname_github_app %} to build diff --git a/content/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions.md b/content/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions.md index a774ed2c6c..db5135b9a6 100644 --- a/content/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions.md +++ b/content/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions.md @@ -15,7 +15,7 @@ allowTitleToDifferFromFilename: true ## {% data variables.product.prodname_actions %} workflows -This section demonstrates how to use the GraphQL API and {% data variables.product.prodname_actions %} to add a pull request to an organization project. In the example workflows, when the pull request is marked as "ready for review", a new task is added to the project with a "Status" field set to "Todo", and the current date is added to a custom "Date posted" field. +This article demonstrates how to use the GraphQL API and {% data variables.product.prodname_actions %} to add a pull request to an organization project. In the example workflows, when the pull request is marked as "ready for review", a new task is added to the project with a "Status" field set to "Todo", and the current date is added to a custom "Date posted" field. You can copy one of the workflows below and modify it as described in the table below to meet your needs. @@ -35,6 +35,8 @@ You may also want to use the **actions/add-to-project** workflow, which is maint ### Example workflow authenticating with a {% data variables.product.prodname_github_app %} +For more information about authenticating in a {% data variables.product.prodname_actions %} workflow with a {% data variables.product.prodname_github_app %}, see "[AUTOTITLE](/apps/creating-github-apps/guides/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow)." + 1. Create a {% data variables.product.prodname_github_app %} or choose an existing {% data variables.product.prodname_github_app %} owned by your organization. For more information, see "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app)." 2. Give your {% data variables.product.prodname_github_app %} read and write permissions to organization projects. For more information, see "[AUTOTITLE](/apps/maintaining-github-apps/editing-a-github-apps-permissions)." @@ -65,7 +67,7 @@ jobs: steps: - name: Generate token id: generate_token - uses: tibdex/github-app-token@c2055a00597a80f713b78b1650e8d3418f4d9a65 + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 with: app_id: {% raw %}${{ secrets.APP_ID }}{% endraw %} private_key: {% raw %}${{ secrets.APP_PEM }}{% endraw %}