简体   繁体   中英

When trying to configure Rails Ruby or jRuby app the secret key is visible in the YAML file. Is there a gem that will provide this at runtime?

There are lots of secrets that apps have that need to be secured in production when running in public cloud and PaaS environments. Common one is database.yml entries for mysql user and password, but there can be others. Your Google App secret, facebook app secret,... the list goes on. There are no clear way of securing these essentially configuration parameters. You DO NOT want to put these in a file as there is no guarantee who will have access to it.

In Heroku you can specify things via environment variables. In Cloudbees (a Java PaaS) you can specify these as Java System properties. Both Heroku and Cloudbees have a commandline utility for uploading this configuration parameters but there is no support for making this work both in development and production easily.

Question is how do you configure your parameters so that you can develop easily in development but not have the production secret be available in development

Ideally there would be a gem that will work in ruby and jruby environment and PaaS that will allow me to specify me secrets in a YML file that has development settings in development but actual production secrets pulled in from ENV or java.lang.System.getProperty .

##
# file: config/secure_config.yml
development:
  db:
    user_id: 'dev_mysql_user'
    password: 'my_dev_pwd'
  google:
    app_id: 'xxxxx' # this is the secret for the dev app so it can be visible
    app_secret: 'xxxxx'
# ...
production:
  db:
    user_id: <%= get_secure_config %>
    password: <%= get_secure_config %>
  google:
    app_id: <%= get_secure_config %>
    app_secret: <%= get_secure_config %>

Where the get_secure_config helper gets the value from ENV or java.lang.System.getProperty in case of Ruby or jRuby. The finally you can use them in your app as needed. For example in database.yml or in the devise code to authenticate using google.

# config/database.yml
# ...
production:
  adapter: mysql2
  username: <%= SecureConfig.db.user_id %>
  password: <%= SecureConfig.db.password %>

And then for extra coolness the gem should also give me an executable that allows me to push the config to my PaaS

~/work/myproject> bundle exec secure_config -push_to_heroku

or

~/work/myproject> bundle exec secure_config -push_to_cloudbees

Check out Figaro . It's almost exactly what you're after.

You place your sensitive data in a git-ignored YAML file, which are then made available to the app in ENV . It also provides a rake task for configuring your Heroku instance with the variables.

As Daniel Wright suggested above Figaro is great! It does every thing I need for ruby on rails. I needed the same support on JRuby on rails and properties via JVM system properties for Cloudbees PaaS service as well. I have forked Figaro and made these extensions and sent a pull request to laserlemon/Figaro. In the mean time you can pull it using git directive in your gem file.

gem 'figaro', '0.4.2', :git => "git://github.com/RedMicaInc/figaro.git"

Main differences are documented below

How does it work?

It works really well.

There are a few similar solutions out there, and a lot of homegrown attempts. Most namespace your configuration under a Config (or similar) namespace. That's fine, but there's already a place to describe the application environment… ENV !

ENV is a collection of simple string key/value pairs and it works just great for application configuration.

These configuration parameters are also then made available as properties of FigaroSettings object. So if you had a property called MY_PROP you can use it in your code or configuration files using FigaroSettings.my_prop or FigaroSettings.MY_PROP

For JRUBY based applications properties stored in JVM system properties are also available in a similar manner. For instance if you had a property called MY_JAVA_PROP it is accessible as FigaroSettings.MY_JAVA_PROP . Java properties are case sensitive.

As an added bonus, this is exactly how apps on Heroku or Cloudbees are configured. So if you configure your Rails app using ENV , you're already set to deploy to Heroku. For Cloudbees you can use ENV or JVM properties similarly using FigaroSettings.<property>

How does it work with Cloudbees?

Cloudbees provides application configuration in a similar manner.

Typically, to configure your application parameters accessible via JVM system properties, you would do the following from the command line using the cloudbees sdk:

cloudbees config:set -a <my_app> PUSHER_APP_ID=8926
cloudbees config:set -a <my_app> PUSHER_KEY=0463644d89a340ff1132
cloudbees config:set -a <my_app> PUSHER_SECRET=0eadfd9847769f94367b

But Figaro provides a rake task to do just that! Just run:

rake figaro:cloudbees

Optionally, you can pass in the name of the Cloudbees app:

rake figaro:cloudbees[my-awesome-app]

If you just want to see the commands used you can run rake figaro:heroku_test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM