Skip to content

Commit

Permalink
Authenticating as an app installation (github#34771)
Browse files Browse the repository at this point in the history
Co-authored-by: Jake Wilkins <jakewilkins@github.com>
Co-authored-by: James Martin <jamesmartin@users.noreply.github.com>
Co-authored-by: Jess Hosman <1183847+jhosman@users.noreply.github.com>
  • Loading branch information
4 people authored Mar 2, 2023
1 parent 621ca95 commit 637e68b
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
title: Authenticating as a GitHub App installation
shortTitle: Authenticate as an installation
intro: You can make your {% data variables.product.prodname_github_app %} authenticate as an installation in order to make API requests that affect resources owned by the account where the app is installed.
versions:
fpt: '*'
ghes: '*'
ghae: '*'
ghec: '*'
topics:
- GitHub Apps
---

## About authentication as a {% data variables.product.prodname_github_app %} installation

Once your {% data variables.product.prodname_github_app %} is installed on an account, you can make it authenticate as an app installation for API requests. This allows the app to access resources owned by that installation, as long as the app was granted the necessary repository access and permissions. API requests made by an app installation are attributed to the app. For more information about installing GitHub Apps, see "[Installing GitHub Apps](/developers/apps/managing-github-apps/installing-github-apps)."

For example, if you want your app to change the `Status` field of an issue on a project owned by an organization called "octo-org," then you would authenticate as the octo-org installation of your app. The timeline of the issue would state that your app updated the status.

To make an API request as an installation, you must first generate an installation access token. Then, you will send the installation access token in the `Authorization` header of your subsequent API requests. You can also use {% data variables.product.company_short %}'s Octokit SDKs, which can generate an installation access token for you.

API requests that are made by app installations are called "server-to-server requests." If a REST API endpoint works with server-to-server requests, the REST reference documentation for that endpoint will say "Works with {% data variables.product.prodname_github_apps %}." Additionally, your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)."

App installations can also use the GraphQL API. Similar to the REST API, the app must have certain permissions to access objects in the GraphQL API. For GraphQL requests, you should test you app to ensure that your app has the required permissions for the GraphQL queries and mutations that you want to make.

For more information about authenticating as an app on behalf of a user instead of as an app installation, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/identifying-and-authorizing-users-for-github-apps)".

## Using an installation access token to authenticate as an app installation

To authenticate as an installation with an installation access token, first use the REST API to generate an installation access token. Then, use that installation access token in the `Authorization` header of a REST API or GraphQL API request. The installation access token will expire after 1 hour.

### Generating an installation access token

{% data reusables.apps.generate-installation-access-token %}

### Authenticating with an installation access token

To authenticate with an installation access token, include it in the `Authorization` header of an API request. The access token will work with both the GraphQL API and the REST API.

Your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)." For GraphQL requests, you should test your app to ensure that it has the required permissions for the GraphQL queries and mutations that you want to make.

In the following example, replace `INSTALLATION_ACCESS_TOKEN` with an installation access token:

```shell
curl --request GET \
--url "{% data variables.product.api_url_pre %}meta" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer INSTALLATION_ACCESS_TOKEN"{% ifversion api-date-versioning %}\
--header "X-GitHub-Api-Version: {{ allVersions[currentVersion].latestApiVersion }}"{% endif %}
```

## Using the Octokit.js SDK to authenticate as an app installation

You can use {% data variables.product.company_short %}'s Octokit.js SDK to authenticate as an app installation. One advantage of using the SDK to authenticate is that you do not need to generate a JSON web token (JWT) yourself. Additionally, the SDK will take care of regenerating an installation access token for you so you don't need to worry about the one hour expiration.

{% note %}

You must install and import `octokit` in order to use the Octokit.js library. The following example uses import statements in accordance with ES6. For more information about different installation and import methods, see [the Octokit.js README's Usage section](https://github.com/octokit/octokit.js/#usage).

{% endnote %}

### Using Octokit.js to authenticate with an installation ID

1. Get the ID of your app. You can find your app's ID on the settings page for your app. For user-owned apps, the settings page is `https://github.com/settings/apps/APP-SLUG`. For organization-owned apps, the settings page is `https://github.com/organizations/ORGANIZATION/settings/apps/APP-SLUG`. Replace `APP-SLUG` with the slugified name of your app. Replace `ORGANIZATION` with the slugified name of your organization. For example, `https://github.com/organizations/octo-org/settings/apps/octo-app`.
1. Generate a private key. For more information, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)".
1. Get the ID of the installation that you want to authenticate as.

If you are responding to a webhook event, the webhook payload will include the installation ID.

You can also use the REST API to find the ID for an installation of your app. For example, you can get an installation ID with the `GET /users/{username}/installation`, `GET /repos/{owner}/{repo}/installation`, `GET /orgs/{org}/installation`, or `GET /app/installations` endpoints. For more information, see "[AUTOTITLE](/rest/apps/apps)".
1. Import `App` from `octokit`. Create a new instance of `App`. In the following example, replace `APP_ID` with a reference to your app's ID. Replace `PRIVATE_KEY` with a reference to your app's private key.

```javascript{:copy}
import { App } from "octokit";
const app = new App({
appId: APP_ID,
privateKey: PRIVATE_KEY,
});
```

1. Use the `getInstallationOctokit` method to create an authenticated `octokit` instance. In the following example, replace `INSTALLATION_ID` with the ID of the installation of your app that you want to authenticate on behalf of.

```javascript{:copy}
const octokit = await app.getInstallationOctokit(INSTALLATION_ID);
```

1. Use an `octokit` method to make a request to the API.

Your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)." For GraphQL requests, you should test you app to ensure that your app has the required permissions for the GraphQL queries and mutations that you want to make.

