Managing security for an open source rails 3 application stored at github - ruby-on-rails

New to rails, open source and soon ready for deploying to a production environment, I have some security considerations.
How to handle the database.yml is covered pretty good by, how-to-manage-rails-database-yml
But from my point of view there are more configuration settings in a normal rails application that shouldn't be hosted in a public github repository and deployed to production e.g.
devise.rb -> config.pepper
secret_token.rb -> Application.config.secret_token
capistrano -> deploy.rb
...
Adding config/****/* to .gitignore would not only prevent new developers from bundle install, db:create, db:migrate, rails server but also to keep the production config up to date if a new gem with an initializer is installed.
Another possibility would be add an environment.yml with sensitive config, like database.yml where sensitive configuration in the initializers will be overridden?
This will make it easy to get up and running after a clean checkout and the production environment will be easy to maintain.
Any ideas how to approach my problems above?

I usually put "safe" data in these files, which will usually work for development purposes. But in production I symlink the files to another location with capistrano, like this:
invoke_command "ln -sf #{shared_path}/database.yml #{release_path}/config/database.yml"
So in the production server I have a bunch of files that override the files in source control. I don't even work with a database.yml.example, just some sane default database.yml that the developers agree upon to use in development and test.
For individual settings, like API keys, I usually create a config/settings.yml and read them from inside the initializer:
SETTINGS = YAML.load(IO.read(Rails.root.join("config", "settings.yml")))
YourApp::Application.config.secret_token = SETTINGS["secret_token"]

Related

How to store secret variables in capistrano

I am writing a Rails app with automated deployment using Capistrano. In the deploy.rb script I have:
set :deploy_to, '/my/deploy/path/'
And in production.rb I have:
server 'example.com', user: 'secret_user_name', roles: %w{web app db}
Currently the app is private. But assume I wanted an open source app like this. Then I wouldn't want secret_user_name and /my/deploy/path to be stored in the repo. In the Rails project if I encountered an issue like this I would store the secret values in secrets.yml and access them from there. However I don't have access to secrets.yml from Capistrano. So I could manually load the secrets file but I'm sure there is a better way to do this.
So my question is: How can I have an automated deployment process without exposing server information using Capistrano? Is there a recommended way to store secrets like there is in Rails?
If your intention is to maintain your own deployment environment (which you keep secret) but open source the code of the application itself, then I would simply move the Capistrano-related files to a separate private repository. Then you can open source the app itself, but keep the Capistrano config private.
There is no need for Capistrano's deploy.rb, etc. to live in the same directory structure or even the same repository as the app that is being deployed. After all, Capistrano deploys based on the :repo_url, which can be anything. It doesn't have to match repo where Capistrano's files are kept.
If you want to give other people (i.e. those that fork/clone the app) the ability to deploy to their own infrastructure, perhaps the easiest solution is to write up a wiki page explaining how they can set up their own Capistrano config. Deployment environments can vary widely and therefore it is probably not something you can do simply with environment variables or encrypted secrets.
In any case make sure you audit and rewrite your Git history if necessary to make sure you won't be leaking any sensitive config when you make the repo public.
Environment variables might help you.
You can put export SSH_PROD_USER=secret_user_name; in your preferred shell profile. For example if you use bash then it would be ~.bash_profile. Then use it in production.rb like this:
server 'example.com', user: ENV['SSH_PROD_USER'], roles: %w{web app db}
So basically ruby will have all your environment variables
Use something like Figaro gem: https://github.com/laserlemon/figaro
and don't push to your repo your application.yml
Or use an encrypted repo with credentials.

Different local database configuration Rails

I'm working in a team in a Rails project.
Each of us have a local database for development purpose. We have a problem: Everyone have different configuration for the local database. When someone make a commit without reset the /config/database.yml the other members of the team can't use their database because the access is not configured.
Can I have a local configuration not commited? To each one can works without problem and without the need of re-set the file every time? Sometime like the local_settings.py in Django
You can configure the database in Rails via both the config/database.yml file and the DATABASE_URL env var. They are merged but settings from DATABASE_URL take precedence.
A good solution is to check in the config/database.yml with a basic configuration thats just enough to support postgres.app or whatever is the most common solution.
Developers that need other settings can set the DATABASE_URL env var to customize the database configuration. Gems like figaro and dotenv make this easier.
If you have ever wondered this how Heroku manages to use the correct DB no matter what you throw into database.yml and the DATABASE_URL ENV var is how you should be configuring your production DB.
Why should I use ENV vars and not more database_*.yaml files?
The twelve-factor app stores config in environment variables (often
shortened to env vars or env). Env vars are easy to change between
deploys without changing any code; unlike config files, there is
little chance of them being checked into the code repo accidentally;
and unlike custom config files, or other config mechanisms such as
Java System Properties, they are a language- and OS-agnostic standard.
https://12factor.net/config
Add config/database.yml in to the .gitignore file at root path of your rails-app.
Copy config/database.yml with the values you need for production into config/database_example.yml.
Now you can modify your local database and in production you copy config/database_expample.yml to config/database.yml
If the config file is ignored by git, everyone can change it locally without getting tracked by git.
EDIT:
HERE YOU SEE HOW YOU CAN REMOVE FILE FROM TRACKING!!!
Ignore files that have already been committed to a Git repository

Which is the safest way to manage Rails database.yml?

Since database.yml file contains some private information, we shouldn't put it under version control.
I just dig out a bunch of solutions for sync database.yml to my server, such as this, I just want to know which is the safest way? Do I should only use scp to for that when I use Cap3 deploy?
You should just create the database.yml on your server manually when you first deploy, and then use Capistrano's linked_files directive to persist the file across deployments. I think the default capistrano configuration contains an example of using the linked_files directive for your database.yml.
Copy the database.yml during deployment from your development machine to your server to shared/db if it doesn't already exist. After deploy and before assets are compiled copy the database.yml to current/config/database.yml.

Rails: Where to put configuration variables

My team is maintaining a Rails application. The previous developer(s) decided to put some configuration variables (like facebook app id, twitter app id) as env variables. But this is not very versatile. If we have two applications (test and production), we are forced to use only one hardcoded configuration (or changing it manually). Also it is good practice to put these variables in the version control.
Is that the right way to do that? If not, what is the right way?
We are using following solution in 2 apps.
Store config variables in yml files for https://github.com/railsjedi/rails_config gem.
Apps are configured to use different yml files in production and dev modes via initializers.
On production servers directory with yml files are symlinked with 2 apps.
Task for capistrano looks so:
namespace :settings do
task :symlink, roles: :app do
run "ln -s /path_to_settings/#{rail_env} #{current_path}/config/settings"
end
end
after "deploy:create_symlink", "settings:symlink"

where to put secure passwords/keys in a rails app?

I have a few web services that require secure tokens/keys/passwords to be passed in. Where should I define these secure values for my rails app to see? I want the development keys in version control, but don't want the production keys in version control. How should I set this up? I'm new to rails.
You see the question properly.
Put your passwords and keys in some yml file excluded from version control.
Then on your production server, create the very same file and symlink your app to it every time you deploy.
EDIT.
Capistrano is almost made to fits these needs:
put your yml files in the shared folder
In your capistrano deploy.rbfile:
after 'deploy' do
run "ln -s #{shared_path}/database.yml #{release_path}/config/database.yml"
end
to work with yml files: http://railscasts.com/episodes/85-yaml-configuration-file
apneadiving is right, symlinking the files is a good idea. Another approach is to put the keys in the shell variables, accessible only to the user that runs the app. Then, in your rails app you'll have
login = ENV['SERVICE_LOGIN']
password = ENV['SERVICE_PASSWORD']
As of Rails 4.1.0, check out secrets.yml.

Resources