This is a Heroku Buildback that automates the decryption of EJSON secrets on deploy.
It's a fork of Shopify's EJSON buildpack that exports secrets as environment variables on application start rather than writing to a JSON file when the slug is compiled. This avoids storing an unencrypted secrets file on disk and allows apps to continue fetching secrets from environment variables.
EJSON files are encrypted via a public-key cryptography scheme, the intention being that the non-secret public key can safely be stored on developer machines and in source control, whereas the sensitive private key can be scoped only to production infrastructure.
Install EJSON with gem install ejson
.
Generate an EJSON keypair with ejson keygen
.
❯ ejson keygen
Public Key:
d437b2159cbf18a9e36fc1aa7a3007ea2b2ea5c0c2878d7101ad740c81418b55
Private Key:
24a4a88328317f80bd74ee80d6fe298ae6e9d02361d818c068dfd445b686098e
Create an EJSON file secrets.ejson
using the public key and add your first secret:
{
"_public_key": "d437b2159cbf18a9e36fc1aa7a3007ea2b2ea5c0c2878d7101ad740c81418b55",
"environment": {
"SOME_API_KEY": "password"
}
}
Do no commit this file to source control at this stage. The value is still unencrypted. Use EJSON to encrypt it:
❯ ejson encrypt secrets.ejson
Wrote %d bytes to %s.
225secrets.ejson
Now the file can be safely committed and deployed.
Add the following environment variables to your heroku app's config:
heroku config:set \
EJSON_FILE=secrets.ejson \
EJSON_PRIVATE_KEY=24a4a88328317f80bd74ee80d6fe298ae6e9d02361d818c068dfd445b686098e
Add this Heroku buildpack:
❯ heroku buildpacks:set https://github.com/envato/heroku-buildpack-ejson.git
Add this line to your application's .profile
script:
export_ejson_secrets
Alternatively you can set the EJSON_AUTO_EXPORT
environment variable.
heroku config:set \
EJSON_AUTO_EXPORT=true
On application start, it will use those 2 environment variables to decrypt the ejson file and export the secrets as environment variables.
Use the Heroku CLI to pipe the private key into ejson for decryption:
❯ heroku config:get EJSON_PRIVATE_KEY | ejson decrypt --key-from-stdin secrets.ejson
{
"_public_key": "d437b2159cbf18a9e36fc1aa7a3007ea2b2ea5c0c2878d7101ad740c81418b55",
"environment": {
"SOME_API_KEY": "password"
}
}