• Stars
    star
    142
  • Rank 249,267 (Top 6 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 5 years ago
  • Updated 21 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

GitHub App authentication for JavaScript

auth-app.js

GitHub App authentication for JavaScript

@latest Build Status

@octokit/auth-app implements authentication for GitHub Apps using JSON Web Token, installation access tokens, and OAuth user-to-server access tokens.

Standalone usage

Browsers

⚠️ @octokit/auth-app is not meant for usage in the browser. A private key and client secret must not be exposed to users.

The private keys provided by GitHub are in PKCS#1 format, but the WebCrypto API only supports PKCS#8. You need to convert it first:

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 @octokit/auth-app directly from cdn.skypack.dev

<script type="module">
  import { createAppAuth } from "https://cdn.skypack.dev/@octokit/auth-app";
</script>
Node

Install with npm install @octokit/auth-app

const { createAppAuth } = require("@octokit/auth-app");
// or: import { createAppAuth } from "@octokit/auth-app";

Authenticate as GitHub App (JSON Web Token)

const auth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12341234567890abcdef1234",
});

// Retrieve JSON Web Token (JWT) to authenticate as app
const appAuthentication = await auth({ type: "app" });

resolves with

{
  "type": "app",
  "token": "jsonwebtoken123",
  "appId": 123,
  "expiresAt": "2018-07-07T00:09:30.000Z"
}

Authenticate as OAuth App (client ID/client secret)

The OAuth Application APIs require the app to authenticate using clientID/client as Basic Authentication

const auth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12341234567890abcdef1234",
});

const appAuthentication = await auth({
  type: "oauth-app",
});

resolves with

{
  "type": "oauth-app",
  "clientId": "lv1.1234567890abcdef",
  "clientSecret": "1234567890abcdef1234567890abcdef12345678",
  "headers": {
    "authorization": "basic bHYxLjEyMzQ1Njc4OTBhYmNkZWY6MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3OA=="
  }
}

Authenticate as installation

const auth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12341234567890abcdef1234",
});

// Retrieve installation access token
const installationAuthentication = await auth({
  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"
}

Authenticate as user

const auth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12341234567890abcdef1234",
});

// Retrieve an oauth-access token
const userAuthentication = await auth({ type: "oauth-user", code: "123456" });

Resolves with

{
  "type": "token",
  "tokenType": "oauth",
  "token": "token123"
}

Usage with Octokit

Browsers

⚠️ @octokit/auth-app is not meant for usage in the browser. A private key and client secret must not be exposed to users.

The private keys provided by GitHub are in PKCS#1 format, but the WebCrypto API only supports PKCS#8. You need to convert it first:

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 @octokit/auth-app and @octokit/core (or a compatible module) directly from cdn.skypack.dev

<script type="module">
  import { createAppAuth } from "https://cdn.skypack.dev/@octokit/auth-app";
  import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
</script>

Node

Install with npm install @octokit/core @octokit/auth-app. Optionally replace @octokit/core with a compatible module

const { Octokit } = require("@octokit/core");
const { createAppAuth, createOAuthUserAuth } = require("@octokit/auth-app");
const appOctokit = new Octokit({
  authStrategy: createAppAuth,
  auth: {
    appId: 1,
    privateKey: "-----BEGIN PRIVATE KEY-----\n...",
    clientId: "1234567890abcdef1234",
    clientSecret: "1234567890abcdef1234567890abcdef12345678",
  },
});

// Send requests as GitHub App
const { slug } = await appOctokit.request("GET /user");
console.log("authenticated as %s", slug);

// Send requests as OAuth App
await appOctokit.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 user
const userOctokit = await appOctokit.auth({
  type: "oauth-user",
  code: "code123",
  factory: (options) => {
    return new Octokit({
      authStrategy: createOAuthUserAuth,
      auth: options,
    });
  },
});

// Exchanges the code for the user access token authentication on first request
// and caches the authentication for successive requests
const {
  data: { login },
} = await userOctokit.request("GET /user");
console.log("Hello, %s!", login);

In order to create an octokit instance that is authenticated as an installation, with automated installation token refresh, set installationId as auth option

