There are several posts ans Stack Overflow questions about how to manage API tokens on the web, but I see a lot of people repeat what they read somewhere else, often with contradictions...
How do you deal with API Tokens, secrets and the like ?
Here's what I have read so far using 3 different gems
secrets.yml
Introduced with Rails 4.1, then updated to encrypted secrets around rails 5
When initially released on rails 4, they were (or were not ?) meant to be pushed on repositories. However I often saw examples using environment variables for production
# config/secrets.yml
development:
secret_key_base: super_long_secret_key_for_development
...
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
...
And at this point someone asked "Why do we use ENV for production ?". A legit question back then, often answered "We don't want production token to be hard coded in the application" (hence how it is not clear anymore if the secrets should have been committed or not).
Later, with Rails 5, secrets became encrypted with a master key, so the encrypted secrets.yml file could be committed to the repository, but then the problem remained the same with the master key used to read the secrets.
PROs:
- Rails convention.
- Easy deploy with
capistrano-secrets
gem andcap [stage] setup
(and it only deploys stage secrets nice) or similar gems - YML data structure (array/hash ok) + can use Ruby code via ERB
- With encrypted secrets since rails 5, easy to collaborate/share the secrets
CONs:
- Need to use
Rails.application.secrets.xxx
- Many services like AWS still read from ENV to automatically setup their gems/services
- Is not the 12 factors way (or is it ?)
- Quite new, so not really used yet ?
- If using encrypted secrets, need to manage the master key
Bkeepers dotenv
Simply defining a .env file at the root that is read by Rails on startup
Plugins like capistrano-env
allow to easily inject environment specific ENV on servers, and secrets can still must be managed using .env.staging, .env.production
PROs
- ENV is in 12factor rules
- 3.5k stars... maybe not for nothing ?
- the dotenv approach is now available on almost all other languages (JS, Go, etc)
- Recent versions allow reusing variables (API_ROOT=X, SOME_ENDPOINT=${X}/endpoint)
CONs
- No Ruby interpolation (unless extra code is added to parse the .env with the ERB templating engine for example)
- limited to string-string key/val
Figaro
Some sort of hybrid secrets/ENV. With 12factors/Rails/Heroku in mind, but in the end doesn't seem better than the rest...
From the above and the rest I didn't write, it would seem like secrets.yml would be a great winner if those secrets were put in ENV instead (and tbh I feel lazy about writing Rails.Application.secrets
each time).
So, suppose I start a quite new Rails app, and also based on your experience. Which one would you choose ?
(My particular stack uses AWS + Capistrano, no Heroku)