config icon indicating copy to clipboard operation
config copied to clipboard

Integration with encrypted Rails credentials

Open smith opened this issue 10 years ago • 13 comments

Rails 4.1 introduces a built-in convention for having a secrets.yml with secrets in it: http://edgeguides.rubyonrails.org/4_1_release_notes.html#config-secrets-yml

It would be cool if this gem did some of these things:

  • Aliased Rails.application.secrets to Settings.secrets
  • Shimmed the secrets.yml functionality in for Rails < 4.1
  • Allowed you to have a secrets.local.yml or config/secrets/production.yml that behave the same way as the existing conventions do for non-secrets files

I think this gem is a better overall solution to managing configuration, but if Rails is making this a thing, it would make sense to go along with it and make this gem work nicely with the new stuff.

smith avatar Mar 07 '14 05:03 smith

Will be great

Darkside73 avatar Aug 18 '14 14:08 Darkside73

@rdubya would you like to have a look at this one?

pkuczynski avatar Jun 28 '19 19:06 pkuczynski

Rails 5 gets away from using secrets and now has a credentials file. It would be cool to have similar functionality built into this gem since it provides a much more flexible way of managing environment settings.

rdubya avatar Jul 01 '19 13:07 rdubya

I think we could add alias Rails.application.secrets to Settings.secrets if anybody is interested in this. However, I would keep the way secrets.yml work meaning with environments groups.

@smith @Darkside73 are you still interested in this?

pkuczynski avatar Aug 06 '19 16:08 pkuczynski

FYI This bug caused me so much pain...

the config gem eager loads credentials, causing any overrides to not be respected in config/application.rb

smtlaissezfaire avatar Oct 23 '23 23:10 smtlaissezfaire

@smtlaissezfaire I would welcome a PR fixing this. Would like to have a look? I no longer work with Rails for few years now so it would be hard for me to get back to it...

pkuczynski avatar Oct 24 '23 07:10 pkuczynski

Just sharing my workaround to work with Rails.application.credentials. Not sure if this the best solution, but this monkey patch works for me to utilize Setting and Rails secret management.

# config/initializers/config.rb
module Config
  def self.load_files(*sources)
    config = Options.new

    # add settings sources
    [sources].flatten.compact.each do |source|
      config.add_source!(source)
    end

    config.add_source!(Sources::EnvSource.new(ENV)) if Config.use_env
    load_credentials(config) # call Settings override
    config.load!
    config
  end
 
  # override with crendentials
  def self.load_credentials(config)
    if Rails.env.production? || Rails.env.staging?
      # Load and replace secret from credentials
      config.add_source!(Rails.application.credentials.to_h)
    end
  end
end

Config.setup do |config|
  # your config
end

noxasch avatar Feb 12 '24 16:02 noxasch

@noxasch I like the idea of merging the Rails credentials into the Settings exported by config. I think that's probably the most ergonomic workflow: all configuration lives in Settings, but you can still use encrypted credentials (they just get merged in)

I could use help understanding why the monkey patch is necessary, though. If, in an initializer, you just

Settings.add_source!(Rails.application.credentials.to_h)
Settings.reload!

Does that work? Or does it not have the opportunity to pick up the credentials correctly?

cjlarose avatar Feb 12 '24 19:02 cjlarose

@cjlarose Yup correct, you can also do that. As for me I want to load the Settings when the config gem is being initialize. So everything related to Settings work as if it is part of the gem. Probably better if the gem allow us to include a block before the config first load though.

noxasch avatar Feb 13 '24 02:02 noxasch

Yeah, that makes sense. In a non-Rails application, config doesn't do anything automatically and the user has the opportunity to customize everything that gets merged into Settings (specific YAML files, hard-coded Hashes, environment variables, etc), but the Rails integration makes some assumptions and performs the first load before the user has the chance to customize anything. That's a separate issue. In the meantime, I'm open to a PR that adds a new (off by default) setting Config.use_rails_credentials that would basically just do what @noxasch 's patch does.

Config.setup do |config|
  config.use_rails_credentials = true
end

I think we might have to use something like Rails.application.credentials.to_h.deep_stringify_keys though in order for merging to work correctly with other config sources.

cjlarose avatar Feb 13 '24 19:02 cjlarose

@noxasch would you like to fire up a PR for this change?

pkuczynski avatar Feb 18 '24 19:02 pkuczynski

Sure I can work on a PR for this @pkuczynski

noxasch avatar Feb 19 '24 06:02 noxasch

Is any help still needed? I'd like to have it in my project too and I see needs help badge, but I'm not getting what help is still needed.

dominh avatar Apr 22 '24 20:04 dominh