Where do you put your secret keys? This question seems simple but it causes a surprising amount of trouble for developers. Early on you might just paste an API key directly into your code. You learn quickly that this is a bad idea. Anyone with access to your source code now has your keys.
The next step is often a YAML file. You create a config/secrets.yml
and add it to .gitignore
. This works but it creates a new problem. How do you share the file with your team? You might use a password manager or send it over a secure channel. It feels clumsy. And now your secrets are not in version control. If a key changes you have to manually tell everyone to update their local file.
Then came environment variables. This became the standard for a long time. You store secrets in a .env
file for development which is also ignored by Git and you set the same variables on your production server. This is better. It separates configuration from code. But it has its own subtle problems. It can be hard to keep track of which variables are needed for a project. And sharing them with a new developer is still a manual process.
Rails saw these problems and built a better solution right into the framework. It is called Encrypted Credentials.
Since Rails 5.2 the default way to manage application secrets is through a single encrypted file config/credentials.yml.enc
. This file is meant to be checked into your version control system like any other piece of code.
This seems wrong at first. Are you not just checking your secrets into Git? The answer is no. The file is encrypted using a key that is not checked into Git. The encrypted file is useless without the key.
This system uses two files:
config/credentials.yml.enc
: The encrypted file containing your secrets. It is safe to commit.config/master.key
: The file containing the key to decrypt the credentials file. This file is automatically added to .gitignore
and must never be committed.This simple setup solves the old problems. Your secrets are now version controlled and in one place. When a key changes you just edit the file and commit it. And a new developer only needs one thing to get started the master key.
To work with your credentials you never edit the .enc
file directly. Instead you use a built in Rails command.
bin/rails credentials:edit
This command does something clever. It finds your master key in config/master.key
decrypts the credentials.yml.enc
file in memory and opens the decrypted contents in your default text editor. When you save and close the editor the command automatically re-encrypts the file with your changes.
You can store anything you want in this file. It is just YAML. For example you might add a key for a payment provider.
stripe:
api_key: sk_test_123456789
publishable_key: pk_test_987654321
To access these values in your application code you use a simple object Rails.application.credentials
. Rails automatically decrypts the file on boot and makes the secrets available through this object.
Stripe.api_key = Rails.application.credentials.stripe[:api_key]
It feels natural because it is just part of Rails. There are no extra gems or complex setup steps.
This workflow is great for development but how does it work on a server? Your production server does not have the config/master.key
file because you did not commit it.
This is intentional. The solution is to provide the key to your application through an environment variable. The variable is named RAILS_MASTER_KEY
.
When your Rails app boots in production it looks for this environment variable. If it finds it Rails uses that key to decrypt credentials.yml.enc
.
So your deployment process has only one extra step. You need to securely set the RAILS_MASTER_KEY
environment variable on your server. Hosting platforms like Heroku Render or Hatchbox all provide a simple way to manage environment variables for your application. You copy the contents of your local config/master.key
file and paste it as the value for RAILS_MASTER_KEY
.
This is a huge improvement. Instead of managing a dozen different environment variables for all your API keys you now manage just one.
The Rails credentials system is better than older methods for a few clear reasons.
First all your secrets are in one place and version controlled. This makes history and collaboration simple. Second a new developer can be onboarded by sharing a single key. Third you reduce the risk of accidentally committing a secret. The only file you have to protect is master.key
.
It is a simple system that solves a complex coordination problem. It removes ambiguity about where secrets should live and how they should be managed. If you are not using it you should be.
It is one of those features that shows the deep thinking behind the Rails framework. It provides a strong default that guides you toward a good practice without getting in your way.
Now think about the last time you had to share a secret key with a teammate. Write down how that process worked.
— Rishi Banerjee
September 2025