Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A JSON web token could not be decoded error when running action #153

Open
avsaase opened this issue Jul 4, 2024 · 14 comments
Open

A JSON web token could not be decoded error when running action #153

avsaase opened this issue Jul 4, 2024 · 14 comments

Comments

@avsaase
Copy link

avsaase commented Jul 4, 2024

Hi, I get this error when running the action:

Run actions/create-github-app-token@v1
  with:
    app-id: ***
    private-key: ***
    github-api-url: https://api.github.com/
owner and repositories not set, creating token for the current repository ("fusion-imu")
Failed to create token for "fusion-imu" (attempt 1): A JSON web token could not be decoded - https://docs.github.com/rest
Failed to create token for "fusion-imu" (attempt 2): A JSON web token could not be decoded - https://docs.github.com/rest
Failed to create token for "fusion-imu" (attempt 3): A JSON web token could not be decoded - https://docs.github.com/rest
Failed to create token for "fusion-imu" (attempt 4): A JSON web token could not be decoded - https://docs.github.com/rest
RequestError [HttpError]: A JSON web token could not be decoded - https://docs.github.com/rest
    at /home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:37050:21
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async hook4 (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39454:18)
    at async getTokenFromRepository (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39768:20)
    at async RetryOperation._fn (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39645:24) {
  status: 401,
  request: {
    method: 'GET',
    url: 'https://api.github.com/repos/avsaase/fusion-imu/installation',
    headers: {
      accept: 'application/vnd.github.v3+json',
      'user-agent': 'actions/create-github-app-token',
      authorization: 'bearer [REDACTED]'
    },
    request: { hook: [Function: bound hook4] AsyncFunction }
Error: A JSON web token could not be decoded - https://docs.github.com/rest
  },
  response: {
    url: 'https://api.github.com/repos/avsaase/fusion-imu/installation',
    status: 401,
    headers: {
      'access-control-allow-origin': '*',
      'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
      'content-length': '117',
      'content-security-policy': "default-src 'none'",
      'content-type': 'application/json; charset=utf-8',
      date: 'Wed, 03 Jul 2024 22:33:58 GMT',
      'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
      server: 'github.com',
      'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
      vary: 'Accept-Encoding, Accept, X-Requested-With',
      'x-content-type-options': 'nosniff',
      'x-frame-options': 'deny',
      'x-github-media-type': 'github.v3; format=json',
      'x-github-request-id': 'E906:311D5D:2A7971:4ADA68:6685D1D2',
      'x-xss-protection': '0'
    },
    data: {
      message: 'A JSON web token could not be decoded',
      documentation_url: 'https://docs.github.com/rest',
      status: '401'
    }
  },
  attemptNumber: 4,
  retriesLeft: 0
}

In my workflow file I have

