secret_broker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a88e6fe8ce430e2375d0fcc0f7ec8a55ccd48650
4
+ data.tar.gz: ee181f5988ea46130f21f696200209de8f3552e0
5
+ SHA512:
6
+ metadata.gz: c655a8b8b0d310f62529a5f346385d693abbf135bdef934cb2ea455b0adc26eeecf7cb42f46d11bc211089b53b67dc8099296e8d1ff2a3a56b4dae722c62ec06
7
+ data.tar.gz: b3a77cd6702ef76662e0f7d1e0508db021696dff6ea48ef0b01554928854d22391854be7c029b8b5e52dbbfaa28e22f9bac43fb6616058ec229fc6969358c2a5
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in secret_broker.gemspec
4
+ gemspec
@@ -0,0 +1,99 @@
1
+ # SecretBroker
2
+
3
+ See the usage section for more details
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'secret_broker'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install secret_broker
20
+
21
+ After installing the gem you can run the installation rake task which sets up
22
+ staging and production ejson files with public keys. Command:
23
+
24
+ $ bundle exec rake secret_broker:install_secrets
25
+
26
+ ## Working with Secrets/Usage
27
+
28
+ ### Overview
29
+
30
+ We use EJSON to store secrets for remote environments in the git repo.
31
+ EJSON encrypts secrets so they
32
+ are not stored in plaintext. EJSON files are stored in
33
+ `config/secrets/environment.ejson`. EJSON is only used in remote environments.
34
+ Secrets from EJSON are decrypted when the app boots.
35
+
36
+ ### Accessing Secrets in the Application
37
+
38
+ All application secrets should come from `Rails.application.secrets.secret_key`
39
+ which is loaded from `config/secrets/yml`. Since
40
+ `Rails.application.secrets.secret_key` is cumbersome to write, you can also
41
+ write `Secrets.secret_key`.
42
+
43
+ ### Modifying Secrets
44
+
45
+ ### Local Environment
46
+
47
+ Open up `config/secrets.yml` and change the secret you want to change.
48
+
49
+ #### Remote Environment
50
+
51
+ Open up the EJSON file for the environment you want to change the secret for.
52
+ Find the key for the secret you want to change. Replace the encrypted value
53
+ with the plaintext value. Run `ejson encrypt environment.ejson`. Then add and
54
+ commit the file.
55
+
56
+ Example scenario: I want to change the production database password.
57
+
58
+ Open `config/secrets/production.ejson`. It looks like:
59
+ ```
60
+ {
61
+ "_public_key": "some_value",
62
+ "some_secret_key: "ENCRYPTED_VALUE",
63
+ "database_password": "ENCRYPTED_OLD_PASSWORD",
64
+ "some_other_secret_key: "ENCRYPTED_VALUE"
65
+ }
66
+ ```
67
+
68
+ Modify the file with the new password. It looks like:
69
+ ```
70
+ {
71
+ "_public_key": "some_value",
72
+ "some_secret_key: "ENCRYPTED_VALUE",
73
+ "database_password": "new_plaintext_pa$$w0rd",
74
+ "some_other_secret_key: "ENCRYPTED_VALUE"
75
+ }
76
+ ```
77
+
78
+ Run `ejson encrypt production.ejson`. It looks like:
79
+ ```
80
+ {
81
+ "_public_key": "some_value",
82
+ "some_secret_key: "ENCRYPTED_VALUE",
83
+ "database_password": "ENCRYPTED_NEW_PASSWORD",
84
+ "some_other_secret_key: "ENCRYPTED_VALUE"
85
+ }
86
+ ```
87
+
88
+ Run `git add config/secrets/production.ejson && git commit -m "Updated
89
+ production database password`.
90
+
91
+ ### References
92
+
93
+ [EJSON gem on Github](https://github.com/Shopify/ejson)
94
+
95
+ ## Development
96
+
97
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
98
+
99
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
@@ -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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "secret_broker"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
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
@@ -0,0 +1,49 @@
1
+ require 'secret_broker/dummy_secrets_hash'
2
+ require 'secret_broker/ejson_secrets_file'
3
+ require 'secret_broker/railtie'
4
+ require 'secret_broker/version'
5
+ require 'active_support/core_ext/hash/indifferent_access'
6
+
7
+
8
+ # SecretBroker class for accessing secrets stored using ejson.
9
+ #
10
+ # Usage:
11
+ #
12
+ # Secrets.environment.fetch :key
13
+ #
14
+ # Example (running in production):
15
+ #
16
+ # Secrets.production.database_password
17
+ # => 'pa$$w0rd'
18
+ #
19
+ # Secrets.staging.database_password
20
+ # => 'SECRET VALUE REQUESTED FOR database_password AN ENVIRONMENT OTHER THAN THE CURRENT ENVIRONMENT'
21
+ #
22
+ class SecretBroker
23
+ class << self
24
+
25
+ def current_environment_secrets
26
+ @current_environment_secrets ||= HashWithIndifferentAccess.new(ejson_secrets_file.to_h)
27
+ end
28
+
29
+ def current_environment
30
+ Rails.env
31
+ end
32
+
33
+ def ejson_secrets_file
34
+ EJsonSecretsFile.new(current_environment)
35
+ end
36
+
37
+ REMOTE_ENVIRONMENTS = [:staging, :production].freeze
38
+
39
+ REMOTE_ENVIRONMENTS.each do |environment_name|
40
+ define_method environment_name do
41
+ if environment_name.to_s == current_environment
42
+ current_environment_secrets
43
+ else
44
+ DummySecretsHash.new
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ class SecretBroker
2
+ class DummySecretsHash
3
+ def fetch(key)
4
+ "SECRET VALUE FOR #{key} REQUESTED FOR AN ENVIRONMENT OTHER THAN THE CURRENT ENVIRONMENT"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+ require 'open3'
3
+
4
+ class SecretBroker
5
+ class EJsonSecretsFile
6
+ def initialize(env)
7
+ @env = env
8
+ end
9
+
10
+ def to_h
11
+ return {} unless file_path.file?
12
+
13
+ stdout_str, stderr_str, status = Open3.capture3 "ejson decrypt #{file_path.to_path}"
14
+ fail "ejson decrypt did not run successfully. stderr: #{stderr_str}" unless status.success?
15
+
16
+ JSON.parse stdout_str
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :env
22
+
23
+ def config_path
24
+ Rails.root.join 'config', 'secrets'
25
+ end
26
+
27
+ def file_path
28
+ config_path.join "#{env}.ejson"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ class SecretBrokerRailtie < Rails::Railtie
2
+ rake_tasks do
3
+ load File.expand_path("../../tasks/secret_broker.tasks", __FILE__)
4
+ end
5
+ end
6
+
@@ -0,0 +1,3 @@
1
+ class SecretBroker
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ namespace :secret_broker do
2
+ desc 'Install secrets directory'
3
+ task install_secrets: :environment do
4
+ config_dir = Rails.root.join 'config', 'secrets'
5
+ config_dir.mkdir unless config_dir.directory?
6
+
7
+ staging_string = <<EOS
8
+ {
9
+ "_public_key": "TODO: Enter public key."
10
+ }
11
+ EOS
12
+
13
+ File.write(config_dir.join('staging.ejson'), staging_string)
14
+
15
+ production_string = <<EOS
16
+
17
+ {
18
+ "_public_key": "TODO: Enter public key."
19
+ }
20
+ EOS
21
+
22
+ File.write(config_dir.join('production.ejson'), production_string)
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'secret_broker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "secret_broker"
8
+ spec.version = SecretBroker::VERSION
9
+ spec.authors = ["Derek Schneider"]
10
+ spec.email = ["schneidermd1993@gmail.com"]
11
+ spec.summary = %q{Secret Broker}
12
+ spec.description = %q{Secret Broker}
13
+ spec.homepage = "https://github.com/schneiderderek/secret_broker"
14
+
15
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
16
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.12"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+
31
+ spec.add_runtime_dependency "rails", [">= 4.0.0", "< 6.0.0"]
32
+ spec.add_runtime_dependency "ejson"
33
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: secret_broker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Derek Schneider
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 4.0.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: 6.0.0
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 4.0.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: 6.0.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: ejson
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: Secret Broker
90
+ email:
91
+ - schneidermd1993@gmail.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - ".gitignore"
97
+ - ".rspec"
98
+ - ".travis.yml"
99
+ - Gemfile
100
+ - README.md
101
+ - Rakefile
102
+ - bin/console
103
+ - bin/setup
104
+ - lib/secret_broker.rb
105
+ - lib/secret_broker/dummy_secrets_hash.rb
106
+ - lib/secret_broker/ejson_secrets_file.rb
107
+ - lib/secret_broker/railtie.rb
108
+ - lib/secret_broker/version.rb
109
+ - lib/tasks/secret_broker.tasks
110
+ - secret_broker.gemspec
111
+ homepage: https://github.com/schneiderderek/secret_broker
112
+ licenses: []
113
+ metadata:
114
+ allowed_push_host: https://rubygems.org
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.5.1
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Secret Broker
135
+ test_files: []