29 December 2012
In my latest project, Malaysia Twitter Political Index, I used Google Prediction API and hosted it on Heroku. To use Google API, you have to create Client ID to authenticate with the endpoints. Since I’m calling the API directly from the server, not end user, I have to create Service Accounts client ID.
Google generated a key pair for me. I then downloaded the private key and I would use it in my app. The key is formatted with PKCS #12.
I used google-api-ruby-client gem, here’s the example to authenticate:
That worked well in development environment. To make it work in Heroku deployment, I had few options:
- Include the private key in my git repository.
- Store it in S3, and pull it when needed.
- Use custom build-pack which will include the key.
- Store it as config vars.
Option 1 is the easiest. But maybe not ideal. While it’s true that I’m the only one working on the project, I wouldn’t know if others might join in any time in the future.
Option 2 and 3 seems like a lot of unnecessary moving pieces involves.
Option 4 is ideal in this scenario. I’m already storing all sensitive information in config vars anyway. Now how would I do that?
I know config vars are string. So I took a peek at the .p12
file.
Bunch of jumbled up stuff. Ok, but PKCS #12 is just a format, maybe I can store the key in different format? I took a look back at the code and inspected what returned by Google::APIClient::PKCS12.load_key
.
Alright, that’s something that I recognized. It was OpenSSL::PKey::RSA
and returned a string. Let’s try load it directly instead of using Google::APIClient::PKCS12.load_key
.
And we are good! Now instead of storing .p12
file, I’d store that instead. Heroku config vars support multiline string. I just had to double quote it.
I make sure I passed the config var when I load the key.
That’s how you store private key in Heroku.