- name: Generate GitHub token
  uses: actions/create-github-app-token@v1
  id: generate-token
  with:
    app-id: ${{ secrets.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}

(full workflow file)

The corresponding app id and private key are set as secrets in my repository. The private key is copy-pasted directly from the .pem file that downloads when creating a private key.

The app is installed
image

Did I do something wrong or is this a bug? Thanks.

@gr2m
Copy link
Contributor

gr2m commented Jul 5, 2024

The error is not very helpful, but it usually means that the private key is somehow not formatted correctly or invalid.

@gr2m gr2m closed this as completed Jul 5, 2024
@gr2m gr2m reopened this Jul 5, 2024
@avsaase
Copy link
Author

avsaase commented Jul 5, 2024

What is the correct format? I tried both with and without the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- lines but with no success,

@avsaase
Copy link
Author

avsaase commented Jul 5, 2024

I just tried it again with those line removed and then the output becomes:

Failed to create token for "fusion-imu" (attempt 2): Invalid keyData
Failed to create token for "fusion-imu" (attempt 3): Invalid keyData
Failed to create token for "fusion-imu" (attempt 4): Invalid keyData
DOMException [DataError]: Invalid keyData
    at Object.rsaImportKey (node:internal/crypto/rsa:235:15)
    at SubtleCrypto.importKey (node:internal/crypto/webcrypto:615:10)
    ... 6 lines matching cause stack trace ...
    at /home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39717:71
Error: Invalid keyData
    at RetryOperation._fn (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39645:30) {
  attemptNumber: 4,
  retriesLeft: 0,
  [cause]: Error: error:0680007B:asn1 encoding routines::header too long
      at createPrivateKey (node:internal/crypto/keys:632:12)
      at Object.rsaImportKey (node:internal/crypto/rsa:229:21)
      at SubtleCrypto.importKey (node:internal/crypto/webcrypto:615:10)
      at getToken (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:37839:56)
      at githubAppJwt (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:37872:23)
      at getAppAuthentication (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39166:37)
      at hook4 (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39450:37)
      at newApi (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:37130:36)
      at getTokenFromRepository (/home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39768:26)
      at /home/runner/work/_actions/actions/create-github-app-token/v1/dist/main.cjs:39717:71 {
    library: 'asn1 encoding routines',
    reason: 'header too long',
    code: 'ERR_OSSL_ASN1_HEADER_TOO_LONG'
  }
}

@gr2m
Copy link
Contributor

gr2m commented Jul 8, 2024

Can you please try to convert PKCS#1 (the current format that GitHub exports) to PKCS#8 and see if that helps?
I documented 3 options to do that here: https://github.com/gr2m/universal-github-app-jwt/?tab=readme-ov-file#converting-pkcs1-to-pkcs8

The PKCS8 key start with -----BEGIN PRIVATE KEY-----. Make sure to leave that line as well as the ending line in when setting it as a repository secret

@avsaase
Copy link
Author

avsaase commented Jul 9, 2024

I needed a quick fix so I switched to another action to generate a token. I haven't tried converting the private key yet but I'll give it a try this week. You are of course welcome to try it yourself.

@hmennen90
Copy link

Can you please try to convert PKCS#1 (the current format that GitHub exports) to PKCS#8 and see if that helps? I documented 3 options to do that here: https://github.com/gr2m/universal-github-app-jwt/?tab=readme-ov-file#converting-pkcs1-to-pkcs8

The PKCS8 key start with -----BEGIN PRIVATE KEY-----. Make sure to leave that line as well as the ending line in when setting it as a repository secret

This does not work for me :-(

@drmmarsunited
Copy link

The conversion didn't work for me either. Upon initial conversion, it was unhappy with line break characters, trying to strip them results in an invalid keyData error.

@drmmarsunited
Copy link

Clarifying my last response now. Using the OpenSSL method of converting the key, it is now being accepted by this action.

However, this feels like a bit of a poor user experience to issue the key(s) one way but have your own vendor provided action expect them in a different format.

@parkerbxyz
Copy link
Contributor

We have tried to reproduce this error and have not been able to so far. Can somebody experiencing this please invalidate the private key that is not working for you and then provide it to us for closer inspection?

@SafeEval
Copy link

SafeEval commented Aug 2, 2024

Found this issue because we're having the same problem.

Here is an invalidated key that isn't working when set as a Github Actions secret and fed to this action, including the trailing newline.

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxi42aN8myTUNsEujDIpm6a17/mxaWYAw333JISOG7BQbk4bI
nUvU0PBbRelJxRY+THiA9I1TOZvFYmzISTmgvDB9KOoVR8rWoJeQD4Y+X1agzvsS
S2sGoVvzkEIaVcRttJxbHstpbzcFzhYzKTGWHu5poiOmVWTvwMJd0SC6V/ZY9ALo
tvwllJlI+NmDyUhbpMjz2nTaBvBKCbShqnfyvChdULdZXWO/eEQsRPqTdGOi1TZw
3ZuZ6XAXRFCyrTBXYSU/n95+5qJ4UGkn0+m34mw1+VELFTf1g11HelcC4g/cQM7v
L0t06FlHIzYi6mG2gDnOH6ildlxWCm1ILMGLeQIDAQABAoIBABhWNHhMbwbmbPfp
UeyIUnr/wupLhAzZoSbQ25ImOrti/L/xHVGzrj66RXsgWt7JDH13jt55PG8moeak
VTQoz4RMsBIGLPbUAedWtWoyohYzHSxNyMFaM0Y9dHuSoolFxfMYAFiXwirWJvBX
6ZB1dmn1/SLcHeD+tDKHq92yly+V6aComV5qJ9JGkceqJ+kbtzhCjM1quXo6ZoJh
jlvwzro2/N+u/WMzE5hcH6CV1Sc359kxXhHgkTtwoIWx+4AV49/hFqLyc1UmeqmC
yBoR5Hs0NO0BGYn2Yy34r/sqBlrfUGu2rB2Nr+bnKSi5x+tvG7QfqH+dnEhVbLeK
YhTkPwECgYEA5n+j6o7yPl/2iqxYrUrO7frGz3OASIICVfW5xt7zmo4yCp1e4KRX
gfwN5NUO6u06u9oqyRetByEiPro7fLCRv8MjlcGRKMF8Sd840t0yjlJ5rzQUgpyt
hiag5qaDmk91WEeHurskZH0e24wKIviiifylY7gpQcPfO83IptfNLuUCgYEA3Bs8
EMOqBdscwu9+0MqzcBUV1H+nf4xwuqtjrI984T6TXKrTOIaludAydl1sv4Y8RZwW
nwSTX4GAXCfGy40ds+9HsN2BDJ11EvWYnVWSDivq41wzrEERZY255gyCcA0UTay1
5/oz3mVntusN85BQgWe8OIz3H08wmZHrk50GDQUCgYEAxjY7GgikzfitxSBh/VtY
SROfBWQ4i6GpKoxtnlO5Pk5LQA+GOD16tt+ufvqsol8wY7w/kL/YXkoi7bguUZJx
M2s2XaCgGGESZWAcuE/ZGsRXuc9aV9st6S+sq8vDXd44dZrFYFFwAS4LbBan3Nzc
wTZOb0s9xz0N6ZqTks3+tvUCgYEAlBVOqAi8DwyHoS74Jwj5CGNnOHxZ+JpIDY7Z
lHNFFVXAVwwm51TPkt/b036vd3uceUi2f23YqNy7u0SXnsLmRPSrSvb7p70X0xWh
A9laVmZ9tVGHAlEUnzpm47tu1mw2SLv19oiC9RFMYehqjn99alKcc3+Dk3D3xZpC
4CE4vPECgYEAsgroShv94iuGIrSGeOytp0H3ZeDaE75YodcEfXYGXXbsqLZyr8q5
oX7zvpc3kLgp7mfCcGg4vQCz0HpOW2i9miJoEe9xbNrQvG1MXmqFM520BNumu+cF
Db0sk6yn3104hgLmfUzdJ1CQZTlnEz9KvYdmwCYVy4HzB38qqLZBTNo=
-----END RSA PRIVATE KEY-----

Converting it to PKCS#8 with OpenSSL did not work.

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
  -in app.2024-08-02.private-key.pem \
  -out app.2024-08-02.private-key-pkcs8.pem

@SafeEval
Copy link

SafeEval commented Aug 2, 2024

In our case this error happened because there were repo-level Github Actions values that were overriding the org-level values, so rotating a private key at the org-level had no effect. The key exported directly from Github works with this action now.

@parkerbxyz
Copy link
Contributor

parkerbxyz commented Aug 8, 2024

I think we've figured out what's going on here!

We were able to reproduce this error by providing a valid app ID and a private key that do not match. Please double-check that you are using the correct app ID and a valid private key that belongs to that app.

We'd like to make the error more helpful for those that encounter this error in the future. Pull requests welcome! See octokit/auth-app.js#375 for more information.

@MPV
Copy link

MPV commented Oct 7, 2024

We were able to reproduce this error by providing a valid app ID and a private key that do not match. Please double-check that you are using the correct app ID and a valid private key that belongs to that app.

I came here to say I ran into this myself, where I had accidentally set the "installation ID" as the "app ID", and amending that fixed it. 🙈

@kevinwright
Copy link

kevinwright commented Nov 28, 2024

In my case I was calling the "GET /app/installations/${installation_id}" endpoint, and converting from PKCS#1 to PKCS#8 was the solution.

That said... I've been successfully calling other endpoints with the PCKS#1 certificate without problem, and I find the inconsistency of this behaviour to be absolutely staggering. If GitHub wants to move to PCKS#8 as the default then might I suggest that they actually RETURN A CERTIFICATE IN THAT FORMAT when we generate one?

Conversion is not always readily accessible. For example, there are "serverless" cloud hosting providers that use a javascript engine without access to the full node.js crypt functionality, meaning that conversion requires a third party library that - as far as I can tell - simply doesn't exist, and of course openssl simply isn't available in that environment. If you should want to install multiple apps via manifests and don't have just the one (for which manual key conversion is less painful) then this starts to become a MAJOR issue.

@gr2m listed three conversion options, none of which are suitable

  • Using an Online Private Key Converter (in an automated scenario? Could this be less secure?)
  • Using Node.js (See above, not always available)
  • Using OpenSSL (See above, not always available)

GitHub needs to do better. Much Much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants