12

I created a new Rails 6 app and since it supports Multi Environment Credentials I'm trying to use the RAILS_PRODUCTION_KEY config var and delete the default RAILS_MASTER_KEY

heroku config:unset RAILS_MASTER_KEY 
heroku config:set RAILS_PRODUCTION_KEY=`cat config/credentials/production.key`

This doesn't work however, and I was able to get it to work after setting RAILS_MASTER_KEY to the production key

heroku config:unset RAILS_PRODUCTION_KEY
heroku config:set RAILS_MASTER_KEY=`cat config/credentials/production.key`

How do I get Heroku to recognize RAILS_PRODUCTION_KEY in a Rails 6 app?

vince
  • 2,374
  • 4
  • 23
  • 39
  • 1
    I think you've discovered the solution yourself: simply trick Heroku into using the production key by assigning it to the master key. Or do you need to have both keys on Heroku? – Dennis Hackethal Dec 31 '20 at 05:51
  • No, it was just to satisfy my OCD to name the production key var as RAILS_PRODUCTION_KEY but this works fine – vince Dec 31 '20 at 17:11

1 Answers1

28

I struggled with figuring out this issue, too. (It's not a Heroku-specific issue.)

Bottom line: an environment variable named RAILS_PRODUCTION_KEY (or any other Rails environment-flavored variable name) is not a thing–Rails doesn't pay attention to it.

From the (weak, IMO) Rails documentation on the Rails 6 credentials feature, I had wrongly assumed that the production key (either in the RAILS_PRODUCTION_KEY env variable or config/credentials/production.key) would decrypt config/credentials/production.yml.enc, the master key (either in the RAILS_MASTER_KEY env variable or config/master.key) would decrypt config/credentials.yml.enc, and that a value for a given secrets key in config/credentials/production.yml.enc would override the value for that key in config/credentials.yml.enc. This is not the case.

This is how it actually works:

  1. Rails 6 uses a single key to decrypt a single encrypted secrets file.
  2. The default location of the decryption key is config/master.key and the default location of the secrets file is config/credentials.yml.enc.
  3. If an environment variable of RAILS_MASTER_KEY is defined, Rails will read the decryption key from the environment variable, not from config/master.key.
  4. When running in a given Rails environment (production/development/etc.), if a corresponding secrets file exists in config/credentials (e.g., config/credentials/production.yml.enc), then Rails will use that secrets file only, and it will use the corresponding decryption key (e.g., config/credentials/production.key) only to decrypt it.
  5. If an environment variable of RAILS_MASTER_KEY is defined, Rails will read the decryption key from the environment variable, not from the decryption key file. NOTE: regardless of the Rails environment, the environment variable that overrides the decryption key file is always RAILS_MASTER_KEY.
Ed Ruder
  • 578
  • 6
  • 13
  • 1
    This is the answer. I also thought it worked the way you thought, and that's how it SHOULD work because I feel like trying to have different keys in development vs. production will be a nightmare to manage, since I'll want to copy everything from development and override some things in production... My head is spinning already – Joe Sak Mar 29 '21 at 02:43
  • This answer finally solved it for me along with this one, https://stackoverflow.com/a/66092950/4408829 – csebryam Apr 07 '21 at 07:33
  • omg, thank you! I've just spent hours trying to figure out why `RAILS_PRODUCTION_KEY` doesn't do anything. – Ben Nov 30 '21 at 15:59