- Notifications
You must be signed in to change notification settings - Fork56
GitHub App authentication for JavaScript
License
octokit/auth-app.js
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
GitHub App authentication for JavaScript
@octokit/auth-app
implements authentication for GitHub Apps usingJSON Web Token, installation access tokens, and OAuth user-to-server access tokens.
- Standalone usage
- Usage with Octokit
createAppAuth(options)
ornew Octokit({ auth })
auth(options)
oroctokit.auth(options)
- Authentication object
auth.hook(request, route, parameters)
orauth.hook(request, options)
- Types
- Implementation details
- License
Browsers |
The private keys provided by GitHub are in openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private-key.pem -out private-key-pkcs8.key The OAuth APIs to create user-to-server tokens cannot be used because they do not have CORS enabled. If you know what you are doing, load <scripttype="module">import{createAppAuth}from"https://esm.sh/@octokit/auth-app";</script> |
---|---|
Node | Install with import{createAppAuth}from"@octokit/auth-app"; |
Important
As we useconditional exports, you will need to adapt yourtsconfig.json
by setting"moduleResolution": "node16", "module": "node16"
.
See the TypeScript docs onpackage.json "exports".
See thishelpful guide on transitioning to ESM from@sindresorhus
constauth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef12341234567890abcdef1234",});// Retrieve JSON Web Token (JWT) to authenticate as appconstappAuthentication=awaitauth({type:"app"});
resolves with
{"type":"app","token":"jsonwebtoken123","appId":123,"expiresAt":"2018-07-07T00:09:30.000Z"}
TheOAuth Application APIs require the app to authenticate using clientID/client as Basic Authentication
constauth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef12341234567890abcdef1234",});constappAuthentication=awaitauth({type:"oauth-app",});
resolves with
{"type":"oauth-app","clientId":"lv1.1234567890abcdef","clientSecret":"1234567890abcdef1234567890abcdef12345678","headers": {"authorization":"basic bHYxLjEyMzQ1Njc4OTBhYmNkZWY6MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3OA==" }}
constauth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef12341234567890abcdef1234",});// Retrieve installation access tokenconstinstallationAuthentication=awaitauth({type:"installation",installationId:123,});
resolves with
{"type":"token","tokenType":"installation","token":"token123","installationId":123,"createdAt":"2018-07-07T00:00:00.000Z","expiresAt":"2018-07-07T00:59:00.000Z"}
constauth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef12341234567890abcdef1234",});// Retrieve an oauth-access tokenconstuserAuthentication=awaitauth({type:"oauth-user",code:"123456"});
Resolves with
{"type":"token","tokenType":"oauth","token":"token123"}
Browsers |
The private keys provided by GitHub are in openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private-key.pem -out private-key-pkcs8.key The OAuth APIs to create user-to-server tokens cannot be used because they do not have CORS enabled. If you know what you are doing, load <scripttype="module">import{createAppAuth}from"https://esm.sh/@octokit/auth-app";import{Octokit}from"https://esm.sh/@octokit/core";</script> |
---|---|
Node | Install with import{Octokit}from"@octokit/core";import{createAppAuth,createOAuthUserAuth}from"@octokit/auth-app"; |
constappOctokit=newOctokit({authStrategy:createAppAuth,auth:{appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",},});// Send requests as GitHub Appconst{ slug}=awaitappOctokit.request("GET /app");console.log("authenticated as %s",slug);// Send requests as OAuth AppawaitappOctokit.request("POST /application/{client_id}/token",{client_id:"1234567890abcdef1234",access_token:"existingtoken123",});console.log("token is valid");// create a new octokit instance that is authenticated as the userconstuserOctokit=awaitappOctokit.auth({type:"oauth-user",code:"code123",factory:(options)=>{returnnewOctokit({authStrategy:createOAuthUserAuth,auth:options,});},});// Exchanges the code for the user access token authentication on first request// and caches the authentication for successive requestsconst{data:{ login},}=awaituserOctokit.request("GET /user");console.log("Hello, %s!",login);
In order to create anoctokit
instance that is authenticated as an installation, with automated installation token refresh, setinstallationId
asauth
option
constinstallationOctokit=newOctokit({authStrategy:createAppAuth,auth:{appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",installationId:123,},});// transparently creates an installation access token the first time it is needed// and refreshes it when it expiresawaitinstallationOctokit.request("POST /repos/{owner}/{repo}/issues",{owner:"octocat",repo:"hello-world",title:"title",});
name | type | description |
---|---|---|
appId | number | Required. FindApp ID on the app’s about page in settings. |
privateKey | string | Required. Content of the*.pem file you downloaded from the app’s about page. You can generate a new private key if needed. If your private key contains escaped newlines (`\\n`), they will be automatically replaced with actual newlines. |
installationId | number | DefaultinstallationId to be used when callingauth({ type: "installation" }) . |
clientId | string | The client ID of the GitHub App. |
clientSecret | string | A client secret for the GitHub App. |
request | function | Automatically set to For standalone usage, you can pass in your own import{request}from"@octokit/request";createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",request:request.defaults({baseUrl:"https://ghe.my-company.com/api/v3",}),}); |
cache | object | Installation tokens expire after an hour. By default,@octokit/auth-app is caching up to 15000 tokens simultaneously usingtoad-cache. You can pass your own cache implementation by passingoptions.cache.{get,set} to the constructor. Example:constCACHE={};createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",cache:{asyncget(key){returnCACHE[key];},asyncset(key,value){CACHE[key]=value;},},}); |
log | object | You can pass in your preferred logging tool by passingoption.log to the constructor. If you would like to make the log level configurable using an environment variable or external option, we recommend the console-log-level package. For example:importconsoleLogLevelfrom"console-log-level";createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",log:consoleLogLevel({level:"info"}),}); |
The asyncauth()
method accepts different options depending on your use case
Authenticate as the GitHub app to list installations, repositories, and create installation access tokens.
name | type | description |
---|---|---|
type | string | Required. Must be either"app" . |
Create, reset, refresh, delete OAuth user-to-server tokens
name | type | description |
---|---|---|
type | string | Required. Must be either"oauth-app" . |
name | type | description |
---|---|---|
type | string | Required. Must be"installation" . |
installationId | number | Required unless a defaultinstallationId was passed tocreateAppAuth() . ID of installation to retrieve authentication for. |
repositoryIds | array of numbers | The id of the repositories that the installation token can access. Also known as adatabaseID when querying the repository object in GitHub's GraphQL API. This option is **(recommended)** overrepositoryNames when needing to limit the scope of the access token, due torepositoryNames having the possibility of changing. Additionally, you should only include eitherrepositoryIds orrepositoryNames , but not both. |
repositoryNames | array of strings | Thename of the repositories that the installation token can access. As mentioned in therepositoryIds description, you should only include eitherrepositoryIds orrepositoryNames , but not both. |
permissions | object | The permissions granted to the access token. The permissions object includes the permission names and their access type. For a complete list of permissions and allowable values, seeGitHub App permissions. |
factory | function | The For example, you can create a new constappAuth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",});constinstallationAuth123=awaitappAuth({type:"installation",installationId:123,factory:createAppAuth,}); |
refresh | boolean | Installation tokens expire after one hour. By default, tokens are cached and returned from cache until expired. To bypass and update a cached token for the given Defaults to |
Exchange code received from the web flow redirect described instep 2 of GitHub's OAuth web flow
name | type | description |
---|---|---|
type | string | Required. Must be"oauth-user" . |
factory | function | The For example, you can create a new import{createAppAuth,createOAuthUserAuth}from"@octokit/auth-oauth-app";constappAuth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef1234567890abcdef12345678",});constuserAuth=awaitappAuth({type:"oauth-user", code,factory:createOAuthUserAuth,});// will create token upon first call, then cache authentication for successive calls,// until token needs to be refreshed (if enabled for the GitHub App)constauthentication=awaituserAuth(); |
code | string | The authorizationcode which was passed as query parameter to the callback URL from theOAuth web application flow. |
redirectUrl | string | The URL in your application where users are sent after authorization. Seeredirect urls. |
state | string | The unguessable random string you provided in Step 1 of theOAuth web application flow. |
Create a token usingGitHub's device flow.
The device flow does not require a client secret, but it is required as strategy option for@octokit/auth-app
, even for the device flow. If you want to implement the device flow without requiring a client secret, use@octokit/auth-oauth-device
.
name | type | description |
---|---|---|
type | string | Required. Must be"oauth-user" . |
onVerification | function | Required. A function that is called once the device and user codes were retrieved. The constauth=auth({type:"oauth-user",onVerification(verification){console.log("Open %s",verification.verification_uri);console.log("Enter code: %s",verification.user_code);awaitprompt("press enter when you are ready to continue");},}); |
factory | function | The For example, you can create a new import{createAppAuth,createOAuthUserAuth}from"@octokit/auth-oauth-app";constappAuth=createAppAuth({appId:1,privateKey:"-----BEGIN PRIVATE KEY-----\n...",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef1234567890abcdef12345678",});constuserAuth=awaitappAuth({type:"oauth-user", code,factory:createOAuthUserAuth,});// will create token upon first call, then cache authentication for successive calls,// until token needs to be refreshed (if enabled for the GitHub App)constauthentication=awaituserAuth(); |
Depending on on theauth()
call, the resulting authentication object can be one of
- JSON Web Token (JWT) authentication
- OAuth App authentication
- Installation access token authentication
- GitHub APP user authentication token with expiring disabled
- GitHub APP user authentication token with expiring enabled
name | type | description |
---|---|---|
type | string | "app" |
token | string | The JSON Web Token (JWT) to authenticate as the app. |
appId | number | GitHub App database ID. |
expiresAt | string | Timestamp in UTC format, e.g."2018-07-07T00:09:30.000Z" . A Date object can be created usingnew Date(authentication.expiresAt) . |
name | type | description |
---|---|---|
type | string | "oauth-app" |
clientType | string | "github-app" |
clientId | string | The client ID as passed to the constructor. |
clientSecret | string | The client secret as passed to the constructor. |
headers | object | { authorization } . |
name | type | description |
---|---|---|
type | string | "token" |
token | string | The installation access token. |
tokenType | string | "installation" |
installationId | number | Installation database ID. |
createdAt | string | Timestamp in UTC format, e.g."2018-07-07T00:00:00.000Z" . A Date object can be created usingnew Date(authentication.expiresAt) . |
expiresAt | string | Timestamp in UTC format, e.g."2018-07-07T00:59:00.000Z" . A Date object can be created usingnew Date(authentication.expiresAt) . |
repositoryIds | array of numbers | Only present ifrepositoryIds option passed toauth(options) . |
repositoryNames | array of strings | Only present ifrepositoryNames option passed toauth(options) . |
permissions | object | An object where keys are the permission name and the value is either"read" or"write" . See the list of allGitHub App Permissions. |
singleFileName | string | If the single file permission is enabled, thesingleFileName property is set to the path of the accessible file. |
name | type | description |
---|---|---|
type | string | "token" |
tokenType | string | "oauth" |
clientType | string | "github-app" |
clientId | string | The app'sClient ID |
clientSecret | string | One of the app's client secrets |
token | string | The user access token |
name | type | description |
---|---|---|
type | string | "token" |
tokenType | string | "oauth" |
clientType | string | "github-app" |
clientId | string | The app'sClient ID |
clientSecret | string | One of the app's client secrets |
token | string | The user access token |
refreshToken | string | The refresh token |
expiresAt | string | Date timestamp inISO 8601 standard. Example:2022-01-01T08:00:0.000Z |
refreshTokenExpiresAt | string | Date timestamp inISO 8601 standard. Example:2021-07-01T00:00:0.000Z |
auth.hook()
hooks directly into the request life cycle. It amends the request to authenticate either as app or as installation based on the request URL. Although the"machine-man"
preview has graduated to the official API,https://developer.github.com/changes/2020-08-20-graduate-machine-man-and-sailor-v-previews/, it is still required in versions of GitHub Enterprise up to 2.21 so it automatically sets the"machine-man"
preview for all endpoints requiring JWT authentication.
Therequest
option is an instance of@octokit/request
. The arguments are the same as for therequest()
method.
auth.hook()
can be called directly to send an authenticated request
const{data:installations}=awaitauth.hook(request,"GET /app/installations",);
Or it can be passed as option torequest()
.
constrequestWithAuth=request.defaults({request:{hook:auth.hook,},});const{data:installations}=awaitrequestWithAuth("GET /app/installations");
Note thatauth.hook()
does not create and set an OAuth authentication token. But you can use@octokit/auth-oauth-app
for that functionality. And if you don't plan on sending requests to routes that require authentication withclient_id
andclient_secret
, you can just retrieve the token and then create a new instance ofrequest()
with the authentication header set:
const{ token}=awaitauth({type:"oauth-user",code:"123456",});constrequestWithAuth=request.defaults({headers:{authentication:`token${token}`,},});
import{// strategy optionsStrategyOptions,// auth optionsAuthOptions,AppAuthOptions,OAuthAppAuthOptions,InstallationAuthOptions,OAuthWebFlowAuthOptions,OAuthDeviceFlowAuthOptions,// authentication objectsAuthentication,AppAuthentication,OAuthAppAuthentication,InstallationAccessTokenAuthentication,GitHubAppUserAuthentication,GitHubAppUserAuthenticationWithExpiration,}from"@octokit/auth-app";
When creating a JSON Web Token, it sets the "issued at time" (iat) to 30s in the past as we have seen people running situations where the GitHub API claimed the iat would be in future. It turned out the clocks on the different machine were not in sync.
Installation access tokens are valid for 60 minutes. This library invalidates them after 59 minutes to account for request delays.
All OAuth features are implemented internally using@octokit/auth-oauth-app.
About
GitHub App authentication for JavaScript
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.