Using secret passwords in Rails App - ruby-on-rails

I am working on a rails application, on which I need to send an issue on github if a certain process takes place. To send a post request, I need to use my github username and password. I can't use my password in open. What should I do?
I know something about secrets.yml file in rails config but I can't even put my password there. I will put my app on github and anyone can hence access. How should I use secrets.yml file to store my password and use it in my rails app?

2 options:
Set it as an environmental variable. How you exactly do so is highly dependent on which operating system you use. There are plenty of tutorials on how to do so and how to access it from a Rails application. These variables are visible only locally and won't be seen when you push your code to GitHub.
Add your secrets.yml to your .gitignore file. If you don't have a .gitignore file, create one in the root directory of your project. Then, simply add secrets.yml to that file. Once you do that, git will forever ignore that file in any commit, push, etc. and won't show up if you push your code to GitHub. However, if you already have a secrets.yml file and it has been tracked previously by git, you need to remove that file's history. Details on how to do so can be found here.

You shouldn't commit the secret.yml to your git repository. A secret.yml that includes production secrets should only exist on the servers (and only be accessible to server administrators).
Furthermore you might want to use an API token instead of your username and password, because API tokens are easier to change.

This is probably a good solution for you.
https://github.com/attr-encrypted/attr_encrypted
You can encrypt the password and save it to the db assigned to the user (if you have one of course).
If you don't have a user then you'll be stuck with environment variables and secrets.yml or another similar solution

Related

What is the correct way to use config/credentials in Rails 6? And how do I stop my app from using /tmp/development_secret?

