Answers · Keys & Services

Should I use Rails credentials or environment variables for secrets?

Either. The app reads ENV first and falls back to Rails.application.credentials, so a value set in the environment wins and a value in the encrypted file is the default. Use credentials when you want secrets versioned with the code, and environment variables when a platform or a team already manages them elsewhere.

The resolution order

ENV, then credentials. That order is what makes both work at once: commit a sensible default in the encrypted file, and override it per environment without editing anything.

bin/rails credentials:edit
bin/rails runner 'puts Rails.application.credentials.dig(:stripe, :secret_key).present?'

When credentials are the better fit

One repository, one team, and a deploy that is git push plus kamal deploy. Secrets travel with the code, a new machine needs exactly one value (RAILS_MASTER_KEY) to get all of them, and the history of what changed is in git.

The tradeoff is that everyone who can read config/master.key can read every secret, and rotating a single value means an edit and a deploy.

When environment variables are the better fit

A platform that already has a secret store, a team where not everyone should see production credentials, or an app that runs in more than one environment with different values. Rotating one value is a change in one place with no deploy.

The tradeoff is that nothing is versioned, and a missing variable is discovered at runtime rather than at review.

Do not split the difference by accident

The failure mode is having both set, with different values, and not knowing which one is live. ENV wins, silently. If you use environment variables, keep the credentials file empty of those keys rather than stale.

The one that is not optional

RAILS_MASTER_KEY or SECRET_KEY_BASE. Production will not boot without one of them, because Rails cannot decrypt credentials or sign cookies. Everything else in docs/BRING_YOUR_OWN_KEYS.md has a fake behind it and is safe to leave unset.

Never commit the key

config/master.key is gitignored and should stay that way. bin/check runs a secret scan over the tree, so a key pasted into a file fails the build rather than reaching the repository. That check is worth keeping in CI for exactly this reason.

Related questions

How do I rotate an API key without taking the app down?

Create the new key at the provider while the old one still works, set it, deploy, verify the app is using it, and only then revoke the old one. Most providers allow several active keys for exactly this reason. Revoking before deploying is what turns a routine rotation into an outage.

What does SECRET_KEY_BASE actually do in a Rails app?

It is the root secret Rails derives every other key from: the one that signs session cookies, encrypts encrypted cookies, and verifies signed global ids and Active Storage URLs. Change it and every existing session becomes invalid, so every signed-in user is logged out at the moment of deploy.

What happens if I lose the Rails master key?

The encrypted credentials are gone. RAILS_MASTER_KEY is the only thing that decrypts config/credentials.yml.enc, and there is no recovery path by design. Delete both files, regenerate them, and re-enter every secret from its source. Production will not boot until the key reaching the server matches the file in the repo.