rails_environment_credentials 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8831db67391191047589682a975a189698cf6ba971835a9057b3d9e308938b50
4
+ data.tar.gz: 7879944840d8771d97098524cb9792ea66049365cc3f92a7db75581f7bcc61e9
5
+ SHA512:
6
+ metadata.gz: 7898632f7087e6e5b922c5b29c61e1410287efa114ec67512cc81caf9f6297149bb4243baf6b25b5e74f645334cc8eeaef5a2eda5a1c9f6679cd89a17bd6f7b2
7
+ data.tar.gz: ac3c92f5610a920d5c0b46f172a72fb75cf0e4a573e58b77277d5d5dba6cd92487f89307b208b73369a2dfbed3683eff383ee0bdbf50362439ebd2612c4d60a4
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # rails-environment-credentials
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module Application
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def credentials
9
+ @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path, key: credentials_key)
10
+ end
11
+
12
+ def encrypted(path, key_path: 'config/master.key', env_key: 'RAILS_MASTER_KEY', key: nil)
13
+ ActiveSupport::EncryptedConfiguration.new(
14
+ config_path: Rails.root.join(path),
15
+ key_path: Rails.root.join(key_path),
16
+ env_key: env_key,
17
+ key: key,
18
+ raise_if_missing_key: config.require_master_key
19
+ )
20
+ end
21
+ end
22
+
23
+ def credentials_key_strategy
24
+ @credentials_key_strategy ||= RailsEnvironmentCredentials::KeyStrategies.
25
+ get(config.credentials.key_strategy).
26
+ new(config.credentials.key_strategy_options)
27
+ end
28
+
29
+ def credentials_key
30
+ @credentials_key ||= credentials_key_strategy.key
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module Configuration
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attr_accessor :credentials
9
+ end
10
+
11
+ def initialize(*)
12
+ super
13
+ @credentials = ActiveSupport::OrderedOptions.new
14
+ @credentials.merge! credentials_config
15
+ @credentials.environment ||= default_credentials_environment
16
+ @credentials.content_path ||= default_credentials_content_path
17
+ @credentials.key_path ||= default_credentials_key_path
18
+ end
19
+
20
+ private
21
+
22
+ def credentials_config
23
+ path = root.join('config/credentials.yml')
24
+ @credentials_config ||= (path.exist? ? YAML.safe_load(path.read) : {}).symbolize_keys
25
+ end
26
+
27
+ def default_credentials_environment
28
+ ENV.fetch('RAILS_CREDENTIALS_ENV') { Rails.env }
29
+ end
30
+
31
+ def default_credentials_content_path
32
+ root.join('config', 'credentials', "#{credentials.environment}.yml.enc")
33
+ end
34
+
35
+ def default_credentials_key_path
36
+ root.join('config', 'credentials', "#{credentials.environment}.key")
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module EncryptedConfiguration
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:, key: nil)
9
+ super(content_path: config_path, key_path: key_path, env_key: env_key, raise_if_missing_key: raise_if_missing_key, key: key)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module EncryptedFile
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:, key: nil)
9
+ @content_path = Pathname.new(content_path)
10
+ @key_path = Pathname.new(key_path)
11
+ @env_key = env_key
12
+ @raise_if_missing_key = raise_if_missing_key
13
+ @key = key unless key.nil?
14
+ end
15
+
16
+ def key
17
+ @key || read_env_key || read_key_file || handle_missing_key
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module KeyStrategies
5
+
6
+ class AzureKeyVaultManagedIdentity < Base
7
+
8
+ def access_token
9
+ response = HTTParty.get( # rubocop:disable Style/RescueModifier
10
+ 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net',
11
+ {
12
+ headers: { Metadata: 'true' },
13
+ timeout: 1,
14
+ open_timeout: 1,
15
+ read_timeout: 1,
16
+ }
17
+ ) rescue nil
18
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity access_token: unable to get' unless response
19
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity access_token: unable to parse response' unless response.parsed_response.is_a?(Hash)
20
+ token = response.parsed_response['access_token']
21
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity access_token: fetch failed' unless token.present?
22
+ token
23
+ end
24
+
25
+ def vault_url
26
+ @vault_url ||= if options.key?(:vault_url)
27
+ options[:vault_url]
28
+ elsif options[:vault]
29
+ "https://#{options[:vault]}.vault.azure.net/"
30
+ else
31
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity vault_url: must supply either vault or vault_url'
32
+ end
33
+ end
34
+
35
+ def secret_name
36
+ @secret_name ||= if options.key?(:secret_name)
37
+ options[:secret_name]
38
+ else
39
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity secret_name: must supply secret_name'
40
+ end
41
+ end
42
+
43
+ def secret_url
44
+ @secret_url ||= if options.key?(:secret_url)
45
+ options[:secret_url]
46
+ else
47
+ "#{vault_url}/secrets/#{secret_name}?api-version=2016-10-01"
48
+ end
49
+ end
50
+
51
+ def key
52
+ response = HTTParty.get( # rubocop:disable Style/RescueModifier
53
+ secret_url,
54
+ {
55
+ headers: { Authorization: "Bearer #{access_token}" },
56
+ timeout: 1,
57
+ open_timeout: 1,
58
+ read_timeout: 1,
59
+ }
60
+ ) rescue nil
61
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity key: unable to get secret' unless response
62
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity key: unable to parse response' unless response.parsed_response.is_a?(Hash)
63
+ secret = response.parsed_response['value']
64
+ raise 'CredentialsKeyStrategy AzureKeyVaultManagedIdentity key: fetch failed' unless secret.present?
65
+ secret
66
+ end
67
+
68
+ end
69
+
70
+ add(:azure_key_vault_managed_identity, AzureKeyVaultManagedIdentity)
71
+
72
+ end
73
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module KeyStrategies
5
+ class Base
6
+ attr_reader :options
7
+
8
+ def initialize(opts = {})
9
+ @options = (opts || {}).with_indifferent_access
10
+ end
11
+
12
+ def key
13
+ nil
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module KeyStrategies
5
+
6
+ class None < Base; end
7
+
8
+ add(nil, None)
9
+
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module KeyStrategies
5
+
6
+ class Raw < Base
7
+
8
+ def key
9
+ Rails.application.config.credentials.raw_key
10
+ end
11
+
12
+ end
13
+
14
+ add(:raw, Raw)
15
+
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+ module KeyStrategies
5
+ @map = {}.with_indifferent_access
6
+
7
+ class << self
8
+ attr_reader :map
9
+
10
+ def get(strategy)
11
+ map[strategy] || raise("CredentialsKeyStrategy unknown strategy: #{strategy}")
12
+ end
13
+
14
+ def add(name, klass)
15
+ map[name] = klass
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ require 'rails_environment_credentials/key_strategies/base'
24
+ require 'rails_environment_credentials/key_strategies/none'
25
+ require 'rails_environment_credentials/key_strategies/raw'
26
+ require 'rails_environment_credentials/key_strategies/azure_key_vault_managed_identity'
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsEnvironmentCredentials
4
+
5
+ module Version
6
+ MAJOR = 0
7
+ MINOR = 0
8
+ PATCH = 1
9
+
10
+ end
11
+
12
+ VERSION = [
13
+ Version::MAJOR,
14
+ Version::MINOR,
15
+ Version::PATCH,
16
+ ].join('.').freeze
17
+
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Container Module
4
+ module RailsEnvironmentCredentials; end
5
+
6
+ require 'active_support/concern'
7
+
8
+ require 'rails_environment_credentials/application'
9
+ require 'rails_environment_credentials/configuration'
10
+ require 'rails_environment_credentials/encrypted_configuration'
11
+ require 'rails_environment_credentials/encrypted_file'
12
+ require 'rails_environment_credentials/key_strategies'
13
+ require 'rails_environment_credentials/version'
14
+
15
+ Rails::Application::Configuration.send(:include, RailsEnvironmentCredentials::Configuration)
16
+ Rails::Application.send(:include, RailsEnvironmentCredentials::Application)
17
+ ActiveSupport::EncryptedConfiguration.send(:include, RailsEnvironmentCredentials::EncryptedConfiguration)
18
+ ActiveSupport::EncryptedFile.send(:include, RailsEnvironmentCredentials::EncryptedFile)
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
4
+ require 'rails_environment_credentials/version'
5
+
6
+ Gem::Specification.new do |s| # rubocop:disable Metrics/BlockLength
7
+ s.name = 'rails_environment_credentials'
8
+ s.version = RailsEnvironmentCredentials::VERSION
9
+ s.authors = ['Taylor Yelverton']
10
+ s.email = 'rubygems@yelvert.io'
11
+ s.homepage = 'https://github.com/ComplyMD/rails_environment_credentials'
12
+ s.summary = 'Add support for different credentials for different environments to Rails'
13
+ s.license = 'MIT'
14
+ s.description = 'Add support for different credentials for different environments to Rails'
15
+ s.metadata = {
16
+ 'bug_tracker_uri' => 'https://github.com/ComplyMD/rails_environment_credentials/issues',
17
+ 'changelog_uri' => 'https://github.com/ComplyMD/rails_environment_credentials/commits/master',
18
+ 'documentation_uri' => 'https://github.com/ComplyMD/rails_environment_credentials/wiki',
19
+ 'homepage_uri' => 'https://github.com/ComplyMD/rails_environment_credentials',
20
+ 'source_code_uri' => 'https://github.com/ComplyMD/rails_environment_credentials',
21
+ 'rubygems_mfa_required' => 'true',
22
+ }
23
+
24
+ s.files = Dir['lib/**/*','README.md','MIT-LICENSE','rails_environment_credentials.gemspec']
25
+
26
+ s.require_paths = %w[ lib ]
27
+
28
+ s.required_ruby_version = '>= 2.7.0'
29
+
30
+ s.add_dependency('activesupport', '>= 5.0.0')
31
+ s.add_dependency('railties', '>= 5.0.0')
32
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_environment_credentials
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Taylor Yelverton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-08-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: railties
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 5.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 5.0.0
41
+ description: Add support for different credentials for different environments to Rails
42
+ email: rubygems@yelvert.io
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - README.md
48
+ - lib/rails_environment_credentials.rb
49
+ - lib/rails_environment_credentials/application.rb
50
+ - lib/rails_environment_credentials/configuration.rb
51
+ - lib/rails_environment_credentials/encrypted_configuration.rb
52
+ - lib/rails_environment_credentials/encrypted_file.rb
53
+ - lib/rails_environment_credentials/key_strategies.rb
54
+ - lib/rails_environment_credentials/key_strategies/azure_key_vault_managed_identity.rb
55
+ - lib/rails_environment_credentials/key_strategies/base.rb
56
+ - lib/rails_environment_credentials/key_strategies/none.rb
57
+ - lib/rails_environment_credentials/key_strategies/raw.rb
58
+ - lib/rails_environment_credentials/version.rb
59
+ - rails_environment_credentials.gemspec
60
+ homepage: https://github.com/ComplyMD/rails_environment_credentials
61
+ licenses:
62
+ - MIT
63
+ metadata:
64
+ bug_tracker_uri: https://github.com/ComplyMD/rails_environment_credentials/issues
65
+ changelog_uri: https://github.com/ComplyMD/rails_environment_credentials/commits/master
66
+ documentation_uri: https://github.com/ComplyMD/rails_environment_credentials/wiki
67
+ homepage_uri: https://github.com/ComplyMD/rails_environment_credentials
68
+ source_code_uri: https://github.com/ComplyMD/rails_environment_credentials
69
+ rubygems_mfa_required: 'true'
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.7.0
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubygems_version: 3.1.4
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Add support for different credentials for different environments to Rails
89
+ test_files: []