DEV Community

Dale Zak
Dale Zak

Posted on • Updated on

Rails Environment Variables Using Credentials

In your Rails app, do you use ENV or Rails.application.credentials? Is there an easy way to use both? Lets find out.

I've been a long time fan of Figaro, a great gem that lets your store your environment variables in /config/application.yml. I've used it in most of my Rails apps for two reasons. One, it lets you easily define variables for your for development, staging, production environments. Two, it works well with Heroku since they also use ENV for storing and accessing environment variables, so things work the same locally while developing as well as after it's been deployed. However the downside with Figaro is that all your environment variables are exposed to the outside world, which is problematic if your repo is open source.

Rails.application.credentials helps solve this problem by encrypting your environment variables in config/credentials.yml.enc so they are only readable with the key providing a secure way to store them. However the downside, is your environment variables are now stored and accessed in two different ways, using Rails.application.credentials and ENV if you are also using Heroku.

It would be a lot more convenient, if you could define your variables in Rails.application.credentials so they are encrypted and secure, yet still access them using ENV so both local and remote environment variables are consistent.

You can do this easily by adding the following into /config/application.rb.

credentials.config.each do |key, value|
  if key.to_s == Rails.env
    value.each do |env_key, env_value|
      ENV[env_key.to_s.upcase] = env_value.to_s if ENV[env_key.to_s.upcase].blank?
      ENV[env_key.to_s.downcase] = env_value.to_s if ENV[env_key.to_s.downcase].blank?
    end
  elsif ['development', 'staging', 'test', 'production'].include?(key.to_s) == false
    ENV[key.to_s.upcase] = value.to_s if ENV[key.to_s.upcase].blank?
    ENV[key.to_s.downcase] = value.to_s if ENV[key.to_s.downcase].blank?
  end
end
Enter fullscreen mode Exit fullscreen mode

Now you have the best of both worlds, security plus accessibility. You can now access all your environment variables via ENV whether they are defined in Heroku or in Rails.application.credentials.

ENV['HEROKU_APP_NAME'] # access Heroku defined variables
ENV['GITHUB_API_KEY'] # access variables from your credentials
ENV['git_api_key'] # also access variables in lowercase
ENV['rails_env_key'] # access environment specific variables
Enter fullscreen mode Exit fullscreen mode

The snippet only sets the ENV if it's not already defined. It also handles global or environment specific variables in your Rails.application.credentials.

You can copy and paste the initializer above, or you can run the following template to add it to your project.

rails app:template LOCATION="https://railsbytes.com/script/Vp7s90"
Enter fullscreen mode Exit fullscreen mode

Discussion (0)