Skip to content

Commit 2e635a3

Browse files
hpsinskedwards88stacycarter
authored
Clarify CAP and relation to GitHub apps (#33740)
Co-authored-by: Sarah Edwards <[email protected]> Co-authored-by: Stacy Carter <[email protected]>
1 parent 59bb158 commit 2e635a3

File tree

2 files changed

+88
-81
lines changed

2 files changed

+88
-81
lines changed

content/admin/identity-and-access-management/using-enterprise-managed-users-for-iam/about-support-for-your-idps-conditional-access-policy.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ If you're unable to use a service account, another option for unblocking actions
3737

3838
### {% data variables.product.prodname_github_apps %} and {% data variables.product.prodname_oauth_apps %}
3939

40-
When {% data variables.product.prodname_github_apps %} and {% data variables.product.prodname_oauth_apps %} make requests on a member's behalf, {% data variables.product.prodname_dotcom %} will send the IP address of the app's server to your IdP for validation. If the IP address of the app's server is not validated by your IdP's CAP, the request will fail.
40+
When {% data variables.product.prodname_github_apps %} and {% data variables.product.prodname_oauth_apps %} sign a user in and make requests on that user's behalf, also known as a [`user-to-server` request](/get-started/quickstart/github-glossary#user-to-server-request), {% data variables.product.prodname_dotcom %} will send the IP address of the app's server to your IdP for validation. If the IP address of the app's server is not validated by your IdP's CAP, the request will fail.
41+
42+
When {% data variables.product.prodname_github_apps %} call {% data variables.product.prodname_dotcom %} APIs acting either as the app itself or as an installation, these calls are not performed on behalf of a user - this is also known as a [`server-to-server` request](/get-started/quickstart/github-glossary#server-to-server-request). Since your IdP's CAP executes and applies policies to user accounts, these application requests cannot be validated against CAP and are always allowed through. For more information on {% data variables.product.prodname_github_apps %} authenticating as themselves, see "[Authenticating with GitHub Apps](/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app)".
4143

4244
You can contact the owners of the apps you want to use, ask for their IP ranges, and configure your IdP's CAP to allow access from those IP ranges. If you're unable to contact the owners, you can review your IdP sign-in logs to review the IP addresses seen in the requests, then allow-list those addresses.
4345

content/developers/apps/building-github-apps/authenticating-with-github-apps.md

Lines changed: 85 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,85 @@ topics:
1616
shortTitle: Authentication
1717
---
1818

19+
## Authenticating as a {% data variables.product.prodname_github_app %}
1920

20-
## Generating a private key
21+
Authenticating as a {% data variables.product.prodname_github_app %} is required for [`server-to-server`](/get-started/quickstart/github-glossary#server-to-server-request) API calls, which let your {% data variables.product.prodname_github_app %} do a couple things:
2122

22-
After you create a GitHub App, you'll need to generate one or more private keys. You'll use the private key to sign access token requests.
23+
* Retrieve high-level management information about your {% data variables.product.prodname_github_app %}.
24+
* Request access tokens for an installation of the app, allowing you to make API calls without a signed-in user.
2325

24-
You can create multiple private keys and rotate them to prevent downtime if a key is compromised or lost. To verify that a private key matches a public key, see [Verifying private keys](#verifying-private-keys).
26+
To authenticate as a {% data variables.product.prodname_github_app %}, [generate a private key](#generating-a-private-key) in PEM format and download it to your local machine. You'll use this key to [sign a JSON Web Token (JWT)](#jwt-payload) and encode it using the `RS256` algorithm. {% data variables.product.product_name %} validates your app's identity by verifying the token with the app's stored public key. You'll exchange this JWT for an installation token, used to authenticate your app as a specific installation.
2527

26-
To generate a private key:
28+
### Listing the installations for an app
2729

28-
{% data reusables.user-settings.access_settings %}
29-
{% data reusables.user-settings.developer_settings %}
30-
{% data reusables.user-settings.github_apps %}
31-
{% data reusables.user-settings.modify_github_app %}
32-
5. In "Private keys", click **Generate a private key**.
33-
![Generate private key](/assets/images/github-apps/github_apps_generate_private_keys.png)
34-
6. You will see a private key in PEM format downloaded to your computer. Make sure to store this file because GitHub only stores the public portion of the key.
30+
To list the installations for your app, include the JWT in the Authorization header in an API request to `GET /app/installations`. For more information about generating a JWT, see "[JWT payload](#jwt-payload)."
31+
32+
```shell
33+
$ curl -i -X GET \
34+
-H "Authorization: Bearer YOUR_JWT" \
35+
-H "Accept: application/vnd.github+json" \
36+
{% data variables.product.api_url_pre %}/app/installations
37+
```
38+
39+
The response will include a list of installations where each installation's `id` can be used for creating an installation access token. For more information about the response format, see "[List installations for the authenticated app](/rest/reference/apps#list-installations-for-the-authenticated-app)."
40+
41+
## Authenticating as an installation
42+
43+
Authenticating as an installation lets your app access that organization or user via the API, as well as public resources on {% data variables.product.product_name %}. To authenticate as an installation, you must use an installation access token, which you get by sending a [JWT](#jwt-payload) to {% data variables.product.product_name %} to prove your app's identity. Ensure that you have already installed your GitHub App to at least one organization or user account; it is impossible to create an installation token without an installation. For more information, see "[Installing GitHub Apps](/developers/apps/managing-github-apps/installing-github-apps)."
44+
45+
By default, installation access tokens are scoped to all the repositories that an installation was granted access to. You can further limit the scope of the installation access token to specific repositories by using the `repository_ids` parameter. Installation access tokens have the permissions configured by the {% data variables.product.prodname_github_app %}, and like repository access, can also be scoped down using the `permissions` parameter. For more information, see the [Create an installation access token for an app](/rest/reference/apps#create-an-installation-access-token-for-an-app) endpoint documentation. All installation tokens expire after 1 hour.
46+
47+
To create an installation access token, include the JWT in the Authorization header in the API request, replacing `:installation_id` with the installation's `id`. For more information about generating a JWT, see "[JWT payload](#jwt-payload)."
48+
49+
```shell
50+
$ curl -i -X POST \
51+
-H "Authorization: Bearer YOUR_JWT" \
52+
-H "Accept: application/vnd.github+json" \
53+
{% data variables.product.api_url_pre %}/app/installations/:installation_id/access_tokens
54+
```
55+
56+
The response will include your installation access token, the expiration date, the token's permissions, and the repositories that the token can access. For more information about the response format, see the [Create an installation access token for an app](/rest/reference/apps#create-an-installation-access-token-for-an-app) endpoint.
57+
58+
To authenticate with an installation access token, include it in the Authorization header in the API request. Replace `YOUR_INSTALLATION_ACCESS_TOKEN` with an installation access token:
59+
60+
```shell
61+
$ curl -i \
62+
-H "Authorization: Bearer YOUR_INSTALLATION_ACCESS_TOKEN" \
63+
-H "Accept: application/vnd.github+json" \
64+
{% data variables.product.api_url_pre %}/installation/repositories
65+
```
3566

3667
{% note %}
3768

38-
**Note:** If you're using a library that requires a specific file format, the PEM file you download will be in `PKCS#1 RSAPrivateKey` format.
69+
**Note:** {% data reusables.getting-started.bearer-vs-token %}
3970

4071
{% endnote %}
4172

42-
## Verifying private keys
43-
{% data variables.product.product_name %} generates a fingerprint for each private and public key pair using the SHA-256 hash function. You can verify that your private key matches the public key stored on {% data variables.product.product_name %} by generating the fingerprint of your private key and comparing it to the fingerprint shown on {% data variables.product.product_name %}.
73+
## Accessing API endpoints as an installation
4474

45-
To verify a private key:
75+
For a list of REST API endpoints that are available for use by {% data variables.product.prodname_github_apps %} using an installation access token, see "[Endpoints available for GitHub Apps](/rest/overview/endpoints-available-for-github-apps)."
4676

47-
1. Find the fingerprint for the private and public key pair you want to verify in the "Private keys" section of your {% data variables.product.prodname_github_app %}'s developer settings page. For more information, see [Generating a private key](#generating-a-private-key).
48-
![Private key fingerprint](/assets/images/github-apps/github_apps_private_key_fingerprint.png)
49-
2. Generate the fingerprint of your private key (PEM) locally by using the following command:
50-
```shell
51-
$ openssl rsa -in PATH_TO_PEM_FILE -pubout -outform DER | openssl sha256 -binary | openssl base64
52-
```
53-
3. Compare the results of the locally generated fingerprint to the fingerprint you see in {% data variables.product.product_name %}.
77+
For a list of endpoints related to installations, see "[Installations](/rest/reference/apps#installations)."
5478

55-
## Deleting private keys
56-
You can remove a lost or compromised private key by deleting it, but you must have at least one private key. When you only have one key, you will need to generate a new one before deleting the old one.
57-
![Deleting last private key](/assets/images/github-apps/github_apps_delete_key.png)
79+
## HTTP-based Git access by an installation
5880

59-
## Authenticating as a {% data variables.product.prodname_github_app %}
81+
Installations with [permissions](/apps/building-github-apps/setting-permissions-for-github-apps/) on `contents` of a repository, can use their installation access tokens to authenticate for Git access. Use the installation access token as the HTTP password:
82+
83+
```shell
84+
git clone https://x-access-token:&lt;token&gt;@github.com/owner/repo.git
85+
```
6086

61-
Authenticating as a {% data variables.product.prodname_github_app %} lets you do a couple of things:
87+
## Generating a JSON Web Token (JWT)
6288

63-
* You can retrieve high-level management information about your {% data variables.product.prodname_github_app %}.
64-
* You can request access tokens for an installation of the app.
89+
The [JWT](https://jwt.io/) that's used to authenticate your application is made up of several claims, as well as a signature that's used to validate its authenticity. Those claims are:
6590

66-
To authenticate as a {% data variables.product.prodname_github_app %}, [generate a private key](#generating-a-private-key) in PEM format and download it to your local machine. You'll use this key to sign a [JSON Web Token (JWT)](https://jwt.io/introduction) and encode it using the `RS256` algorithm. {% data variables.product.product_name %} checks that the request is authenticated by verifying the token with the app's stored public key.
91+
|Claim | Meaning | Details |
92+
|---|---|---|
93+
|`iat`| Issued At | The time the JWT was created. To protect against clock drift, we recommend you set this 60 seconds in the past. |
94+
|`exp`| Expires At | The expiration time of the JWT, after which it can't be used to request an installation token. The `exp` must be no more than 10 minutes into the future. |
95+
|`iss`| Issuer | Your application ID, used to find the right public key to verify the signature of the JWT. |
6796

68-
### Generating a Json Web Token (JWT)
97+
Tokens must be signed using the `RS256` algorithm, with a matching `alg` claim of `RS256`.
6998

7099
#### Using Ruby
71100

@@ -94,8 +123,6 @@ jwt = JWT.encode(payload, private_key, "RS256")
94123
puts jwt
95124
```
96125

97-
98-
99126
#### Using Python
100127

101128
Here is a similar script for generating a JWT in Python. Note you will have to use `pip install jwt` in order to use this script. This script will prompt you for the location of your PEM file and your app's ID, or you can pass them as inline arguments when you execute the script.
@@ -149,8 +176,6 @@ $ curl -i -H "Authorization: Bearer YOUR_JWT" -H "Accept: application/vnd.github
149176

150177
`YOUR_JWT` is the value you must replace.
151178

152-
153-
154179
The examples above uses the maximum expiration time of 10 minutes, after which the API will start returning a `401` error:
155180

156181
```json
@@ -166,61 +191,41 @@ You'll need to create a new JWT after the time expires.
166191

167192
For a list of REST API endpoints you can use to get high-level information about a {% data variables.product.prodname_github_app %}, see "[GitHub Apps](/rest/reference/apps)."
168193

169-
## Authenticating as an installation
170-
171-
Authenticating as an installation lets you perform actions in the API for that installation. Before authenticating as an installation, you must create an installation access token. Ensure that you have already installed your GitHub App to at least one repository; it is impossible to create an installation token without a single installation. These installation access tokens are used by {% data variables.product.prodname_github_apps %} to authenticate. For more information, see "[Installing GitHub Apps](/developers/apps/managing-github-apps/installing-github-apps)."
172-
173-
By default, installation access tokens are scoped to all the repositories that an installation can access. You can limit the scope of the installation access token to specific repositories by using the `repository_ids` parameter. See the [Create an installation access token for an app](/rest/reference/apps#create-an-installation-access-token-for-an-app) endpoint for more details. Installation access tokens have the permissions configured by the {% data variables.product.prodname_github_app %} and expire after one hour.
174-
175-
To list the installations for an authenticated app, include the JWT [generated above](#jwt-payload) in the Authorization header in the API request:
176-
177-
```shell
178-
$ curl -i -X GET \
179-
-H "Authorization: Bearer YOUR_JWT" \
180-
-H "Accept: application/vnd.github+json" \
181-
{% data variables.product.api_url_pre %}/app/installations
182-
```
183-
184-
The response will include a list of installations where each installation's `id` can be used for creating an installation access token. For more information about the response format, see "[List installations for the authenticated app](/rest/reference/apps#list-installations-for-the-authenticated-app)."
185-
186-
To create an installation access token, include the JWT [generated above](#jwt-payload) in the Authorization header in the API request and replace `:installation_id` with the installation's `id`:
187-
188-
```shell
189-
$ curl -i -X POST \
190-
-H "Authorization: Bearer YOUR_JWT" \
191-
-H "Accept: application/vnd.github+json" \
192-
{% data variables.product.api_url_pre %}/app/installations/:installation_id/access_tokens
193-
```
194+
## Generating a private key
194195

195-
The response will include your installation access token, the expiration date, the token's permissions, and the repositories that the token can access. For more information about the response format, see the [Create an installation access token for an app](/rest/reference/apps#create-an-installation-access-token-for-an-app) endpoint.
196+
After you create a {% data variables.product.prodname_github_app %}, you'll need to generate one or more private keys in order to make requests to the {% data variables.product.product_name %} API as the application itself. You'll use the private key to sign the [JWTs used to request an installation access token](#jwt-payload).
196197

197-
To authenticate with an installation access token, include it in the Authorization header in the API request:
198+
You can create multiple private keys and rotate them to prevent downtime if a key is compromised or lost. To verify that a private key matches a public key, see [Verifying private keys](#verifying-private-keys).
198199

199-
```shell
200-
$ curl -i \
201-
-H "Authorization: Bearer YOUR_INSTALLATION_ACCESS_TOKEN" \
202-
-H "Accept: application/vnd.github+json" \
203-
{% data variables.product.api_url_pre %}/installation/repositories
204-
```
200+
To generate a private key:
205201

206-
`YOUR_INSTALLATION_ACCESS_TOKEN` is the value you must replace.
202+
{% data reusables.user-settings.access_settings %}
203+
{% data reusables.user-settings.developer_settings %}
204+
{% data reusables.user-settings.github_apps %}
205+
{% data reusables.user-settings.modify_github_app %}
206+
5. In "Private keys", click **Generate a private key**.
207+
![Generate private key](/assets/images/github-apps/github_apps_generate_private_keys.png)
208+
6. You will see a private key in PEM format downloaded to your computer. Make sure to store this file because GitHub only stores the public portion of the key.
207209

208210
{% note %}
209211

210-
**Note:** {% data reusables.getting-started.bearer-vs-token %}
212+
**Note:** If you're using a library that requires a specific file format, the PEM file you download will be in `PKCS#1 RSAPrivateKey` format.
211213

212214
{% endnote %}
213215

214-
## Accessing API endpoints as an installation
215-
216-
For a list of REST API endpoints that are available for use by {% data variables.product.prodname_github_apps %} using an installation access token, see "[Available Endpoints](/rest/overview/endpoints-available-for-github-apps)."
217-
218-
For a list of endpoints related to installations, see "[Installations](/rest/reference/apps#installations)."
216+
## Verifying private keys
217+
{% data variables.product.product_name %} generates a fingerprint for each private and public key pair using the SHA-256 hash function. You can verify that your private key matches the public key stored on {% data variables.product.product_name %} by generating the fingerprint of your private key and comparing it to the fingerprint shown on {% data variables.product.product_name %}.
219218

220-
## HTTP-based Git access by an installation
219+
To verify a private key:
221220

222-
Installations with [permissions](/apps/building-github-apps/setting-permissions-for-github-apps/) on `contents` of a repository, can use their installation access tokens to authenticate for Git access. Use the installation access token as the HTTP password:
221+
1. Find the fingerprint for the private and public key pair you want to verify in the "Private keys" section of your {% data variables.product.prodname_github_app %}'s developer settings page. For more information, see [Generating a private key](#generating-a-private-key).
222+
![Private key fingerprint](/assets/images/github-apps/github_apps_private_key_fingerprint.png)
223+
2. Generate the fingerprint of your private key (PEM) locally by using the following command:
224+
```shell
225+
$ openssl rsa -in PATH_TO_PEM_FILE -pubout -outform DER | openssl sha256 -binary | openssl base64
226+
```
227+
3. Compare the results of the locally generated fingerprint to the fingerprint you see in {% data variables.product.product_name %}.
223228

224-
```shell
225-
git clone https://x-access-token:&lt;token&gt;@github.com/owner/repo.git
226-
```
229+
## Deleting private keys
230+
You can remove a lost or compromised private key by deleting it, but you must always have at least one private key registered for your {% data variables.product.prodname_github_app %}. When your {% data variables.product.prodname_github_app %} has only one key, you will need to generate a new one before deleting the old one.
231+
![Deleting last private key](/assets/images/github-apps/github_apps_delete_key.png)

0 commit comments

Comments
 (0)