const installationOctokit = new Octokit({
  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 expires
await installationOctokit.request("POST /repos/{owner}/{repo}/issues", {
  owner: "octocat",
  repo: "hello-world",
  title: "title",
});

createAppAuth(options) or new Octokit({ auth })

name type description
appId number Required. Find App 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.
installationId number Default installationId to be used when calling auth({ 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 octokit.request when using with an Octokit constructor.

For standalone usage, you can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the hostname + /api/v3. Example:

const { request } = require("@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 using lru-cache. You can pass your own cache implementation by passing options.cache.{get,set} to the constructor. Example:
const CACHE = {};
createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  cache: {
    async get(key) {
      return CACHE[key];
    },
    async set(key, value) {
      CACHE[key] = value;
    },
  },
});
log object You can pass in your preferred logging tool by passing option.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:
createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  log: require("console-log-level")({ level: "info" }),
});

auth(options) or octokit.auth(options)

The async auth() method accepts different options depending on your use case

JSON Web Token (JWT) Authentication

Authenticate as the GitHub app to list installations, repositories, and create installation access tokens.

name type description
type string Required. Must be either "app".

OAuth App authentication

Create, reset, refresh, delete OAuth user-to-server tokens

name type description
type string Required. Must be either "oauth-app".

Installation authentication

name type description
type string Required. Must be "installation".
installationId number Required unless a default installationId was passed to createAppAuth(). 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 a databaseID when querying the repository object in GitHub's GraphQL API. This option is **(recommended)** over repositoryNames when needing to limit the scope of the access token, due to repositoryNames having the possibility of changing. Additionally, you should only include either repositoryIds or repositoryNames, but not both.
repositoryNames array of strings The name of the repositories that the installation token can access. As mentioned in the repositoryIds description, you should only include either repositoryIds or repositoryNames, 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, see GitHub App permissions.
factory function

The auth({type: "installation", installationId, factory }) call with resolve with whatever the factory function returns. The factory function will be called with all the strategy option that auth was created with, plus the additional options passed to auth, besides type and factory.

For example, you can create a new auth instance for an installation which shares the internal state (especially the access token cache) with the calling auth instance:

const appAuth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
});

const installationAuth123 = await appAuth({
  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 installationId, set refresh to true.

Defaults to false.

User authentication (web flow)

Exchange code received from the web flow redirect described in step 2 of GitHub's OAuth web flow

name type description
type string Required. Must be "oauth-user".
factory function

The auth({type: "oauth-user", factory }) call with resolve with whatever the factory function returns. The factory function will be called with all the strategy option that auth was created with, plus the additional options passed to auth, besides type and factory.

For example, you can create a new auth instance for an installation which shares the internal state (especially the access token cache) with the calling auth instance:

const {
  createAppAuth,
  createOAuthUserAuth,
} = require("@octokit/auth-oauth-app");

const appAuth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef1234567890abcdef12345678",
});

const userAuth = await appAuth({
  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)
const authentication = await userAuth();
code string The authorization code which was passed as query parameter to the callback URL from the OAuth web application flow.
redirectUrl string The URL in your application where users are sent after authorization. See redirect urls.
state string The unguessable random string you provided in Step 1 of the OAuth web application flow.

User authentication (device flow)

Create a token using GitHub'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 onVerification() callback can be used to pause until the user completes step 2, which might result in a better user experience.

const auth = auth({
  type: "oauth-user",
  onVerification(verification) {
    console.log("Open %s", verification.verification_uri);
    console.log("Enter code: %s", verification.user_code);
    await prompt("press enter when you are ready to continue");
  },
});
factory function

The auth({type: "oauth-user", factory }) call with resolve with whatever the factory function returns. The factory function will be called with all the strategy option that auth was created with, plus the additional options passed to auth, besides type and factory.

For example, you can create a new auth instance for an installation which shares the internal state (especially the access token cache) with the calling auth instance:

const {
  createAppAuth,
  createOAuthUserAuth,
} = require("@octokit/auth-oauth-app");

const appAuth = createAppAuth({
  appId: 1,
  privateKey: "-----BEGIN PRIVATE KEY-----\n...",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef1234567890abcdef12345678",
});

const userAuth = await appAuth({
  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)
const authentication = await userAuth();

Authentication object

Depending on on the auth() call, the resulting authentication object can be one of

  1. JSON Web Token (JWT) authentication
  2. OAuth App authentication
  3. Installation access token authentication
  4. GitHub APP user authentication token with expiring disabled
  5. GitHub APP user authentication token with expiring enabled

JSON Web Token (JWT) authentication

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 using new Date(authentication.expiresAt).

OAuth App authentication

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 }.

Installation access token authentication

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 using new Date(authentication.expiresAt).
expiresAt string Timestamp in UTC format, e.g. "2018-07-07T00:59:00.000Z". A Date object can be created using new Date(authentication.expiresAt).
repositoryIds array of numbers Only present if repositoryIds option passed to auth(options).
repositoryNames array of strings Only present if repositoryNames option passed to auth(options).
permissions object An object where keys are the permission name and the value is either "read" or "write". See the list of all GitHub App Permissions.
singleFileName string If the single file permission is enabled, the singleFileName property is set to the path of the accessible file.

GitHub APP user authentication token with expiring disabled

name type description
type string "token"
tokenType string "oauth"
clientType string "github-app"
clientId string The app's Client ID
clientSecret string One of the app's client secrets
token string The user access token

GitHub APP user authentication token with expiring enabled

name type description
type string "token"
tokenType string "oauth"
clientType string "github-app"
clientId string The app's Client 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 in ISO 8601 standard. Example: 2022-01-01T08:00:0.000Z
refreshTokenExpiresAt string Date timestamp in ISO 8601 standard. Example: 2021-07-01T00:00:0.000Z

auth.hook(request, route, parameters) or auth.hook(request, options)

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.

The request option is an instance of @octokit/request. The arguments are the same as for the request() method.

auth.hook() can be called directly to send an authenticated request

const { data: installations } = await auth.hook(
  request,
  "GET /app/installations"
);

Or it can be passed as option to request().

const requestWithAuth = request.defaults({
  request: {
    hook: auth.hook,
  },
});

const { data: installations } = await requestWithAuth("GET /app/installations");

Note that auth.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 with client_id and client_secret, you can just retrieve the token and then create a new instance of request() with the authentication header set:

const { token } = await auth({
  type: "oauth-user",
  code: "123456",
});
const requestWithAuth = request.defaults({
  headers: {
    authentication: `token ${token}`,
  },
});

Types

import {
  // strategy options
  StrategyOptions,
  // auth options
  AuthOptions,
  AppAuthOptions,
  OAuthAppAuthOptions,
  InstallationAuthOptions,
  OAuthWebFlowAuthOptions,
  OAuthDeviceFlowAuthOptions,
  // authentication objects
  Authentication,
  AppAuthentication,
  OAuthAppAuthentication,
  InstallationAccessTokenAuthentication,
  GitHubAppUserAuthentication,
  GitHubAppUserAuthenticationWithExpiration,
} from "@octokit/auth-app";

Implementation details

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.

License

MIT

More Repositories

1

octokit.js

The all-batteries-included GitHub SDK for Browsers, Node.js, and Deno.
TypeScript
6,695
star
2

octokit.rb

Ruby toolkit for the GitHub API
Ruby
3,818
star
3

octokit.net

A GitHub API client library for .NET
C#
2,591
star
4

octokit.objc

GitHub API client for Objective-C
Objective-C
1,841
star
5

core.js

Extendable client for GitHub's REST & GraphQL APIs
TypeScript
1,145
star
6

rest.js

GitHub REST API client for JavaScript
JavaScript
503
star
7

graphql.js

GitHub GraphQL API client for browsers and Node
TypeScript
446
star
8

request-action

A GitHub Action to send arbitrary requests to GitHub's REST API
JavaScript
350
star
9

authentication-strategies.js

GitHub API authentication strategies for Browsers, Node.js, and Deno
320
star
10

webhooks.js

GitHub webhook events toolset for Node.js
TypeScript
296
star
11

go-octokit

Simple Go wrapper for the GitHub API
Go
257
star
12

request.js

Send parameterized requests to GitHub’s APIs with sensible defaults in browsers and Node
TypeScript
223
star
13

webhooks

machine-readable, always up-to-date GitHub Webhooks specifications
TypeScript
202
star
14

action.js

GitHub API client for GitHub Actions
TypeScript
173
star
15

graphql-schema

GitHub’s GraphQL Schema with validation. Automatically updated.
JavaScript
170
star
16

app.js

GitHub Apps toolset for Node.js
TypeScript
149
star
17

octokit.graphql.net

A GitHub GraphQL client library for .NET
C#
140
star
18

graphql-action

A GitHub Action to send queries to GitHub's GraphQL API
JavaScript
114
star
19

types.ts

Shared TypeScript definitions for Octokit projects
TypeScript
113
star
20

plugin-throttling.js

Octokit plugin for GitHub’s recommended request throttling
TypeScript
100
star
21

plugin-rest-endpoint-methods.js

Octokit plugin adding one method for all of api.github.com REST API endpoints
TypeScript
100
star
22

fixtures

Fixtures for all the octokittens
JavaScript
98
star
23

auth-token.js

GitHub API token authentication for browsers and Node.js
TypeScript
94
star
24

routes

machine-readable, always up-to-date GitHub REST API route specifications
JavaScript
84
star
25

oauth-app.js

GitHub OAuth toolset for Node.js
TypeScript
74
star
26

auth-oauth-app.js

GitHub OAuth App authentication for JavaScript
TypeScript
64
star
27

endpoint.js

Turns REST API endpoints into generic request options
TypeScript
54
star
28

go-sdk

A generated Go SDK from GitHub's OpenAPI specification.
Go
51
star
29

webhooks.net

GitHub webhook events toolset for .NET
C#
46
star
30

plugin-paginate-rest.js

Octokit plugin to paginate REST API endpoint responses
TypeScript
45
star
31

dotnet-sdk

C#
43
star
32

octopoller.rb

A micro gem for polling and retrying. Perfect for making repeating requests.
Ruby
43
star
33

auth-action.js

GitHub API token authentication for GitHub Actions
TypeScript
38
star
34

openapi

GitHub's official OpenAPI spec with Octokit extensions
JavaScript
38
star
35

openapi-types.ts

Generated TypeScript definitions based on GitHub's OpenAPI spec
JavaScript
37
star
36

plugin-paginate-graphql.js

Octokit plugin to paginate GraphQL Query responses
TypeScript
31
star
37

plugin-retry.js

Octokit plugin for GitHub’s recommended request retries
TypeScript
29
star
38

fixtures-server

Fixtures server for browser & language agnositic octokit testing
JavaScript
26
star
39

webhooks-methods.js

Methods to handle GitHub Webhook requests
TypeScript
20
star
40

plugin-enterprise-server.js

Octokit plugin for GitHub Enterprise REST APIs
TypeScript
19
star
41

octokit-next.js

JavaScript
18
star
42

oauth-authorization-url.js

Universal library to retrieve GitHub’s identity URL for the OAuth web flow
TypeScript
16
star
43

auth-oauth-user-client.js

OAuth user authentication without exposing client secret
15
star
44

create-octokit-project.js

"npm init" script to create a new Octokit JS module
JavaScript
15
star
45

auth-oauth-user.js

Octokit authentication strategy for OAuth clients
TypeScript
15
star
46

plugin-create-or-update-text-file.js

Convenience method to create/edit/delete a text file based on its current content
TypeScript
13
star
47

app-permissions

machine-readable, always up-to-date GitHub App permissions
JavaScript
10
star
48

auth-oauth-device.js

GitHub OAuth Device authentication strategy for JavaScript
TypeScript
10
star
49

request-error.js

Error class for Octokit request errors
TypeScript
9
star
50

handbook

Handbook for Octokit maintainers and GitHub integrators
9
star
51

auth-basic.js

GitHub API Basic authentication for browsers and Node.js
TypeScript
8
star
52

.github

7
star
53

discussions

discussions and planning for Octokit clients
7
star
54

plugin-request-log.js

Log all requests and request errors
TypeScript
7
star
55

source-generator

Go
6
star
56

plugin-enterprise-cloud.js

Octokit plugin for GitHub Enterprise Cloud REST APIs
TypeScript
6
star
57

tsconfig

TypeScript configuration for Octokit packages
JavaScript
5
star
58

oauth-methods.js

Request methods to create and refresh user access tokens for OAuth and GitHub Apps
TypeScript
4
star
59

auth-callback.js

GitHub API authentication using a callback method
TypeScript
4
star
60

auth-unauthenticated.js

strategy for explicitly unauthenticated Octokit instances
TypeScript
4
star
61

tf-acc-test-empty-f89p1

Terraform acceptance test f89p1
2
star
62

plugin-enterprise-compatibility.js

Octokit plugin for improving GHE compatibility
TypeScript
1
star
63

openapi-webhooks

JavaScript
1
star