auth-app.js: Using with @octokit/graphql & GHES fails with 406

This is similar to #47, but when using createAppAuth.

We have some code that looks like this:

const { createAppAuth } = require('@octokit/auth-app');
const { graphql } = require('@octokit/graphql');
const { request } = require('@octokit/request');

function graphqlForInstallation(installationId) {
  const auth = createAppAuth({
    id: GITHUB_APP_ISSUER_ID,
    privateKey: PEM,
    installationId,
    request: request.defaults({
      baseUrl: `${GITHUB_BASE_URL}/api/v3`,
    }),
  });
  const graphqlWithAuth = graphql.defaults({
    baseUrl: GITHUB_BASE_URL,
    request: {
      hook: auth.hook,
    },
  });
  return graphqlWithAuth;
}

When this is used with public GitHub it works okay. However, when it is used with GHE v2.18 (specifically tried with 2.18.20), we get an error with the following stack trace (partial, starting at @octokit/auth-app code):

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at set (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:65:63)
    at getInstallationAuthentication (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:161:9)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async hook (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:280:7)

I looked into applying the workaround mentioned in #47, but after reading through some of the code here, I think that may not be possible at this time.

Looking at the stack trace, the problem seems to be when octokit is getting installation authentication via the request auth hook

    at getInstallationAuthentication (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:161:9)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async hook (/usr/src/app/node_modules/@octokit/auth-app/dist-node/index.js:280:7)

I believe that is called right here: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/hook.ts#L32

This is calling getInstallationAuthentication with {} as the second argument. Here’s the signature: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/get-installation-authentication.ts#L11-L15

The second argument here is options, which is where it pulls permissions when making the request: https://github.com/octokit/auth-app.js/blob/71e1d1d8a2672686464a9399655bcd8872da6e58/src/get-installation-authentication.ts#L58-L61

So since createAppAuth or the hook do not provide a way for us to specify this permissions option, I don’t think we can use this workaround with createAppAuth.

Is there an alternative approach we could use here, or would you be open to making a change to this package to make this work?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (17 by maintainers)

Most upvoted comments

@gr2m Yep, that works! Here’s my diff:

 diff --git a/ghe.js b/ghe.js
index 06a915b..78763ea 100644
--- a/ghe.js
+++ b/ghe.js
@@ -14,13 +14,10 @@ function graphqlForInstallation(installationId) {
     id: GITHUB_APP_ISSUER_ID,
     privateKey: PEM,
     installationId,
-    request: request.defaults({
-      baseUrl: `${GITHUB_BASE_URL}/api/v3`,
-    }),
   });
 
   const graphqlWithAuth = graphql.defaults({
-    baseUrl: `${GITHUB_BASE_URL}/api`,
+    baseUrl: `${GITHUB_BASE_URL}/api/v3`,
     request: {
       hook: auth.hook,
     },
diff --git a/package-lock.json b/package-lock.json
index 4bb03c0..65b523a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -37,6 +37,18 @@
         "@octokit/types": "^5.0.0",
         "before-after-hook": "^2.1.0",
         "universal-user-agent": "^6.0.0"
+      },
+      "dependencies": {
+        "@octokit/graphql": {
+          "version": "4.5.4",
+          "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.4.tgz",
+          "integrity": "sha512-ITpZ+dQc0cXAW1FmDkHJJM+8Lb6anUnin0VB5hLBilnYVdLC0ICFU/KIvT7OXfW9S81DE3U4Vx2EypDG1OYaPA==",
+          "requires": {
+            "@octokit/request": "^5.3.0",
+            "@octokit/types": "^5.0.0",
+            "universal-user-agent": "^6.0.0"
+          }
+        }
       }
     },
     "@octokit/endpoint": {
@@ -50,9 +62,8 @@
       }
     },
     "@octokit/graphql": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.3.tgz",
-      "integrity": "sha512-JyYvi3j2tOb5ofASEpcg1Advs07H+Ag+I+ez7buuZfNVAmh1IYcDTuxd4gnYH8S2PSGu+f5IdDGxMmkK+5zsdA==",
+      "version": "https://github.pika.dev/octokit/graphql.js/pr/186",
+      "integrity": "sha512-hUPAXu5w3+rcJ0AjzuGgoQNhYh5QYygRdxvDAP4Nhu/5t/I3dsjaywuapY6sEsjno+O3ObYzUNDzcr0w4FKGxQ==",
       "requires": {
         "@octokit/request": "^5.3.0",
         "@octokit/types": "^5.0.0",
diff --git a/package.json b/package.json
index 838756e..86a1197 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
   "license": "ISC",
   "dependencies": {
     "@octokit/auth-app": "^2.4.14",
-    "@octokit/graphql": "^4.5.3",
+    "@octokit/graphql": "https://github.pika.dev/octokit/graphql.js/pr/186",
     "@octokit/request": "^5.4.7",
     "@octokit/rest": "^18.0.3",
     "jsonwebtoken": "^8.5.1"

Apologies for not getting back to you. I’m looking into it right now

We have now updated GHE to 2.20.14, and I just wanted to report that the behavior is the same as I observed with 2.20.12.

We’ve recently updated GHE to 2.20.12 and I tried this stuff again and I’m seeing similar behavior.

  • Fresh install of required packages: 406 error
  • Only change {} to { permissions: {} } in @octokit/auth-app/dist-node/index.js line 288: 406 error
  • Only add requestOptions.url = requestOptions.url.replace('/api/app/installations/', '/api/v3/app/installations/'); to the fetchWrapper function in @octokit/request/dist-node/index.js (line 28): Successful request

So it seems that the newer version of GHE no longer needs the empty permissions object, but the URLs are still not able to be set correctly to get through a GraphQL request that also ends up making a REST request for authentication, since it tries to POST to /api/app/installations/<APP ISSUER ID>/access_tokens instead of /api/v3/app/installations/<APP ISSUER ID>/access_tokens.

I did not have time to look into this yet. I will keep you posted.

I think we’re going to try the same thing with github enterprise before we put together a PR (@lencioni and I).