Rails Encrypted Credentials on Rails 5.2

Facebook
Twitter
LinkedIn

encryption2

Rails 5.1 introduced encrypted secrets, which gives you two places to put your secrets — secrets.yml and secrets.yml.enc. This causes a bit of confusion on when you should use normal secrets or encrypted secrets.

Rails 5.2 replaces both secrets with encrypted credentials. You cannot use plain text credentials. There’s only credentials.yml.enc.

Encrypted Credentials

To use encrypted credentials, you need a key. Without this encryption key, you won’t be able to decrypt your credentials. It’s safe to commit the encrypted file to your repository but you should never commit the encryption key.

The key, located on config/master.key is created when you run rails new. It’s also added to .gitignore so it doesn’t get committed to your repository.

The encrypted credentials are saved on config/credentials.yml.enc. Don’t edit the file directly. To add credentials, run

bin/rails credentials:edit

Your text editor will open an unencrypted version of your credentials. If you don’t have EDITOR set, you can run EDITOR=vi bin/rails credentials:edit or use your favorite text editor.

After saving the file, the encrypted version will be saved to config/credentials.yml.enc.

Reading the Credentials

If you want to use the credentials in the production environment, add the following to config/environments/production.rb

config.require_master_key = true

You can access the credentials with Rails.application.credentials. For example, if you have

foo: bar

Rails.application.credentials.foo will return bar.

Credentials Format

You can use any valid YAML on your credentials. Rails suggests using a flat format which means you don’t have to put development or production anymore.

aws:
  access_key_id: 123
  secret_access_key: 345

You can access these credentials with Rails.application.credentials.aws[:access_key_id] and Rails.application.credentials.aws[:secret_access_key]

There’s nothing stopping you from using production though.

production:
  aws:
    access_key_id: 123
    secret_access_key: 345

You can access the credentials using Rails.application.credentials.production[:aws][:access_key_id] and Rails.application.credentials.production[:aws][:secret_access_key].

Advantages of Encrypted Credentials

  1. First the obvious: your credentials are encrypted. No one will be able to decrypt your credentials without the key.

  2. The encrypted credentials are saved in your repository. You’ll have a history of the changes and who made them.

  3. You deploy new credentials together with your code. If you add code to access an API for example, you can deploy that code together with the token on credentials.yml.enc. Previously, you’ll have to make sure you add the environment variable before deploying the new code.

  4. All secrets are in one location. Instead of managing multiple environment variables, everything is in one file.

You might also like:   Code Concurrency and Two Easy Fixes

Managing the Key

While using encrypted credentials provides a number of advantages over unencrypted secrets, we still have to find a way to put the key in place. Our options are similar to handling secrets pre-Rails 5.1. You cannot save the key to your repository because someone who can access your code can then decrypt the credentials.

  1. Upload master.key securely.

    You can scp or sftp the file. In Engine Yard, you only have to do this once. When you scale your environment, the new servers will get a copy of master.key.

    Upload the key to a shared directory. Shared here means shared between releases, not a shared filesystem. On each deploy, you symlink config/master.key to /path/to/shared/config/master.key. You can do this on a deploy hook on Engine Yard or in Capistrano.

    If you need to give a developer a copy of the key, never send it via email (unless you’re using encrypted emails which most of us don’t!) You can use a password manager because they use encryption.

  2. Put the key on the RAILS_MASTER_KEY environment variable.

    In some cases where you can’t upload a file, this is the only option. Even though this is convenient, make sure you know the risks of using environment variables. The risks can be mitigated, but if you can upload master.key then use that option.

A Note on Secret Key Base

The key used to encrypt credentials is different from the secret key base. The key on master.key is used to encrypt and decrypt all credentials. It does not replace the secret key base.

The secret key base is required by Rails. If you want to generate a new secret key base run,

bin/rails secret

and add that to your credentials by running bin/rails credentials:edit.

Conclusion

Encrypted credentials offer a few advantages over plaintext credentials or environment variables. Rails like many times in the past has provided us a simple workflow. Try the encrypted credentials feature and let us know in the comments what you think.

Want more posts like this?

What you should do now:

Facebook
Twitter
LinkedIn

Easy Application Deployment to AWS

Focus on development, not on managing infrastructure

Deploying, running and managing your Ruby on Rails app is taking away precious resources? Engine Yard takes the operational overhead out of the equation, so you can keep innovating.

  • Fully-managed Ruby DevOps
  • Easy to use, Git Push deployment
  • Auto scaling, boost performance
  • Private, fully-configured Kubernetes cluster
  • Linear pricing that scales, no surprises
  • Decades of Ruby and AWS experience

14 day trial. No credit card required.

Sign Up for Engine Yard

14 day trial. No credit card required.

Book a Demo