What is the secrets.yml file in Rails?

If you try to run a Rails 4 or 5 app, in production mode, without creating a secrets.yml file you will get an error.

Missing secret_key_base for ‘production’ environment, set this value in config/secrets.yml

What is secrets.yml and secret_key_base?

The config/secrets.yml should contain the applications secret_key_base. It is also a place to store access tokens, external API keys, configuration options, etc.

development:
  secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
  some_api_key: SOMEKEY

The secret_key_base is used for verifying the integrity of signed cookies. Without this, it’s impossible to trust cookies that the browser sends, and hence difficult to rely on session based authentication. It should be a random string with at least 30 characters. You can ask Rails to generate a secure key for you:

$ bin/rails secret
b38d37ade7f08854e436e01783ad5a3956389bca4e2b89bd3e9fc209723ca8e0939b1a3de9639440b1d766f170cb155108886e0903c992c701c2c38f20080c8e

Then, you just need to copy this key into your secrets.yml file.

secrets.yml vs application.yml

Before secrets.yml came along in Rails 4, how did developers manage configuration options? Personally, I used a third party gem, called Figaro. The gem allows you to place configuration options into config/application.yml. You can then access configuration, anywhere in your app using the global ENV variable: ENV["example_api_key"].

Now that Rails has introduced the secrets.yml file, you have the option to put configuration in there rather than using a gem like Figaro. There are some reasons that you would still want to use Figaro over secrets.yml but most developers can happily switch over to secrets.yml.

Committing secrets.yml to source control

The secrets.yml file should be committed to source control. However, best practice is that the secret_key_base, for production, should not be in source control.

Committing the production secret_key_base is insecure because attackers could impersonate any user if they were to obtain this key.

Instead, you should read the key from the environment. Here is an example:

development:
  secret_key_base: a20b443c63a9261415c0d80a8ceac4c76fbf3d8fe9cfa27ccff52b1e61bbcd28157b19145a72e3779204f3a503c80523b79ded15f9398f923f797765f240fe82
test:
  secret_key_base: af067fc9ea732b4ed7a1f3c7ea0b55a5e764fd269160b55f5b47a89a57886127f15f8b16f7d86063d33ee3c5e586a48ef1a06919dd8cc8d4300a7ed0c738af81 
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Summary

In short, Rails 4 and up requires secret_key_base to be set in config/secrets.yml. The secrets.yml file can also be used to store configuration for your application. Finally, the secret_key_base should not be stored in source control, for production.