For example, to make a request to the GraphQL API:

```javascript{:copy}
await octokit.graphql(`
query {
viewer {
login
}
}
`)
```

For example, to make a request to the REST API:

```javascript{:copy}
await octokit.request("GET /meta")
```

### Using Octokit.js to authenticate in response to a webhook event

The Octokit.js SDK also passes a pre-authenticated `octokit` instance to webhook event handlers.

1. Get the ID of your app. You can find your app's ID on the settings page for your app. For user-owned apps, the settings page is `https://github.com/settings/apps/APP-SLUG`. For organization-owned apps, the settings page is `https://github.com/organizations/ORGANIZATION/settings/apps/APP-SLUG`. Replace `APP-SLUG` with the slugified name of your app. Replace `ORGANIZATION` with the slugified name of your organization. For example, `https://github.com/organizations/octo-org/settings/apps/octo-app`.
1. Generate a private key. For more information, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)".
1. Get the webhook secret that you specified in your app's settings.
1. Import `App` from `octokit`. Create a new instance of `App`. In the following example, replace `APP_ID` with a reference to your app's ID. Replace `PRIVATE_KEY` with a reference to your app's private key. Replace `WEBHOOK_SECRET` with the your app's webhook secret.

```javascript{:copy}
import { App } from "octokit";
const app = new App({
appId: APP_ID,
privateKey: PRIVATE_KEY,
webhooks: { WEBHOOK_SECRET },
});
```

1. Use an `app.webhooks.*` method to handle webhook events. For more information, see [the Octokit.js README's Webhooks section](https://github.com/octokit/octokit.js#webhooks). For example, to create a comment on an issue when the issue is opened:

```javascript
app.webhooks.on("issues.opened", ({ octokit, payload }) => {
await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", {
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.issue.number,
body: `This is a bot post in response to this issue being opened.`,
{% ifversion api-date-versioning %}
headers: {
"x-github-api-version": "{{ allVersions[currentVersion].latestApiVersion }}",
},{% endif %}
}
)
});
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Generating an installation access token for a GitHub App
shortTitle: Installation access token
intro: Learn how to generate an installation access token for your {% data variables.product.prodname_github_app %}.
versions:
fpt: '*'
ghes: '*'
ghae: '*'
ghec: '*'
topics:
- GitHub Apps
---

## About installation access tokens

In order to authenticate as an app installation, you must generate an installation access token. For more information about authenticating as an app installation, see "[Authenticating as a GitHub App installation](/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation)."

{% note %}

**Note**: Instead of generating an installation access token, you can use {% data variables.product.company_short %}'s Octokit SDKs to authenticate as an app. The SDK will take care of generating an installation access token for you and will regenerate the token once it expires. For more information about authenticating as an app installation, see "[Authenticating as a GitHub App installation](/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation)."

{% endnote %}

## Generating an installation access token

{% data reusables.apps.generate-installation-access-token %}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ topics:
- GitHub Apps
children:
- /authenticating-with-github-apps
- /identifying-and-authorizing-users-for-github-apps
- /refreshing-user-to-server-access-tokens
- /authenticating-as-a-github-app
- /authenticating-as-a-github-app-installation
- /managing-private-keys-for-github-apps
- /generating-a-json-web-token-jwt-for-a-github-app
- /generating-an-installation-access-token-for-a-github-app
- /identifying-and-authorizing-users-for-github-apps
- /refreshing-user-to-server-access-tokens
---
31 changes: 31 additions & 0 deletions data/reusables/apps/generate-installation-access-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
1. Generate a JSON web token (JWT) for your app. For more information, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app)".
1. Get the ID of the installation that you want to authenticate as.

If you are responding to a webhook event, the webhook payload will include the installation ID.

You can also use the REST API to find the ID for an installation of your app. For example, you can get an installation ID with the `GET /users/{username}/installation`, `GET /repos/{owner}/{repo}/installation`, `GET /orgs/{org}/installation`, or `GET /app/installations` endpoints. For more information, see "[AUTOTITLE](/rest/apps/apps)".
1. Send a REST API `POST` request to `/app/installations/INSTALLATION_ID/access_tokens`. Include your JSON web token in the `Authorization` header of your request. Replace `INSTALLATION_ID` with the ID of the installation that you want to authenticate as.

For example, send this curl request. Replace `INSTALLATION_ID` with the ID of the installation and `JWT` with your JSON web token:

```shell
curl --request POST \
--url "{% data variables.product.api_url_pre %}app/installations/INSTALLATION_ID/access_tokens" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer JWT"{% ifversion api-date-versioning %}\
--header "X-GitHub-Api-Version: {{ allVersions[currentVersion].latestApiVersion }}"{% endif %}
```

Optionally, you can use the `repositories` or `repository_ids` body parameters to specify individual repositories that the installation access token can access. If you don't use `repositories` or `repository_ids` to grant access to specific repositories, the installation access token will have access to all repositories that the installation was granted access to. The installation access token cannot be granted access to repositories that the installation was not granted access to.

Optionally, use the `permissions` body parameter to specify the permissions that the installation access token should have. If `permissions` is not specified, the installation access token will have all of the permissions that were granted to the app. The installation access token cannot be granted permissions that the app was not granted.

The response will include an installation access token, the time that the token expires, the permissions that the token has, and the repositories that the token can access. The installation access token will expire after 1 hour.

For more information about this endpoint, see "[AUTOTITLE](/rest/apps/apps)".

{% note %}

**Note:** {% data reusables.getting-started.bearer-vs-token %}

{% endnote %}

0 comments on commit 637e68b

Please sign in to comment.