secure_credentials 0.1.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: 67f34834484a909ed1ca0cdb4da8d09a57f9c1f2381237c6a22f95081827d4c9
4
+ data.tar.gz: 2da212d3f2e4941c269937cbb40484b2e27d5d38609c224ca92a3b4d1af8d258
5
+ SHA512:
6
+ metadata.gz: b0bbf47d6d142af404268bbfe991c40e9f502dc065e780fdcf2d6fa003c7bc6eaf374ee7c2a2d9aa2d4795266e2c561641d115425ee539afce23b803b9542577
7
+ data.tar.gz: a6284aa14dd2998ca6cb6ca5fdd0bab26f5274a978704cf4339fc961ddca7df780352057b612a3f12786f782f659f4d247ad748de2ede16aaf951cd1eee7146d
data/.codeclimate.yml ADDED
@@ -0,0 +1,8 @@
1
+ checks:
2
+ method-complexity:
3
+ config:
4
+ threshold: 6 # should be just fine
5
+
6
+ plugins:
7
+ rubocop:
8
+ enabled: true
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,44 @@
1
+ # This config aims:
2
+ #
3
+ # - compact, readable and reusable source,
4
+ # - consistent constructions (same things stay the same in different context),
5
+ # - consistent indentation,
6
+ # - avoiding unnecessary lines in diffs
7
+ # - wise usage of Ruby features and expressiveness.
8
+
9
+ AllCops:
10
+ TargetRubyVersion: 2.2
11
+
12
+ Layout/AlignParameters: {EnforcedStyle: with_fixed_indentation}
13
+
14
+ # Allows copy-pasting to repl.
15
+ Layout/DotPosition: {EnforcedStyle: trailing}
16
+
17
+ Layout/SpaceInsideHashLiteralBraces: {EnforcedStyle: no_space}
18
+
19
+ # # Keep everything consistent.
20
+ Layout/SpaceBeforeBlockBraces: {EnforcedStyleForEmptyBraces: space}
21
+
22
+ # Offences named scopes and `expect {}.to change {}`.
23
+ Lint/AmbiguousBlockAssociation: {Enabled: false}
24
+
25
+ # It's removed from next rubocop version.
26
+ Lint/SplatKeywordArguments: {Enabled: false}
27
+
28
+ # Other metrics are just enough.
29
+ # This one offences all specs, routes and some initializers.
30
+ Metrics/BlockLength: {Enabled: false}
31
+ Metrics/LineLength: {Max: 100}
32
+ Metrics/MethodLength: {Max: 30}
33
+
34
+ Style/Alias: {EnforcedStyle: prefer_alias_method}
35
+
36
+ Style/FrozenStringLiteralComment: {EnforcedStyle: never}
37
+
38
+ Style/Lambda: {EnforcedStyle: literal}
39
+
40
+ Style/RescueStandardError: {EnforcedStyle: implicit}
41
+ Style/SignalException: {EnforcedStyle: only_raise}
42
+
43
+ Style/TrailingCommaInArrayLiteral: {EnforcedStyleForMultiline: consistent_comma}
44
+ Style/TrailingCommaInHashLiteral: {EnforcedStyleForMultiline: consistent_comma}
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.5
6
+ - 2.4
7
+
8
+ notifications:
9
+ email: false
10
+
11
+ # for 2.5.0 until 2.5.1 is released:
12
+ # https://github.com/travis-ci/travis-ci/issues/8978
13
+ # https://github.com/travis-ci/travis-ci/issues/8969#issuecomment-354135622
14
+ before_install:
15
+ - gem update --system
16
+ - gem install bundler
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in gemspec file
6
+ gemspec
7
+
8
+ gem 'rspec', '~> 3.7'
9
+ gem 'rspec-its', '~> 1.2'
10
+
11
+ gem 'rubocop', '~> 0.56'
12
+
13
+ gem 'pry', '~> 0.11'
14
+ gem 'pry-byebug', '~> 3.6'
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # SecureCredentials
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/secure_credentials.svg)](http://badge.fury.io/rb/secure_credentials)
4
+ [![Code Climate](https://codeclimate.com/github/printercu/secure_credentials/badges/gpa.svg)](https://codeclimate.com/github/printercu/secure_credentials)
5
+ [![Build Status](https://travis-ci.org/printercu/secure_credentials.svg)](https://travis-ci.org/printercu/secure_credentials)
6
+
7
+ Makes it possible to use best of encrypted credentials
8
+ and environment-dependent secrets. Sharing encryption keys with
9
+ every developer in a team is a security issue, and purpose of this gem
10
+ is to help you to avoid it.
11
+
12
+ ## Rationale
13
+
14
+ Rails 5.2 brings good idea of storing encrypted credentials in the repo:
15
+ credentials are securely tracked in version control, less chances to face an issue
16
+ during deployment, etc. However there are several drawbacks in current implementation:
17
+
18
+ - It's hard to manage environment-specific credentials.
19
+ For example, use some different browser api keys in development and production,
20
+ one is whitelisted for `locahost` and other one for app's domain.
21
+ - In most cases it's required to share `master.key` with every developer.
22
+ This is not acceptable for a lot of teams, and framework must serve their needs too.
23
+
24
+ There are a couple ways to workaround this issues, but all of them brings
25
+ unnecessary complexity. This gem takes best from new encrypted `credentials.yml.enc`
26
+ and multi-environmental `secrets.yml`. It allows to use combination
27
+ of encrypted and plain files for same configuration in different environments.
28
+ For example, having encrypted `credentials.production.yml.enc` for production
29
+ and multi-environmental `credentials.yml` for all other environments.
30
+
31
+ ## Installation
32
+
33
+ Add this line to your application's Gemfile:
34
+
35
+ ```ruby
36
+ gem 'secure_credentials'
37
+ ```
38
+
39
+ And then execute:
40
+
41
+ $ bundle
42
+
43
+ ## Usage
44
+
45
+ By default this gem patches Rails::Application to make `#credentials`, `#secrets` and `#encrypted`
46
+ use Rails-compatible wrapper around SecureCredentials::Store.
47
+
48
+ SecureCredentials::Store provides read-write interface for YAML configuration files. It supports:
49
+
50
+ - both encrypted and plain files,
51
+ - both file-per-environment and multi-environment files.
52
+
53
+ It takes base path of configuration file (for example, `config/secrets`)
54
+ and environment value. Then it tries to find the most appropriate file
55
+ for this configuration in following order:
56
+
57
+ "#{base}.#{env}.yml.enc"
58
+ "#{base}.#{env}.yml"
59
+ "#{base}.yml.enc"
60
+ "#{base}.yml"
61
+
62
+ If environment specific file is present, it's whole content is returned.
63
+ Otherwise `env` is used to fetch appropriate section.
64
+
65
+ Key for decoding encoded files can be passed:
66
+
67
+ - in `key` argument;
68
+ - envvar identified by `env_key`, default is to upcased basename appended with `_KEY`
69
+ (ex., `SECRETS_KEY`);
70
+ - in file found at `key_path`,
71
+ by default it uses filename and replaces `.yml.enc` with `.key`
72
+ (`secrets.production.key` for `secrets.production.yml.enc`);
73
+ - `SecureCredentials.master_key` which is read from `config/master.key` in Rails apps.
74
+
75
+ Use `rails encrypted path/to/file.yml.enc -k path/to/key.key` to edit encrypted files.
76
+ Missing `.key` and `.yml` files are automatically created when you edit them for the first time.
77
+
78
+ ## Best practices
79
+
80
+ - __Don't keep master.key in local repo!__
81
+
82
+ It's the as PIN-code written on backside of credit card.
83
+ Keep it in secure place and use it when you need to modify credentials.
84
+
85
+ - Don't share production credentials with those who must not access them.
86
+
87
+ Secrets get less secret every time they are shared.
88
+
89
+ ## Development
90
+
91
+ After checking out the repo, run `bin/setup` to install dependencies.
92
+ Then, run `rake spec` to run the tests.
93
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
94
+
95
+ To install this gem onto your local machine, run `bundle exec rake install`.
96
+ To release a new version, update the version number in `version.rb`,
97
+ and then run `bundle exec rake release`, which will create a git tag for the version,
98
+ push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
99
+
100
+ ## Contributing
101
+
102
+ Bug reports and pull requests are welcome on GitHub at
103
+ https://github.com/printercu/secure_credentials.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'secure_credentials'
5
+
6
+ require 'pry'
7
+ Pry.start
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ pattern=$(echo -n '\.rb
4
+ \.gemspec
5
+ \.jbuilder
6
+ \.rake
7
+ config\.ru
8
+ Gemfile
9
+ Rakefile' | tr "\\n" '|')
10
+
11
+ files=`git diff --cached --name-status | grep -E "^[AM].*($pattern)$" | cut -f2-`
12
+ if [ -n "$files" ]; then
13
+ bundle exec rubocop $files --force-exclusion
14
+ fi
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path('../', __dir__)
4
+ hooks_dir = "#{root}/bin/git-hooks"
5
+
6
+ `ls -1 #{hooks_dir}`.each_line.map(&:strip).each do |file|
7
+ `ln -sf #{hooks_dir}/#{file} #{root}/.git/hooks/#{file}`
8
+ end
data/bin/setup ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
9
+ bin/install_git_hooks
@@ -0,0 +1,24 @@
1
+ require 'secure_credentials/version'
2
+
3
+ # Makes it possible to use best of encrypted credentials
4
+ # and environment-dependent secrets. Sharing encryption keys with
5
+ # every developer in a team is a security issue, and purpose of this gem
6
+ # is to help you to avoid it.
7
+ module SecureCredentials
8
+ class FileNotFound < StandardError; end
9
+
10
+ module_function
11
+
12
+ attr_writer :master_key
13
+
14
+ def master_key
15
+ return @master_key if @master_key
16
+ return unless defined?(::Rails)
17
+ key_path = ::Rails.root.join('config/master.key')
18
+ key_path.binread.strip if key_path.exist?
19
+ end
20
+ end
21
+
22
+ require 'secure_credentials/store'
23
+ require 'secure_credentials/credentials'
24
+ require 'secure_credentials/rails' if defined?(Rails)
@@ -0,0 +1,31 @@
1
+ require 'active_support/ordered_options'
2
+ require 'active_support/core_ext/hash/keys'
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ module SecureCredentials
6
+ # Wraps store into compatible with Rails::Application#credentials interface.
7
+ class Credentials
8
+ attr_reader :store
9
+ private :store
10
+
11
+ delegate_missing_to :data
12
+
13
+ def initialize(store)
14
+ @store = store
15
+ end
16
+
17
+ # Required by `rails encrypted` command.
18
+ delegate :change, :read, to: :store
19
+
20
+ # Required by `rails encrypted` command.
21
+ def key
22
+ store.send(:encrypted_file).key if store.encrypted?
23
+ rescue ActiveSupport::EncryptedFile::MissingKeyError
24
+ nil
25
+ end
26
+
27
+ def data
28
+ @data ||= ActiveSupport::OrderedOptions.new.merge(store.content.deep_symbolize_keys)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ require 'securerandom'
2
+ require 'active_support/encrypted_file'
3
+
4
+ module SecureCredentials
5
+ # Wraps ActiveSupport::EncryptedFile and provides passing key as an argument.
6
+ # Automatically generates missing key filenames based on store filename.
7
+ class EncryptedFile < ActiveSupport::EncryptedFile
8
+ class << self
9
+ # Same file name but with `.key` extension instead of `.enc`.
10
+ def default_key_path_for(filename)
11
+ filename.sub_ext('.key')
12
+ end
13
+ end
14
+
15
+ def initialize(path, key = nil, key_path: nil, env_key: nil)
16
+ @key = key
17
+ super(
18
+ content_path: path,
19
+ key_path: key_path || self.class.default_key_path_for(path),
20
+ env_key: env_key,
21
+ raise_if_missing_key: true,
22
+ )
23
+ end
24
+
25
+ def key
26
+ @key || read_env_key || read_key_file || SecureCredentials.master_key || handle_missing_key
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ # Use `gem 'rails-secure_credentials', require: 'secure_credentials/no_rails_patch'
2
+ # to load gem without patching rails.
3
+ RAILS_SECURE_CREDENTIALS_SKIP_PATCH = true
4
+ require 'secure_credentials'
@@ -0,0 +1,4 @@
1
+ unless defined?(RAILS_SECURE_CREDENTIALS_SKIP_PATCH)
2
+ require 'secure_credentials/rails/application_methods'
3
+ Rails::Application.prepend SecureCredentials::Rails::ApplicationMethods
4
+ end
@@ -0,0 +1,27 @@
1
+ require 'secure_credentials/credentials'
2
+ require 'secure_credentials/store'
3
+
4
+ module SecureCredentials
5
+ module Rails
6
+ # Provides patch for Rails::Application, to make it use SecureCredentials
7
+ # as a replacement for built-in `#credentials` and `#secrets`.
8
+ module ApplicationMethods
9
+ def secrets
10
+ @secrets ||= read_secure_credentials('config/secrets')
11
+ end
12
+
13
+ def credentials
14
+ @credentials ||= read_secure_credentials('config/credentials')
15
+ end
16
+
17
+ def read_secure_credentials(path, key_path: nil, **options)
18
+ key_path &&= ::Rails.root.join(key_path)
19
+ store = Store.new(::Rails.root.join(path), key_path: key_path, env: ::Rails.env, **options)
20
+ Credentials.new(store)
21
+ end
22
+
23
+ # Override default #credentials method.
24
+ alias_method :encrypted, :read_secure_credentials
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,113 @@
1
+ require 'secure_credentials/encrypted_file'
2
+ require 'yaml'
3
+
4
+ module SecureCredentials
5
+ # Store provides read-write interface for YAML configuration files. It supports:
6
+ #
7
+ # - both encrypted and plain files,
8
+ # - both file-per-environment and multi-environment files.
9
+ #
10
+ # It takes base path of configuration file (for example, `config/secrets`)
11
+ # and environment value. Then it tries to find the most appropriate file
12
+ # for this configuration in following order:
13
+ #
14
+ # "#{base}.#{env}.yml.enc"
15
+ # "#{base}.#{env}.yml"
16
+ # "#{base}.yml.enc"
17
+ # "#{base}.yml"
18
+ #
19
+ # Key for decoding encoded files can be passed:
20
+ #
21
+ # - in `key` argument;
22
+ # - envvar identified by `env_key`, default is to upcased basename appended with `_KEY`
23
+ # (ex., `SECRETS_KEY`);
24
+ # - in file found at `key_path`,
25
+ # by default it uses filename and replaces `.yml.enc` with `.key`
26
+ # (`secrets.production.key` for `secrets.production.yml.enc`);
27
+ # - SecureCredentials.master_key.
28
+ #
29
+ # If environment specific file is present, it's whole content is returned.
30
+ # Otherwise `env` is used to fetch appropriate section.
31
+ class Store
32
+ class << self
33
+ # Finds the most appropriate existing file for given path and env.
34
+ # Returns `[environmental?, encrypted?, filename]`.
35
+ def detect_filename(path, env)
36
+ stub_ext_path = Pathname.new("#{path}.stub")
37
+ if path.basename.to_s.include?('.yml')
38
+ [false, path.basename.to_s.end_with?('.enc'), path]
39
+ else
40
+ [
41
+ [true, true, stub_ext_path.sub_ext(".#{env}.yml.enc")],
42
+ [true, false, stub_ext_path.sub_ext(".#{env}.yml")],
43
+ [false, true, stub_ext_path.sub_ext('.yml.enc')],
44
+ [false, false, stub_ext_path.sub_ext('.yml')],
45
+ ].find { |x| x[2].exist? }
46
+ end
47
+ end
48
+
49
+ def env_key_for(path)
50
+ "#{path.basename.to_s.upcase}_KEY"
51
+ end
52
+
53
+ # ERB -> YAML.safe_load with aliases support.
54
+ def load_yaml(string)
55
+ YAML.safe_load(ERB.new(string).result, [], [], true)
56
+ end
57
+ end
58
+
59
+ attr_reader :path, :filename, :env, :environmental, :encrypted
60
+ alias_method :environmental?, :environmental
61
+ alias_method :encrypted?, :encrypted
62
+
63
+ def initialize(path, key = nil, env: nil, key_path: nil, env_key: nil)
64
+ @path = path = Pathname.new(path)
65
+ @env = env
66
+ @environmental, @encrypted, @filename = self.class.detect_filename(path, env)
67
+ @key = key
68
+ @key_path = key_path || filename && filename.sub_ext('').sub_ext('.key')
69
+ @env_key = env_key || self.class.env_key_for(path)
70
+ end
71
+
72
+ # Fetches appropriate environmental content or returns whole content
73
+ # in the case of single-environment file.
74
+ def content
75
+ result = environmental? ? full_content : full_content[env.to_s]
76
+ result || {}
77
+ end
78
+
79
+ # Read file content.
80
+ def read
81
+ return '' unless filename && filename.exist?
82
+ if encrypted?
83
+ encrypted_file.read
84
+ else
85
+ filename.read
86
+ end
87
+ end
88
+
89
+ # Prepares file for edition, yields filename and then saves updated file.
90
+ def change(&block)
91
+ raise FileNotFound, "File not found for '#{path}'" unless filename && filename.exist?
92
+ if encrypted?
93
+ encrypted_file.change(&block)
94
+ else
95
+ yield filename
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ attr_reader :key, :key_path, :env_key
102
+
103
+ def full_content
104
+ string = read
105
+ result = self.class.load_yaml(string) if string.present?
106
+ result || {}
107
+ end
108
+
109
+ def encrypted_file
110
+ EncryptedFile.new(filename, key, key_path: key_path, env_key: env_key)
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,3 @@
1
+ module SecureCredentials
2
+ VERSION = '0.1.1'.freeze
3
+ end
@@ -0,0 +1,26 @@
1
+
2
+ lib = File.expand_path('lib', __dir__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'secure_credentials/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'secure_credentials'
8
+ spec.version = SecureCredentials::VERSION
9
+ spec.authors = ['Max Melentiev']
10
+ spec.email = ['melentievm@gmail.com']
11
+
12
+ spec.summary = 'Rails credentials without security issues. With environments support.'
13
+ spec.homepage = 'https://github.com/printercu/secure_credentials'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'activesupport', '~> 5.2'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.16'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: secure_credentials
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Max Melentiev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-06-01 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.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description:
56
+ email:
57
+ - melentievm@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".codeclimate.yml"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".rubocop.yml"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/git-hooks/pre-commit
72
+ - bin/install_git_hooks
73
+ - bin/setup
74
+ - lib/secure_credentials.rb
75
+ - lib/secure_credentials/credentials.rb
76
+ - lib/secure_credentials/encrypted_file.rb
77
+ - lib/secure_credentials/no_rails_patch.rb
78
+ - lib/secure_credentials/rails.rb
79
+ - lib/secure_credentials/rails/application_methods.rb
80
+ - lib/secure_credentials/store.rb
81
+ - lib/secure_credentials/version.rb
82
+ - secure_credentials.gemspec
83
+ homepage: https://github.com/printercu/secure_credentials
84
+ licenses: []
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.7.6
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Rails credentials without security issues. With environments support.
106
+ test_files: []