universal-github-app-jwt
Calculate GitHub App bearer tokens for Node & modern browsers
⚠ The private keys provide by GitHub are in PKCS#1 format, but the WebCrypto API only supports PKCS#8. You can see the difference in the first line, PKCS#1 format starts with -----BEGIN RSA PRIVATE KEY----- while PKCS#8 starts with -----BEGIN PRIVATE KEY-----. You can convert one format to the other using oppenssl:
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private-key.pem -out private-key-pkcs8.key
It's also possible to convert the formats with JavaScript, e.g. using node-rsa, but it turns a 4kb to a 200kb+ built. I'm looking for help to create a minimal PKCS#1 to PKCS#8 convert library that I can recommend people to use before passing the private key to githubAppJwt. Please create an issue if you'd like to help.
The way it works with node-rsa is this
const PRIVATE_KEY = `-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----`;
const key = new NodeRSA(PRIVATE_KEY);
const privateKeyPkcs8 = key.exportKey("pkcs8-private-pem");
// privateKeyPkcs8 is now
// -----BEGIN PRIVATE KEY-----
// ...
// -----END PRIVATE KEY-----
When using a node, a conversion is not necessary, the implementation is agnostic to either format.
Usage
| Browsers | Load   | 
|---|---|
| Node | Install with   | 
(async () => {
  const { token, appId, expiration } = await githubAppJwt({
    id: APP_ID,
    privateKey: PRIVATE_KEY,
  });
})();
The retrieved token can now be used in Authorization request header, e.g. with @octokit/request:
request("GET /app", {
  headers: {
    authorization: `bearer ${token}`,
  },
});
For a complete implementation of GitHub App authentication strategies, see @octokit/auth-app.js.
githubAppJwt(options)
| name | type | description | 
|---|---|---|
| options.id | number | Required. Find App ID on the app’s about page in settings. | 
| options.privateKey | string | Required. Content of the *.pemfile you downloaded from the app’s about page. You can generate a new private key if needed. Make sure to preserve the line breaks. | 
githubAppJwt(options) resolves with an object with the following keys
| name | type | description | 
|---|---|---|
| token | string | The JSON Web Token (JWT) to authenticate as the app. | 
| appId | number | The GitHub App database ID passed in options.id. | 
| expiration | number | Timestamp as UNIX epoch, e.g. 1530922170. A Date object can be created usingnew Date(authentication.expiration). | 
