Hi! Thanks for doing this!
As of Rails 6, there are 3 supported ways to tackle the problem of adding sensitive information to your app’s configuration securely: 1) Secrets, 2) Encrypted Credentials (Rails 5.2) and 3) Multi-Environment Encrypted Credentials (Rails 6).
There are a few gotchas when trying to navigate which approach to use and how each works. Here is a list of gotchas in no particular order:
The documentation in the Rails Guides about Encrypted Credentials is limited and only mentions the Rails 5.2 variant (it does not mention the multi-environment encrypted credentials). Furthermore, the 5.2 variant received a lot of “air time” and most blog posts online related to credentials talk about it, making it is easy to overlook that the 6.0 variant even exists. My suggestion would be to include documentation for multi-env encrypted credentials on the Rails guides.
If you are upgrading from the
secrets.ymlapproach to the Encrypted Credentials approach (Rails 5.2), you might be tempted to add “environment namespacing” with keys inside your
config/credentials.yml.encfile. However, when coding locally, you will be surprised when you change your credentials using
rails credentials:editand your
rails serverdo not pick up the changes even if you re-start them. To make that happen, you need to restart Spring.
(Related to the point above) However, if you use the multi-env encrypted credentials approach with
rails credentials:edit --environment development, changes are picked up automatically by Spring and everything works as expected.
The lines between using
rails credentials:edit(5.2) and
rails credentials:edit --environment production(6.0) are blurry. New developers might think that the automatic fallback from an environment-specific file to a “general” file also applies in this scenario, and it doesn’t. The best documentation I found about this behaviour is: a PR and a blog post, but no mention of this on the Rails Guides.
Say you create a production-specific credentials file with
rails credentials:edit --environment production, which in turn creates a
config/credentials/production.key. When you deploy to production, you can provide the key by setting the
RAILS_MASTER_KEYenvironment variables. However, if you only use the
config/credentials.yml.enc5.2 variant, then
RAILS_MASTER_KEYshould be used to host the
master.key. Since both variants can be configured at the same time, but only one (the most specific one) is used when the app loads, the name overloading of
RAILS_MASTER_KEYbecomes very confusing.