Month: May 2016

  • Rails 4.1 introduced the concept of secrets.yml, a file in which you store all the credentials for your app, separated by environment, so for example, development can talk to Test Stripe and production to Live Stripe. Furthermore, this file is capable of picking up environment variables which allows you to divorce credentials from code. Not properly separating credentials from code recently cost Uber the leakage of 50,000 driver names and license numbers.

    At Qredo we are very strict about handling credentials, including the ones for SMTP, which in Rails projects are normally stored in config/environments/development.rbconfig/environments/production.rb, etc. Trying to read Rails.application.secrets from those files doesn’t work, because they are loaded before the secrets, so, we came up with this alternative solution.

    The environment files that need to use SMTP for delivering email have this common configuration:

    config.action_mailer.delivery_method = :smtp
    config.action_mailer.smtp_settings = {
      address: "smtp.example.com",
      port: 587,
      authentication: "plain",
      enable_starttls_auto: true
    }

    and then, on config/initializers/email.rb we finish configuring our SMTP credentials by reading it from secrets.yml:

    if ActionMailer::Base.delivery_method == :smtp
      ActionMailer::Base.smtp_settings[:domain]    = Rails.application.secrets.smtp_domain
      ActionMailer::Base.smtp_settings[:user_name] = Rails.application.secrets.smtp_user_name
      ActionMailer::Base.smtp_settings[:password]  = Rails.application.secrets.smtp_password
    end
    

    In config/secrets.yml you need set those credentials:

    development:
      secret_key_base: 123...
      smtp_domain: example.org
      smtp_user_name: postmaster@oderq.com
      smtp_password: <%= ENV["SMTP_PASSWORD"] %>
    
    test:
      secret_key_base: c7f3f62597b14c7287d75c239168fd3a89d3a6cb51beb909679c2609e912aaa3ca0a0aa5df2e191648baed6fe49698527a75dd265d222697576405971f478c98
    
    staging:
      secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
      smtp_domain: example.net
      smtp_user_name: staging_user@example.net
      password: <%= ENV["SMTP_PASSWORD"] %>
    
    production:
      secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
      smtp_domain: example.com
      smtp_user_name: user@example.com
      smtp_password: <%= ENV["SMTP_PASSWORD"] %>

    And that’s it! Enjoy bringing SMTP credentials into Rails >4.0 secrets management.