Authentication
There are two workflows for authentication:
- Authenticating as an Integration to retrieve metadata about your integration and to request access tokens.
- Authenticating as an Installation to perform actions in the API.
Most of the useful work is done by authenticating as an Installation. However, it is a prerequisite to grab access tokens as a Integration before being able to do so.
In order to access the API with your Integration, you must provide a custom media type in the Accept
Header for your requests.
application/vnd.github.machine-man-preview+json
As an Integration
To authenticate as an Integration, generate a private key. Use this key to sign a JSON Web Token (JWT). GitHub checks that the request is authenticated by verifying the token with the integration's stored public key.
For the issuer claim (iss), you can obtain the GitHub identifier for your integration via the initial webhook ping after creating the integration, or at any time from the integration settings page in the web UI.
# Private key contents
private_pem = File.read(path_to_pem)
private_key = OpenSSL::PKey::RSA.new(private_pem)
# Generate the JWT
payload = {
# issued at time
iat: Time.now.to_i,
# JWT expiration time
exp: 1.minute.from_now.to_i,
# Integration's GitHub identifier
iss: 42
}
jwt = JWT.encode(payload, private_key, "RS256")
After creating the JWT you need to set it in the Header
of the request:
curl -i -H "Authorization: Bearer $JWT"
As an installation
Installation access tokens are used by integrations to perform actions in the API.
- Installation access tokens are scoped to the repositories an installation can access.
- Installation access tokens have the permissions that an integration specifies.
- Installation access tokens expire after one hour.
To create an installation access token, include the JWT payload generated above:
curl -i -X POST \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github.machine-man-preview+json" \
https://api.github.com/installations/:installation_id/access_tokens
Status: 201 Created
{
"token": "v1.1f699f1069f60xxx",
"expires_at": "2016-07-11T22:14:10Z",
"on_behalf_of": null
}
To authenticate with an installation access tokens, include it with the Authorization header:
curl -i \
-H "Authorization: token $INSTALLATION_TOKEN" \
-H "Accept: application/vnd.github.machine-man-preview+json" \
https://api.github.com/installations/:installation_id/access_tokens
Requesting an access token on behalf of a user
Integrations can perform actions on behalf of users for the following:
Name | Type | Description |
---|---|---|
user_id |
integer |
The GitHub id of the user for whom the integration is acting on behalf of. |
curl -i -X POST \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github.machine-man-preview+json" \
-d '{"user_id": 1}' \
https://api.github.com/installations/:installation_id/access_tokens
Status: 201 Created
{
"token": "v1.1f699f1069f60xxx",
"expires_at": "2016-07-11T22:14:10Z",
"on_behalf_of": {
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
}
}
Request for an access token, on behalf of a user who doesn't have access to the installation
This could be the case if a user no longer has access to the repositories the integration is installed on.
curl -i -X POST \ -H "Authorization: Bearer $JWT" \ -H "Accept: application/vnd.github.machine-man-preview+json" \ -d '{"user_id": 4635}' \ https://api.github.com/installations/:installation_id/access_tokens HTTP/1.1 403 Forbidden { "message": "User does not have access to this installation", "documentation_url": "https://developer.github.com/v3" }
Request for an access token, on behalf of a user who doesn't exist
curl -i -X POST \ -H "Authorization: Bearer $JWT" \ -H "Accept: application/vnd.github.machine-man-preview+json" \ -d '{"user_id": 838383838}' \ https://api.github.com/installations/:installation_id/access_tokens HTTP/1.1 404 Not Found { "message": "Not Found", "documentation_url": "https://developer.github.com/v3" }
Actions performed with an installation access token on behalf of a user requires both the user and the installation to have access to the resource. A 403
is returned otherwise.
HTTP-based Git access by an installation
Installations with permissions on "contents" of a repository, can use their access tokens to authenticate for Git access. The token is used as the HTTP password.
git clone https://x-access-token:<token>@github.com/owner/repo.git