I'm pretty new to rails, but I have some experience programming in PHP and other languages. I really like rails, and I'm working on an application for my company, but I still don't fully understand how the secrets.yml file works with git and heroku. I understand that secrets are used for authentication, but I don't understand exactly how to keep them secret while still deploying to heroku through git.
First question is, do I really need to keep my development and test secrets a secret? Rails automatically sets production development secret to the environment secret (which I still don't fully understand), but why would it matter if people knew what my development and test secrets are?
Secondly, what is a good resource to better understand using secrets.yml file in conjunction with git? The rails guide doesn't seem to document using it very well (only about a paragraph is dedicated to secrets.yml), and this seems like a pretty important topic that could lead to a serious security flaw in your application.
Finally, how do other people protect their secrets? Looking at several example apps on github, I've noticed that most people don't seem to take any steps to keep the secrets file in .gitignore. Is this simply an oversight, or is it because it isn't as serious of a security matter as I think it is?
I appreciate any help I can get. I've been researching this particular issue for a while and haven't really gotten any comprehensive solutions to the problem. I want to present my project to my company and explain the advantages of using version control systems like git, but I also want the app to be secure enough to trust that it is keeping my company's data safe.
All very good questions. Although there is probably no serious harm in not securing development and test secrets, it is good practice to do so. There is no upside in revealing information which could potentially make it easier for a bad actor to access your application code or data.
As of Rails 4.1, config/secrets.yml
can be used to manage all of your application secrets. This is described in the Rails 4.1 release notes. If you manage your secrets in this file, you should definitely include the file in .gitignore
so that your secrets do not show up in your code repository, even if it is currently private. You never know if you will want to open source your code in the future or share your private repository with another collaborator. As you probably know, once you put a file in git, it can be an involved process to remove all traces of it. Alternatively, you could maintain a secrets.yml template in git so that you have source control of the format of your secrets file, but keep the actual secrets in a separate file.
How you manage your secrets in production depends on your deployment platform. If you deploy to your own server, you just need to make sure that you have a mechanism to separately maintain deployment of secrets.yml
, since it will not be available in your git repository. You should be able to manage this through your deployment process using a tool like Capistrano
or Mina
. If you deploy to Heroku, you need to set config variables either through the Heroku CLI or the Heroku dashboard as described in the documentation.
Hope this helps.
As far as I can tell Rails hasn't solved this one yet (as of Rails 4.2).
Here's a great summary of the mess situation
From Rails 4.1 there's a secrets.yml
file that is for all your secrets, but it's not in .gitignore
by default. People tell you to put it into .gitignore
but that doesn't help Heroku users get it to production. There's a gem that can help with that. If you do that then you might as well just use the Figaro gem that does all that in a neater way.
From the default contents of the secrets.yml
file it looks like the Rails developers intended for it to be included in source code repositories, but for any real secrets you're supposed to use environment variables and import those into the secrets file, which almost defeats the purpose.
If you want to use environment variables to hold the secrets, that means the underlying OS is storing them for you and when you need to use them you ask the OS what the variable is, that way it's not in your code at all. The command for setting the environment variables on Heroku looks like this:
heroku config:set YOUR_SECRET_VAR_NAME=your_secret
There are disadvantages to doing it this way. If you have a lot of secrets things will get messy fast, and it'll be hard to get it set up on a new machine.
the dotenv gem solves these problems letting you do environment variables without all the downsides of them. I recommend you use dotenv in conjunction with secrets.yml
without putting sectrets.yml
in the .gitignore
and manually set environment variable on Heroku.
Rails 5.2 has finally solved this by encrypting all your secrets within then Rails app and the you only need to store one key in the environment variable.
First off, I always add all .yml
files to my .gitignore
file, like this:
*.yml
This serves to keep any configuration files off of git. However, I also create "distribution files" to keep on git. Basically, clone somefile.yml
to somefile.yml.dist
and remove the actual values, but keep the structure/keys intact, so anyone else using your code can "fill in the blanks" themselves.
Keeping your development/test secrets secret isn't that important, as long as they differ from your production secrets. Some secrets (like if you are using Cloudinary) are the same for all environments, so you don't want to share those.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With