I'm working on a Rails application and I am attempting to organize my secret_key_base and related important secrets (Think API keys, database credentials, etc.)
I am trying to find a way to setup something like the following, under /config
/config
credentials.yml.enc
master.key
/config/credentials
development.yml.enc
development.key
production.yml.enc
production.key
test.yml.enc
test.key
First Question:
Is it that secret_key_base exists in /config/credentials.yml.enc, which is loaded (first?) and then the credentials are loaded for the environment rails is running in? Or should I create a different secret_key_base for each environment?
Second Question:
No matter what I do, when I run in development or test, tmp/development_secret loads first. In addition, whenever I try to access my secrets in development, (Rails.application.secret_key_base) as referenced here: What's the correct way of defining secret_key_base on Rails 6, I run into an issue where I only ever receive nil when looking for secrets I've defined in my development.yml.enc, which I assume is because it's not loading anything in that file, it's going to tmp/development_secret and not finding anything else (Maybe I'm wrong.)
Goals:
Stop tmp/development_secret from being created, and instead access
secrets using the specific .yml.enc file depending on the
environment.
Understand why /config/credentials.yml.enc exists if it doesn't
load in all the environments. If it doesn't, then it isn't clear when it loads.
Why?
Using config/database.yml as an example, I want to store different creds for each environment, but none of them in version control. (I want nobody but a few to have production.) However, I want to access them the exact same way in all of my environments. Not having creds load in production because of an issue with a .yml file will crash my app, so I don't want to load them differently in test/development.
Put together a blog post about this because searching for documentation on this feature is painful. It's a really easy thing because then only the master.key, and production.key would need loaded as ENV variables which is great. (Or possibility just one of them.)
This really should be a simple, out-of-the-box thing, but it's hard to find real documentation on best practices.
I've found the answer, at least the one I'm looking for. You can have your initializer load whatever file you want by overriding the defaults.
config.credentials.content_path = 'config/credentials/development.yml.enc'
config.credentials.key_path = 'config/credentials/development.key'
https://edgeapi.rubyonrails.org/classes/Rails/Application.html

How to store email credentials securely using Figaro in Rails

So, I'm a little confused on how to securely store my email credentials using Figaro - am about to push my app up to production from development. Noted on the guide at https://github.com/laserlemon/figaro though I not know where to begin and end. I tried searching on stack overflow for a guide on this but found none. What steps should I take after installing Figaro to store said credentials in development, then push my app up to production? Thanks. p.s. I'm a beginner in Rails.
My Git is up at https://github.com/cheese1884/197451
Is Using Figaro and Secrets.yml to Manage Env Variables still relevant as of 2018?
Thought I would add this as an answer to make it easier to read and follow. From your response you have set up an application.yml and it will have the values you want to reference in your code somewhere.
Using a simple example I have set up a username and password in an application.yml.
application.yml
development:
username: Mark
password: secret123
production:
username: admin
password: supersecret123
If I then want to get the values somewhere in my code then I can use the following syntax:
Figaro.env.username
Which should return (in development):
Mark
When you push the code to live the same command will pick up the value from the production block and return:
admin
Similarly you can get the password with the
Figaro.env.password
When pushing to live the application.yml is a file like any other. Like I said in your comment I don't know how you are deploying. We have a capistrano script that runs copying the repo to the server. The application.yml is then manually added because it is not included in the repository. We don't use Heroku and I have never used it myself so can't comment on it.
Hopefully this adds some clarity.

Is it ok to store DB password for the production environment in the config/database.yml file

Is it ok to store DB password for the production environment in the "config/database.yml" file? Or is there any more correct way to do it (maybe environment variables)?
Thanks in advance.
It's not a good idea! One main reason is that the config/database.yml file will probably be included in some kind of source control, like a git repository. Even if the repo is private currently, you can't know for sure it won't be made public in the future and then you would have a problem on your hands!
In addition, if anyone ever gains read-access to your application's files or just a copy of your application's source, they now have your database password.
A typical solution is to set an environment variable like you suggested and then read it in the .yml file:
password: <%= ENV['DATABASE_PASSWORD'] %>
If you're using a PaaS like Heroku, this is the standard way to do things. But even this isn't a perfect solution, so evaluate your options carefully.

How to store credentials for third party services in Rails

I am setting up a redirection through SendGrid for the mails sent by my rails application.
However I am not really satisfied with the way I'm told to store the credentials.
As it is specified there, they suggest to overwrite ActionMailers defaults in the config/environment.rb file. I've found out that my predecessor created a initializers/smtp.rb file where he defined the previous settings, but by discovering this file, I discovered the SMTP password...
If I modify any of these files, anuone having access to the git repository will have access to the credentials (including the front-end and back-end freelances we work with).
I was thinking of creating a file that would stay on the server's shared folder (like the database.yml file) and that would be symlinked to the app each time we deploy thanks to capistrano.
What do you think of it? Would it be okay to just move this initializers/smtp.rb to the server's shared folder and symlink it when deploying?
My suggestion (what I've seen done):
Move API keys and sensitive info into a yml file under config/.
Load this yml file into a variable, for instance
KEYS = YAML::load(File.open("#{RAILS_ROOT}/config/config.yml"))
Voila.
Also, when putting your code up on GitHub for example, this config.yml would be something you add to the .gitignore. Instead, make a config-example.yml and tell your developers to get their own keys and passwords and such, storing them in their local config.yml.
Environmental variables are the best way if you're on *nix
Stick your variables in .bashrc file like so:
// no need for quotation marks
export GMAIL_USER=my_gmail_user_name#gmail.com
export GMAIL_PASSWORD=my_gmail_password
And call them in your smtp initializer like so:
ActionMailer::Base.smtp_settings = {
:user_name => ENV['GMAIL_USER'],
:password => ENV['GMAIL_PASSWORD']
}
Restart bash and your rails app. All should work. Heroku have a good article on how to use env variables on their network.

How Do You Secure database.yml?

Within Ruby on Rails applications database.yml is a plain text file that stores database credentials.
When I deploy my Rails applications I have an after deploy callback in my Capistrano
recipe that creates a symbolic link within the application's /config directory to the database.yml file. The file itself is stored in a separate directory that's outside the standard Capistrano /releases directory structure. I chmod 400 the file so it's only readable by the user who created it.
Is this sufficient to lock it down? If not, what else do you do?
Is anyone encrypting their database.yml files?
The way I have tackled this is to put the database password in a file with read permissions only for the user I run my application as. Then, in database.yml I use ERB to read the file:
production:
adapter: mysql
database: my_db
username: db_user
password: <%= begin IO.read("/home/my_deploy_user/.db") rescue "" end %>
Works a treat.
You'll also want to make sure that your SSH system is well secured to prevent people from logging in as your Capistrano bot. I'd suggest restricting access to password-protected key pairs.
Encrypting the .yml file on the server is useless since you have to give the bot the key, which would be stored . . . on the same server. Encrypting it on your machine is probably a good idea. Capistrano can decrypt it before sending.
Take a look at this github solution: https://github.com/NUBIC/bcdatabase. bcdatabase provides an encrypted store where the passwords can be kept separated from the yaml files.
bcdatabase
bcdatabase is a library and utility
which provides database configuration
parameter management for Ruby on Rails
applications. It provides a simple
mechanism for separating database
configuration attributes from
application source code so that
there's no temptation to check
passwords into the version control
system. And it centralizes the
parameters for a single server so that
they can be easily shared among
multiple applications and easily
updated by a single administrator.
Better late than never, I am posting my answer as the question still remains relevant. For Rails 5.2+, it is possible to secure any sensitive information using an encrypted file credentials.yml.enc.
Rails stores secrets in config/credentials.yml.enc, which is encrypted and hence cannot be edited directly. We can edit the credentials by running the following command:
$ EDITOR=nano rails credentials:edit
secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
production_dbpwd: my-secret-password
Now, these secrets can be accessed using Rails.application.credentials.
So your database.yml will look like this:
production:
adapter: mysql
database: my_db
username: db_user
password: <%= Rails.application.credentials.production_dbpwd %>
You can read more about this here
Even if you secure the database.yml file, people can still write that uses the same credentials if they can change the code of your application.
An other way to look at this is: does the web application have to much access to the database. If true lower the permissions. Give just enough permissions to the application. This way an attacker can only do what the web application would be able to do.
If you're very concerned about security of the yml file, I have to ask: Is it stored in your version control? If so, that's another point where an attacker can get at it. If you're doing checkout/checkin over non-SSL, someone could intercept it.
Also, with some version control (svn, for exampl), even if you remove it, it's still there in the history. So, even if you removed it at some point in the past, it's still a good idea to change the passwords.

Resources