sanctum 0.8.0

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: cf7c163a643291aa2598c9aa95282d252e27b1a6dcd98229bc1531f6c74326db
4
+ data.tar.gz: de8e41efc63ca29c75afa13f09c17962875d30e702b03a4572d706a88099629d
5
+ SHA512:
6
+ metadata.gz: 2e56cc5a812d15c94a30b344e5c048b2fb829eeaed7c79f0eff42c901f3a148be985ab7593081fbf152a895848121c79275b6d654084f90ae1d3c9c4af2f3077
7
+ data.tar.gz: 94ea6c9b31d49bea98c4dfcf19f445bc0a60317825de118d544dd05ecbf72021e2f79744e05def3703f356c7670c2a58896f05338c544c125f416f532d579db9
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sanctum (0.8.0)
5
+ gli (~> 2)
6
+ hashdiff (~> 0)
7
+ vault (~> 0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ aws-sigv4 (1.0.2)
13
+ coderay (1.1.2)
14
+ diff-lcs (1.3)
15
+ gli (2.17.1)
16
+ hashdiff (0.3.7)
17
+ method_source (0.9.0)
18
+ pry (0.11.3)
19
+ coderay (~> 1.1.0)
20
+ method_source (~> 0.9.0)
21
+ rake (10.5.0)
22
+ rspec (3.7.0)
23
+ rspec-core (~> 3.7.0)
24
+ rspec-expectations (~> 3.7.0)
25
+ rspec-mocks (~> 3.7.0)
26
+ rspec-core (3.7.1)
27
+ rspec-support (~> 3.7.0)
28
+ rspec-expectations (3.7.0)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.7.0)
31
+ rspec-mocks (3.7.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.7.0)
34
+ rspec-support (3.7.1)
35
+ vault (0.11.0)
36
+ aws-sigv4
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ bundler (~> 1.16)
43
+ pry (~> 0)
44
+ rake (~> 10.0)
45
+ rspec (~> 3.0)
46
+ sanctum!
47
+
48
+ BUNDLED WITH
49
+ 1.16.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Corban Raun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # Sanctum
2
+ Simple and secure filesystem-to-vault KV synchronization. Inspired by [constancy](https://github.com/daveadams/constancy).
3
+ Local files are encrypted using vaults [transit](https://www.vaultproject.io/api/secret/transit/index.html) backend.
4
+ This makes maintaining multiple vault secrets for multiple applications simple and secure.
5
+
6
+ ## Usage Example
7
+ Lets say you have a vault instance with a `generic`, or `kv` enabled backend.
8
+ if you were to run, `vault read secrets/cool-app/dev/env` you would see something similar to
9
+
10
+ ```
11
+ Key Value
12
+ --- -----
13
+ refresh_interval 768h
14
+ db_password heydudeihaveacoolapp
15
+ token myrandomtoken
16
+
17
+ ```
18
+
19
+ using the sanctum gem, you could run `sanctum pull`. Depending on the path you specified in the `sanctum.yaml` config file; Your local file system would look similar to
20
+ ```
21
+ <path-specified>/cool-app/dev/env
22
+ ```
23
+ `env` would contain a `transit` encrypted base64 encoded blob, which you could then edit with `sanctum edit <path-specified>/cool-app/dev/env`. You could then push any changes with
24
+ `sanctum push`.
25
+
26
+ ## Installation
27
+
28
+ From source:
29
+
30
+ $ bundle install && bundle exec rake:install
31
+
32
+ Or install rubygems:
33
+
34
+ $ gem install sanctum
35
+
36
+ ## Usage
37
+ ```
38
+ sanctum check - Checks differences between local files and vault.
39
+ sanctum push - Push local file changes (if any) to vault.
40
+ sanctum pull - Pull vault secrets to local files (encrypted).
41
+ sanctum config - Generate an example config file.
42
+ sanctum create - Create an encrypted local file.
43
+ sanctum edit - Edit an encrypted local file.
44
+ sanctum view - View an encrypted local file.
45
+ ```
46
+
47
+
48
+ ## Configuration
49
+ **sanctum.yaml is required, run `sanctum config` to generate an example file**
50
+
51
+ Sanctum will use the **first `sanctum.yaml`** file it comes across when searching backwards through the directory tree from the current working directory.
52
+ So, typically you may wish to place the config file in the root of your git repository or the base directory of your config file tree.
53
+
54
+ You can also specify a config file using the -c,--config <filename> command line argument.
55
+ ## Variables
56
+ The example `sanctum.yaml` has all options documented, run `sanctum config` to generate an example file.
57
+
58
+ The following environment variables are read.
59
+ ```
60
+ VAULT_ADDR=
61
+ VAULT_TOKEN=
62
+ ```
63
+
64
+ **Variables order of precedence**
65
+ The higher the number the higher the precedence.(Command line arguments will always win).
66
+
67
+ 1. Default variables (Documented in sanctum.yaml)
68
+ 2. Config file
69
+ 3. Environment variables
70
+ 4. Command line arguments.
71
+
72
+
73
+ ## Configuration file structure
74
+ The configuration file is a Hash represented in YAML format with three possible top-level keys: `sanctum`, `vault`, and `sync`.
75
+ * The `sanctum` section sets global defaults.
76
+ * This section is **NOT** required.
77
+ * The `vault` section specifies the url, token, and transit_key to the Vault REST API endpoint.
78
+ * url, token, and transit_key are **required** and can be set here or through environment variables.
79
+ * The `sync` section sets the local paths and Vault prefixes you wish to synchronize.
80
+ * At lease one application/target definition is required.
81
+
82
+ ## Roadmap
83
+ * Better/more Tests
84
+ * Built in Backup features
85
+ * Performance optimizations
86
+
87
+ ## Backup scenario.
88
+ One possible use case for sanctum is for backing up vault secrets. This feature is NOT built in yet.
89
+ The following instructions are for testing purposes only and are not recommended as an actual backup solution.
90
+ See the [Transit Secrets Engine(API)](https://www.vaultproject.io/api/secret/transit/index.html) for command reference.
91
+
92
+ 1. Create a new key with, or enable `allow_plaintext_backup` and `exportable` on the transit key you are using for sanctum. **Once enabled you cannot disable**
93
+ * Example: `curl -v --header "X-Vault-Token: $VAULT_TOKEN" --request POST --data '{"allow_plaintext_backup": true, "exportable": true}' $VAULT_ADDR/v1/transit/keys/<my_transit_key>/config`
94
+ 2. `sanctum pull`
95
+ 3. Get your transit key
96
+ * Example: `curl -v --header "X-Vault-Token: $VAULT_TOKEN" --request GET $VAULT_ADDR/v1/transit/backup/<my_transit_key>`
97
+ 4. Securely store/ backup your key.
98
+
99
+ ### Restoring:
100
+ If you ever need to restore the key, you can restore using the restore endpoint
101
+ 1. `curl -v --header "X-Vault-Token: $VAULT_TOKEN" --data @transit_key.json --request POST $VAULT_ADDR/v1/transit/restore/<my_transit_key>`
102
+
103
+ transit_key.json would look something like
104
+ ```
105
+ {"backup":"<your_long_key>"}
106
+ ```
107
+ One thing that is nice, is that you can use this method to restore to a locally running vault instance.
108
+ This would allow you to be able to quickly decrypt local secrets in a disaster recovery event.
109
+ 1. run `vault server -dev`
110
+ 2. export the new `VAULT_TOKEN` and `$VAULT_ADDR` variables.
111
+ 3. Restore the key to your locally running vault instance.
112
+
113
+ ## Development
114
+ Ensure you have the [vault](https://www.vaultproject.io/downloads.html) binary in your path. Tests need this in order to setup a dev vault server(`vault server -dev`)
115
+ 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.
116
+
117
+ 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).
118
+
119
+ ## Contributing
120
+
121
+ Bug reports and pull requests are welcome on GitHub at https://github.com/CorbanR/sanctum. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
122
+
123
+ ## License
124
+
125
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
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,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'sanctum'
5
+ require 'pry'
6
+
7
+ Pry.start
8
+
9
+ require 'irb'
10
+ IRB.start(__FILE__)
data/bin/sanctum ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sanctum'
3
+ exit Sanctum::CLI.run(ARGV)
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
data/lib/sanctum.rb ADDED
@@ -0,0 +1 @@
1
+ require 'sanctum/cli'
@@ -0,0 +1,109 @@
1
+ require 'gli'
2
+ require 'sanctum/command'
3
+ require 'sanctum/get_config'
4
+ require 'sanctum/version'
5
+
6
+ module Sanctum
7
+ class CLI
8
+ extend GLI::App
9
+
10
+ def self.common_options(c, *opts)
11
+ opts.map(&:to_sym).each do |opt|
12
+ case opt
13
+ when :config
14
+ c.desc 'specify config file'
15
+ c.flag :c, :config
16
+ when :targets
17
+ c.desc 'Comma seperated list of targets'
18
+ c.flag :t, :targets
19
+ when :force
20
+ c.desc 'Force, will not ask you to confirm differences'
21
+ c.switch :force
22
+ else
23
+ raise "unrecognized option #{opt.inspect}"
24
+ end
25
+ end
26
+ end
27
+
28
+ program_desc 'Simple and secure filesystem-to-Vault secrets synchronization'
29
+
30
+ version VERSION
31
+
32
+ subcommand_option_handling :normal
33
+ arguments :strict
34
+
35
+ desc 'Checks differences that exist'
36
+ command :check do |c|
37
+ common_options c, :targets, :config
38
+ c.action do
39
+ Command::Check.new(@options_hash).run
40
+ end
41
+ end
42
+
43
+ desc 'Pull in secrets that already exist in Vault.'
44
+ command :pull do |c|
45
+ common_options c, :targets, :config, :force
46
+ c.action do
47
+ Command::Pull.new(@options_hash).run
48
+ end
49
+ end
50
+
51
+ desc 'Synchronize secrets to Vault'
52
+ command :push do |c|
53
+ common_options c, :targets, :config, :force
54
+ c.action do
55
+ Command::Push.new(@options_hash).run
56
+ end
57
+ end
58
+
59
+ desc 'Creates example config file'
60
+ skips_pre
61
+ command :config do |c|
62
+ c.action do
63
+ Command::Config.new.run
64
+ end
65
+ end
66
+
67
+ desc 'Create an encrypted file'
68
+ arg_name 'path/to/file'
69
+ command :create do |c|
70
+ common_options c, :config
71
+ c.action do |_,_,args|
72
+ Command::Create.new(@options_hash, args).run
73
+ end
74
+ end
75
+
76
+ desc 'View encrypted file[s]'
77
+ arg_name 'path/to/file'
78
+ command :view do |c|
79
+ common_options c, :config
80
+ c.action do |_,_,args|
81
+ if args.empty?
82
+ help_now! "Please specify at least one argument"
83
+ end
84
+ Command::View.new(@options_hash, args).run
85
+ end
86
+ end
87
+
88
+ desc 'Edit an encrypted file'
89
+ arg_name 'path/to/file'
90
+ command :edit do |c|
91
+ common_options c, :config
92
+
93
+ c.action do |_,_,args|
94
+ Command::Edit.new(@options_hash, args).run
95
+ end
96
+ end
97
+
98
+ pre do |_,_,options,_|
99
+ @options_hash = GetConfig::ConfigMerge.new(config_file: options[:c], targets: options[:t], force: options[:force]).final_options
100
+ Colorizer.colorize = @options_hash[:sanctum][:color]
101
+ true
102
+ end
103
+
104
+ on_error do |exception|
105
+ true
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,44 @@
1
+ module Sanctum
2
+ module Colorizer
3
+ def self.colorize=(flag)
4
+ @colorize = !!flag
5
+ end
6
+
7
+ def self.colorize?
8
+ @colorize = true if @colorize.nil?
9
+ @colorize
10
+ end
11
+
12
+ def colorize(color_code, string, colorize: Colorizer.colorize?)
13
+ if colorize
14
+ "\e[#{color_code}m#{string}\e[0m"
15
+ else
16
+ string
17
+ end
18
+ end
19
+
20
+ def red(string)
21
+ colorize(31, string)
22
+ end
23
+
24
+ def green(string)
25
+ colorize(32, string)
26
+ end
27
+
28
+ def yellow(string)
29
+ colorize(33, string)
30
+ end
31
+
32
+ def blue(string)
33
+ colorize(34, string)
34
+ end
35
+
36
+ def pink(string)
37
+ colorize(35, string)
38
+ end
39
+
40
+ def light_blue(string)
41
+ colorize(36, string)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ #colorize_string needs to be required first
2
+ require 'sanctum/colorize_string'
3
+ require 'sanctum/vault_client'
4
+ require 'sanctum/vault_secrets'
5
+ require 'sanctum/vault_transit'
6
+
7
+ #base needs to be required first
8
+ require 'sanctum/command/base'
9
+
10
+ require 'sanctum/command/check'
11
+ require 'sanctum/command/config'
12
+ require 'sanctum/command/create'
13
+ require 'sanctum/command/edit'
14
+ require 'sanctum/command/pull'
15
+ require 'sanctum/command/push'
16
+ require 'sanctum/command/view'
@@ -0,0 +1,30 @@
1
+ require 'sanctum/command/diff_helper'
2
+ require 'sanctum/command/editor_helper'
3
+ require 'sanctum/command/paths_helper'
4
+
5
+ module Sanctum
6
+ module Command
7
+ class Base
8
+ include Colorizer
9
+ include DiffHelper
10
+ include EditorHelper
11
+ include PathsHelper
12
+
13
+ attr_reader :options, :args, :transit_key, :targets, :config_file
14
+
15
+ def initialize(options={}, args=[])
16
+ @options = options.to_h
17
+ @args = args
18
+
19
+ @transit_key = options.fetch(:vault).fetch(:transit_key)
20
+ @targets = options.fetch(:sync)
21
+ @config_file = options.fetch(:config_file)
22
+ end
23
+
24
+ def vault_client
25
+ @vault_client ||= VaultClient.build(options[:vault][:url], options[:vault][:token])
26
+ end
27
+
28
+ end
29
+ end
30
+ end