-
Notifications
You must be signed in to change notification settings - Fork 51
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
[BUG]: secretOrPrivateKey must be an asymmetric key when using RS256 #465
Comments
Can you share your node and npm versions? There seems to be recurring issues with private keys, see also #450 |
I generated another private key using the UI and it still doesn't work. I'll try different node versions and see what happens. |
Oh wow, changing to Node 19 fixes the problem! |
I would still like to get to the bottom of why it isn't working on earlier versions of Node as we still support them. |
Same issue with vercel serverless function using node 18. Has there been any updates on this issue? |
Getting the same issue in Vercel's production environment when using serverless functions. The private key works and is authenticated in the dev environment, but I get the "secretOrPrivateKey must be an asymmetric key when using RS256" error when in production. I tried changing to Node 14, 16, and 18 and get the same error in all of them. Vercel doesn't have Node 19 as a possible runtime. I also tried regenerating the private key, triple-checked its formatted correctly, and checked my authentication against Octokit docs to make sure it's structured correctly and I'm still getting the error. Any updates on why this is happening or a possible fix? Thanks! |
We fixed this error for us
|
So we have two fixes for the error (depending on the context it appears):
For reference, in the original post here I mentioned I removed all whitespace (which includes all newlines), and it still didn't work until I changed Node versions. |
Can confirm that it didn't work for me on node 16, and upgrading to node 19 somehow fixes the issue. Didn't change anything about the downloaded certificate. Code used to initialize the service is:
|
I'm guessing the key file we get from Github somehow cannot be parsed to a https://github.com/auth0/node-jsonwebtoken/blob/master/sign.js#L124 Edit: Downgrading back to node 16 does not break it again. Now it's happily working with node 16 as well. |
We can probably add this line .replace(/\\n/g, '\n') if that fixes the problem across all supported Node version. If the fix works, we should probably add it to the lower-level library we use: https://github.com/gr2m/universal-github-app-jwt |
Node |
Can you please see check if
Alternatively if anyone could create a reproducible test case that would be very helpful. You can directly share the private key but make sure to invalidate it in your app. |
@gr2m How to test with that repo? Do you have any instructions? I tested with my github private key and appId and it returns an object, but I don't know if it is the correct way: (async function () {
const res = await githubAppJwt({
id: 339380,
privateKey: privateKey,
});
console.log(res);
})(); console output:
$ node index.js |
Thanks, that seems to be working ... 🤔 If someone could provide a working code example that reproduces the error, that would be great. something like this const auth = createAppAuth({
appId: 1,
privateKey: "-----BEGIN PRIVATE KEY-----\n...",
});
auth({ type: "app" }).then(() => console.log("ok"), (error) => console.log(error)) That throws the |
I figured out what is the problem. The problem is coming from loading environment variables in Working scenario: const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA280nfuUM9w00Ib9E2rvZJ6Qu3Ua3IqR34ZlK53vn/Iobn2EL
Z9puc5Q/nFBU15NKwHyQNb+OG2hTCkjd1Xi9XPzEOH1r42YQmTGq8YCkUSkk6KZA
5dnhLwN9pFquT9fQgrf4r1D5GJj3rqvj8JDr1sBmunArqY5u4gziSrIohcjLIZV0
cIMz/RUIMe/EAsNeiwzEteHAtf/WpMs+OfF94SIUrDlkPr0H0H3DER8l1HZAvE0e
eD3ZJ6njrF6UHQWDVrekSTB0clpVTTU9TMpe+gs2nnFww9G8As+WsW8xHVjVipJy
AwqBhiR+s7wlcbh2i0NQqt8GL9/jIFTmleiwsQIDAQABAoIBAHNyP8pgl/yyzKzk
/0871wUBMTQ7zji91dGCaFtJM0HrcDK4D/uOOPEv7nE1qDpKPLr5Me1pHUS7+NGw
EAPtlNhgUtew2JfppdIwyi5qeOPADoi7ud6AH8xHsxg+IMwC+JuP8WhzyUHoJj9y
PRi/pX94Mvy9qdE25HqKddjx1mLdaHhxqPkr16/em23uYZqm1lORsCPD3vTlthj7
WiEbBSqmpYvjj8iFP4yFk2N+LvuWgSilRzq1Af3qE7PUp4xhjmcOPs78Sag1T7nl
ww/pgqCegISABHik7j++/5T+UlI5cLsyp/XENU9zAd4kCIczwNKpun2bn+djJdft
ravyX4ECgYEA+k2mHfi1zwKF3wT+cJbf30+uXrJczK2yZ33//4RKnhBaq7nSbQAI
nhWz2JESBK0TEo0+L7yYYq3HnT9vcES5R1NxzruH9wXgxssSx3JUj6w1raXYPh3B
+1XpYQsa6/bo2LmBELEx47F8FQbNgD5dmTJ4jBrf6MV4rRh9h6Bs7UkCgYEA4M3K
eAw52c2MNMIxH/LxdOQtEBq5GMu3AQC8I64DSSRrAoiypfEgyTV6S4gWJ5TKgYfD
zclnOVJF+tITe3neO9wHoZp8iCjCnoijcT6p2cJ4IaW68LEHPOokWBk0EpLjF4p2
7sFi9+lUpXYXfCN7aMJ77QpGzB7dNsBf0KUxMCkCgYEAjw/mjGbk82bLwUaHby6s
0mQmk7V6WPpGZ+Sadx7TzzglutVAslA8nK5m1rdEBywtJINaMcqnhm8xEm15cj+1
blEBUVnaQpQ3fyf+mcR9FIknPRL3X7l+b/sQowjH4GqFd6m/XR0KGMwO0a3Lsyry
MGeqgtmxdMe5S6YdyXEmERECgYAgQsgklDSVIh9Vzux31kh6auhgoEUh3tJDbZSS
Vj2YeIZ21aE1mTYISglj34K2aW7qSc56sMWEf18VkKJFHQccdgYOVfo7HAZZ8+fo
r4J2gqb0xTDfq7gLMNrIXc2QQM4gKbnJp60JQM3p9NmH8huavBZGvSvNzTwXyGG3
so0tiQKBgGQXZaxaXhYUcxYHuCkQ3V4Vsj3ezlM92xXlP32SGFm3KgFhYy9kATxw
Cax1ytZzvlrKLQyQFVK1COs2rHt7W4cJ7op7C8zXfsigXCiejnS664oAuX8sQZID
x3WQZRiXlWejSMUAHuMwXrhGlltF3lw83+xAjnqsVp75kGS6OH61
-----END RSA PRIVATE KEY-----`;
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: process.env.GITHUB_APP_ID,
privateKey: privateKey,
installationId: process.env.GITHUB_CLIENT_ID,
},
}); All solutions that loads the private key content from environment variable is not worked for me, the problem is environment variable is not loaded with the actual content of the variable: GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA280nfuUM9w00Ib9E2rvZJ6Qu3Ua3IqR34ZlK53vn/Iobn2EL
Z9puc5Q/nFBU15NKwHyQNb+OG2hTCkjd1Xi9XPzEOH1r42YQmTGq8YCkUSkk6KZA
5dnhLwN9pFquT9fQgrf4r1D5GJj3rqvj8JDr1sBmunArqY5u4gziSrIohcjLIZV0
cIMz/RUIMe/EAsNeiwzEteHAtf/WpMs+OfF94SIUrDlkPr0H0H3DER8l1HZAvE0e
eD3ZJ6njrF6UHQWDVrekSTB0clpVTTU9TMpe+gs2nnFww9G8As+WsW8xHVjVipJy
AwqBhiR+s7wlcbh2i0NQqt8GL9/jIFTmleiwsQIDAQABAoIBAHNyP8pgl/yyzKzk
/0871wUBMTQ7zji91dGCaFtJM0HrcDK4D/uOOPEv7nE1qDpKPLr5Me1pHUS7+NGw
EAPtlNhgUtew2JfppdIwyi5qeOPADoi7ud6AH8xHsxg+IMwC+JuP8WhzyUHoJj9y
PRi/pX94Mvy9qdE25HqKddjx1mLdaHhxqPkr16/em23uYZqm1lORsCPD3vTlthj7
WiEbBSqmpYvjj8iFP4yFk2N+LvuWgSilRzq1Af3qE7PUp4xhjmcOPs78Sag1T7nl
ww/pgqCegISABHik7j++/5T+UlI5cLsyp/XENU9zAd4kCIczwNKpun2bn+djJdft
ravyX4ECgYEA+k2mHfi1zwKF3wT+cJbf30+uXrJczK2yZ33//4RKnhBaq7nSbQAI
nhWz2JESBK0TEo0+L7yYYq3HnT9vcES5R1NxzruH9wXgxssSx3JUj6w1raXYPh3B
+1XpYQsa6/bo2LmBELEx47F8FQbNgD5dmTJ4jBrf6MV4rRh9h6Bs7UkCgYEA4M3K
eAw52c2MNMIxH/LxdOQtEBq5GMu3AQC8I64DSSRrAoiypfEgyTV6S4gWJ5TKgYfD
zclnOVJF+tITe3neO9wHoZp8iCjCnoijcT6p2cJ4IaW68LEHPOokWBk0EpLjF4p2
7sFi9+lUpXYXfCN7aMJ77QpGzB7dNsBf0KUxMCkCgYEAjw/mjGbk82bLwUaHby6s
0mQmk7V6WPpGZ+Sadx7TzzglutVAslA8nK5m1rdEBywtJINaMcqnhm8xEm15cj+1
blEBUVnaQpQ3fyf+mcR9FIknPRL3X7l+b/sQowjH4GqFd6m/XR0KGMwO0a3Lsyry
MGeqgtmxdMe5S6YdyXEmERECgYAgQsgklDSVIh9Vzux31kh6auhgoEUh3tJDbZSS
Vj2YeIZ21aE1mTYISglj34K2aW7qSc56sMWEf18VkKJFHQccdgYOVfo7HAZZ8+fo
r4J2gqb0xTDfq7gLMNrIXc2QQM4gKbnJp60JQM3p9NmH8huavBZGvSvNzTwXyGG3
so0tiQKBgGQXZaxaXhYUcxYHuCkQ3V4Vsj3ezlM92xXlP32SGFm3KgFhYy9kATxw
Cax1ytZzvlrKLQyQFVK1COs2rHt7W4cJ7op7C8zXfsigXCiejnS664oAuX8sQZID
x3WQZRiXlWejSMUAHuMwXrhGlltF3lw83+xAjnqsVp75kGS6OH61
-----END RSA PRIVATE KEY-----" Printing the console.log(process.env.GITHUB_PRIVATE_KEY);
// output: "-----BEGIN RSA PRIVATE KEY----- I opened an issue in Note: Private key is invalidated. |
Ah, okay, yes, I ran into this myself. Multi-line environment variables is a feature by dotenv. I don't think it's something that is supported by unix systems, nor is it supported by whatever next is using internally. But we can provide a more helpful error message. We know that there must be at least one line break in the private key and can check for that, and at least provide a more helpful error message |
For the next.js env files, you have to replace line breaks with
|
Or if it is not containing the closing tag then it means private key schema is invalid :) Opening tag: |
I created gr2m/universal-github-app-jwt#71, happy to accept a pull request for that change. We can leave this open until the change has been implemented. But let's continue the discussion there |
Thanks, This way it is working. |
I've been running into this as well when using auth-app in a custom GitHub Actions implementation. If it helps, I was able to confirm that things work fine in Node 16.16 and later, but fail in Node 16.13. |
Has anyone managed to get this working in Deno at all? I get stuck somewhere in the whole cryptographic process. I think it stems from if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) { I can't seem to be able to create an object which passes the And I can't seem to use Things like this:
|
For deno support it is recommended to use esm.sh import { createAppAuth } from "https://esm.sh/@octokit/auth-app@4.0.13"; Out of the box support just isn't available, yet. |
I have same issue, i am using sveltekit, i am initializing the admin sdk like this in the server side: import { initializeApp, credential, apps } from "firebase-admin";
import * as path from "path";
import * as fs from "fs";
import { deleteApp } from "firebase-admin/app";
// Get the path to the service account key JSON file
const serviceAccountPath = path.join(
process.cwd(),
"firebase",
"serviceAccountKey.json",
);
// Read the service account key JSON file synchronously
const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountPath, "utf-8"));
const config = {
credential: credential.cert(serviceAccount),
};
let adminSDK = null;
if (!apps.length) {
adminSDK = initializeApp(config, "admin");
} else {
await deleteApp(adminSDK);
adminSDK = initializeApp(config, "admin");
}
export default adminSDK; and when i use it in hook.server.js: /** @type {import('@sveltejs/kit').Handle} */
import adminSDK from "../firebase/firebaseAdminSdk.js";
export async function handle({ event, resolve }) {
const token = event.cookies.get("_token_");
const uuid = event.cookies.get("UUID");
if (token) {
try {
const decodedToken = await adminSDK.auth().verifyIdToken(token);
const user = await adminSDK.auth().getUser(uuid);
event.locals.authenticated = true;
return await resolve(event);
} catch (error) {
event.locals.authenticated = false;
console.log(error);
}
}
return await resolve(event);
} when i console.log(decodedToken) everything goes as expected, but it throws out error Error: secretOrPrivateKey must be an asymmetric key when u |
Is the issue still present if you use Octokit itself and not vite? You need to use the browser build of Octokit from ESM.sh with Vite for it to work properly |
I'm also getting the error const { createAppAuth } = require("@octokit/auth-app");
const auth = createAppAuth({
appId: 123,
privateKey: `-----BEGIN RSA PRIVATE KEY-----
lorem ipsum
-----END RSA PRIVATE KEY-----`,
installationId: 123,
});
const graphqlWithAuth = graphql.defaults({
request: {
hook: auth.hook,
},
});
const { repository } = await graphqlWithAuth(
`{
repository(owner: "octokit", name: "graphql.js") {
issues(last: 3) {
edges {
node {
title
}
}
}
}
}`,
); |
Note that if you passed your private key exactly like this, line two and following start with 2 spaces, which makes the key invalid |
Trying to use Node:19 instead of Node:16 to fix error similar to: ``` octokit/auth-app.js#465 ``` Signed-off-by: Sean P. Goggins <s@goggins.com>
Troubleshooting node version as possible source of key error: similar to: ``` octokit/auth-app.js#465 ``` Signed-off-by: Sean P. Goggins <s@goggins.com>
I figured that I would post here and say how I got this to work because it was really a PIA. So what I did was I took my PEM key locally and base64 encoded it: cat private.pem | jq -s -R -r @uri | base64 > private.pem.encoded Then what I did was added it as an environment variable (Im using amplify but whatever). For those using amplify I just set them in my backend build in the yaml: version: 1
backend:
phases:
build:
commands:
- echo "Creating config directory..."
- echo "SALESFORCE_PRIVATE_KEY_ENCODED='$SALESFORCE_PRIVATE_KEY_ENCODED'" >> .env
- echo "SALESFORCE_CLIENT_ID='$SALESFORCE_CLIENT_ID'" >> .env
- echo "SALESFORCE_USER='$SALESFORCE_USER'" >> .env
- echo "SALESFORCE_LOGIN_URL='$SALESFORCE_LOGIN_URL'" >> .env
- echo "Printing environment variables for debugging..."
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple Once I did that I was able to pull in my key and decode it in my file and get it to work: const privateKeyEncoded = process.env.SALESFORCE_PRIVATE_KEY_ENCODED;
const privateKeyUrlEncoded = Buffer.from(privateKeyEncoded, 'base64').toString('utf8');
const privateKey = decodeURIComponent(privateKeyUrlEncoded); Anyways I hope this helps you all. |
What happened?
Generated a privatekey using the GitHub Apps interface, which downloaded a .pem file. I loaded this file directly into my auth config:
I also tried pasting in the key directly. I also removed all whitespace in a separate attempt. All yielded the same error, which seems to me indicates a problem with the keys being generated from GitHub. Would appreciate any assistance with this.
Relevant error is shown in the log output below.
Versions
Relevant log output
Code of Conduct
The text was updated successfully, but these errors were encountered: