ActionMailer password security

actionmailer, ruby-on-rails, security

Solution

Use an application configuration file that is not stored in your repository for storing sensitive information. Here is how I've done it:

Add an `app_config.yml` in your `config` directory. Its contents would look like this:

smtp_password: kl240jvfslkr32rKgjlk
some_other_password: 34hg9r0j0g402jg
and_so_on: lkn$@gJkjgsFLK4gaj

Add a `preinitializer.rb` in your `config` directory with the following contents:

require 'yaml'
APP_CONFIG = YAML.load(File.read(RAILS_ROOT + "/config/app_config.yml"))

Substitute your passwords for values in the `APP_CONFIG` variable, like so:

smtp_password = kl240jvfslkr32rKgjlk # old version
smtp_password = APP_CONFIG['smtp_password'] # new version

Make sure you don't include `app_config.yml` in your repository, though you may want to create an example file that is checked in, just to show a sample of what should be in it. When you deploy your application, make sure that `app_config.yml` is stored on the server. If you're using a standard Capistrano deployment, put the file in the shared folder and update your deployment task to create a symlink to it in the current release's directory.

Problem

Am I crazy, or is it a bad idea to keep my SMTP username and password for ActionMailer in the actual (development/production) config file? It seems like I should store it an encrypted place, or at the very minimum, exclude it from my Mercurial pushes. Right now, I'm just removing the password from my source file before performing a push, but there's got to be a smarter way than the one I'm using. :) Perhaps I should store it in my database as another user (which is already stored with encrypted passwords) and fetch it programatically?

Original source