Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to set RSA private key as config var

Tags:

heroku

I'm trying to deploy an Express app to Heroku. The trouble I'm having is that Heroku or something along the way is screwing up the format of the RSA private key string. I have the following in my .env which works locally and is kept out of git:

TYPE=
PROJECT_ID=
PRIVATE_KEY_ID=
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
CLIENT_EMAIL=
CLIENT_ID=
AUTH_URI=
TOKEN_URI=
AUTH_CERT_URL=
CLIENT_CERT_URL=

I initially used https://github.com/xavdid/heroku-config to set the above vars instead of doing it by hand through the dashboard on Heroku, but that private key failed.

Then I tried setting that value manually by copy/pasting (without double quotes) through the Heroku Dashboard, still failed.

Finally I set the value via heroku config:set, but still fails to parse it when the app starts up.

I even tried replacing \n with '\n' as someone did here and using quotes with heroku config:set PRIVATE_KEY="", but still doesn't work.

So my question is, is Heroku doing something funky with the long string value? Or am I missing something. The above values are called/used as shown below:

const { credential } = require('firebase-admin')

exports.serviceAccount = {
  type: process.env.TYPE,
  project_id: process.env.PROJECT_ID,
  private_key_id: process.env.PRIVATE_KEY_ID,
  private_key: process.env.PRIVATE_KEY,
  client_email: process.env.CLIENT_EMAIL,
  client_id: process.env.CLIENT_ID,
  auth_uri: process.env.AUTH_URI,
  token_uri: process.env.TOKEN_URI,
  auth_provider_x509_cert_url: process.env.AUTH_CERT_URL,
  client_x509_cert_url: process.env.CLIENT_CERT_URL
}

exports.credential = credential.cert(exports.serviceAccount)

exports.databaseURL = process.env.DATABASE_URL

exports.adminConfig = {
  credential: exports.credential,
  databaseURL: exports.databaseURL
}

And logs from Heroku:

2017-06-05T01:50:13.761150+00:00 app[web.1]: > NODE_ENV=production node ./server/server.prod.js
2017-06-05T01:50:14.231853+00:00 app[web.1]: /app/node_modules/firebase-admin/lib/auth/credential.js:129
2017-06-05T01:50:14.231876+00:00 app[web.1]:             throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse private key: ' + error);
2017-06-05T01:50:14.231877+00:00 app[web.1]:             ^
2017-06-05T01:50:14.231878+00:00 app[web.1]:
2017-06-05T01:50:14.231878+00:00 app[web.1]: Error: Failed to parse private key: Error: Invalid PEM formatted message.
2017-06-05T01:50:14.231883+00:00 app[web.1]:     at FirebaseAppError.FirebaseError [as constructor] (/app/node_modules/firebase-admin/lib/utils/error.js:39:28)
2017-06-05T01:50:14.231884+00:00 app[web.1]:     at new FirebaseAppError (/app/node_modules/firebase-admin/lib/utils/error.js:84:23)
2017-06-05T01:50:14.231885+00:00 app[web.1]:     at new Certificate (/app/node_modules/firebase-admin/lib/auth/credential.js:129:19)
2017-06-05T01:50:14.231886+00:00 app[web.1]:     at new CertCredential (/app/node_modules/firebase-admin/lib/auth/credential.js:195:33)
2017-06-05T01:50:14.231887+00:00 app[web.1]:     at Object.cert (/app/node_modules/firebase-admin/lib/firebase-namespace.js:189:58)
2017-06-05T01:50:14.231887+00:00 app[web.1]:     at Object.<anonymous> (/app/server/firebase/index.js:16:33)
2017-06-05T01:50:14.231888+00:00 app[web.1]:     at Module._compile (module.js:569:30)
2017-06-05T01:50:14.231888+00:00 app[web.1]:     at Object.Module._extensions..js (module.js:580:10)
2017-06-05T01:50:14.231889+00:00 app[web.1]:     at Module.load (module.js:503:32)
2017-06-05T01:50:14.231889+00:00 app[web.1]:     at tryModuleLoad (module.js:466:12)
like image 505
Francisco Mateo Avatar asked Jun 05 '17 02:06

Francisco Mateo


2 Answers

I was able to solve my issue using a comment suggestion I found here.

So on the Heroku dashboard for the app, I set the PRIVATE_KEY value to be double quoted:

private key screenshot

I then changed

private_key: process.env.PRIVATE_KEY

to

private_key: JSON.parse(process.env.PRIVATE_KEY)

and finally redeployed via git push heroku master and the app started up fine.


2018-10-27: The comments from the link above are gone now. But essentially the commenter had mentioned that the string is effectively a JSON string which needs to be parsed back into a String.

2019-08-01: The domain originally linked is no longer valid. So I have replaced the original link with one from the Wayback Machine.

like image 182
Francisco Mateo Avatar answered Sep 28 '22 08:09

Francisco Mateo


Your key inside your .env must be wrapped inside a single and double qoutes in the same time like this
'"[PRIVATE_KEY]"' which indeed the same format you will get from heroku when you call this command
$ heroku config:get PRIVATE_KEY -s >> .env
One more thing to add to JSON.parse in case it stills gets you an error which you will find in here:
Node.js -Firebase Service Account Private Key won't parse

So after you came back from that page, the final code line will look like this: JSON.parse(process.env.PRIVATE_KEY).replace(/\\n/g, '\n')

like image 39
Mahmoud Mohamed Zakria Avatar answered Sep 28 '22 07:09

Mahmoud Mohamed Zakria