# universal-github-app-jwt > Calculate GitHub App bearer tokens for Node & modern browsers [![@latest](https://img.shields.io/npm/v/universal-github-app-jwt.svg)](https://www.npmjs.com/package/universal-github-app-jwt) ![Build status](https://github.com/gr2m/universal-github-app-jwt/workflows/Test/badge.svg) [![Greenkeeper](https://badges.greenkeeper.io/gr2m/universal-github-app-jwt.svg)](https://greenkeeper.io/) ⚠ 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](https://github.com/rzcoder/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 ```js 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 `universal-github-app-jwt` directly from [cdn.pika.dev](https://cdn.pika.dev) ```html ```
Node Install with npm install universal-github-app-jwt ```js const { githubAppJwt } = require("universal-github-app-jwt"); // or: import { githubAppJwt } from "universal-github-app-jwt"; ```
```js (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`](https://github.com/octokit/request.js/#readme): ```js request("GET /app", { headers: { authorization: `bearer ${token}`, }, }); ``` For a complete implementation of GitHub App authentication strategies, see [`@octokit/auth-app.js`](https://github.com/octokit/auth-app.js/#readme). ## `githubAppJwt(options)`
name type description
options.id number | string Required. The GitHub App's ID or Client ID. For github.com and GHES 3.14+, it is recommended to use the Client ID.
options.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. 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 or Client ID passed in options.id.
expiration number Timestamp as UNIX epoch, e.g. 1530922170. A Date object can be created using new Date(authentication.expiration).
## License [MIT](LICENSE)