sanctum 0.8.5.rc1 → 0.8.5.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7669c1c9dff3c31915cef379c1d95ce55a58e21a8c785f4b543d7a8b55dff42f
4
- data.tar.gz: 9d87df11f2f28a3ae833271c6ea35329f82d4f08767765bc3383ef5ae66fccba
3
+ metadata.gz: 6dc55aef33e0ba6113e5577b80799818e64a8953d0643d6b029335b84a5edc23
4
+ data.tar.gz: 52638d7d39ccb21cb830288081d9ca23017e3582e991603ec8f084175f0f3034
5
5
  SHA512:
6
- metadata.gz: 144efff039e4dead3c2d14c7557aef22cde70972b9d2130ef7f94acc8dd1f7a28349382e51d81ca927d40d8e434d8a2cf1d366c52d0394a6a5246296151deef0
7
- data.tar.gz: 216aedadda62921b7941b52aab144a57a3152dce5f23db1e5febe19d001c4af679c46f53c6c91b2d24b966ca27cb0eeb1a858b01fc56d6582755bcda9ae5fbf8
6
+ metadata.gz: 475976714b4229cd2e9a4dce401ed6aada1decbb2da6e73f55e7de3ba95e8ea17ef0aa0e4b84be9225713d8cacfe2260236b75cc75e21d396bcb6d63403463f5
7
+ data.tar.gz: 16b9465d78eeceb1580c8203eb8c21096d6a398d3b2c6c023f8c4e68bbfbe698c21be2cc9f52daf81175d35706f2a95b89a07214ccba1f4dde38ed7ef4303e8e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sanctum (0.8.5.rc1)
4
+ sanctum (0.8.5.rc2)
5
5
  gli (~> 2.18)
6
6
  hashdiff (~> 0.3)
7
7
  vault (~> 0.12)
data/README.md CHANGED
@@ -63,7 +63,7 @@ VAULT_TOKEN=
63
63
  ```
64
64
 
65
65
  **Variables order of precedence**
66
- The higher the number the higher the precedence.(Command line arguments will always win).
66
+ The higher the number the higher the precedence.(1 is the lowest precedence, 4 is the highest, Command line arguments will always win).
67
67
 
68
68
  1. Default variables (Documented in sanctum.yaml)
69
69
  2. Config file
@@ -0,0 +1,54 @@
1
+ # Helpful documentation can be found
2
+ # https://www.vaultproject.io/guides/identity/policies
3
+ # https://www.vaultproject.io/docs/concepts/policies.html
4
+ # https://learn.hashicorp.com/vault/getting-started/policies
5
+ #
6
+ # You can make permissions more granular or limited by specifying deeper paths
7
+ # Example: `path "sanctum-test/data/dev/*"`, etc.
8
+ #
9
+ ################# Read/Write v2 api example #################################################
10
+ path "sanctum-test/data/*" { capabilities = ["list","read","create","update","delete"] }
11
+ path "sanctum-test/metadata/*" { capabilities = ["list","read","create","update","delete"] }
12
+ path "sanctum-test/destroy/*" { capabilities = ["update"] }
13
+ path "sanctum-test/delete/*" { capabilities = ["update"] }
14
+ path "sanctum-test/undelete/*" { capabilities = ["update"] }
15
+ #############################################################################################
16
+
17
+ ################# Read/Write v1/generic example ###################################
18
+ path "sanctum-test/*" { capabilities = ["list","read","create","update","delete"] }
19
+ ###################################################################################
20
+
21
+ ################## Additional sys/ and sys/mount permissions ############################################
22
+ # Grant access to tune existing mount
23
+ # Required to upgrade from v1/generic to v2
24
+ path "sys/mounts/sanctum-test/tune" { capabilities = ["read", "update"] }
25
+ # Grant broader permission to specific mount
26
+ path "sys/mounts/sanctum-test" { capabilities = ["create", "read", "update", "delete", "list", "sudo"] }
27
+ # Read health checks
28
+ path "sys/health" { capabilities = ["read", "sudo"] }
29
+ # View capabilities of token
30
+ path "sys/capabilities" { capabilities = ["create", "update"] }
31
+ # View capabilities of token
32
+ path "sys/capabilities-self" { capabilities = ["create", "update"] }
33
+ # View mount info for mounts that you have permissions on
34
+ path "sys/internal/ui/mounts" { capabilities = ["read"] }
35
+ #########################################################################################################
36
+
37
+ ################### Transit permissions###########################################################
38
+ # General permission on key
39
+ path "transit/keys/sanctum-test" { capabilities = ["list","read","create","update", "delete"] }
40
+ # Permission to rotate keys
41
+ path "transit/keys/sanctum-test/rotate" { capabilities = ["list","read","create","update"] }
42
+ # Permission to modify transit key config
43
+ path "transit/keys/sanctum-test/config" { capabilities = ["list","read","create","update"] }
44
+ # Permission to backup key
45
+ #path "transit/backup/sanctum-test" { capabilities = ["list","read"] }
46
+ # Permission to restore key
47
+ #path "transit/restore/sanctum-test" { capabilities = ["list","read","create","update"] }
48
+ # Transit encryption endpoint
49
+ path "transit/encrypt/sanctum-test" { capabilities = ["list","read","create","update"] }
50
+ # Transit decrypt endpoint
51
+ path "transit/decrypt/sanctum-test" { capabilities = ["list","read","create","update"] }
52
+ # Transit rewrap permissions
53
+ path "transit/rewrap/sanctum-test" { capabilities = ["list","read","create","update"] }
54
+ ##################################################################################################
@@ -0,0 +1,14 @@
1
+ # sanctum.yml
2
+ sanctum:
3
+ force: false
4
+ color: true
5
+
6
+ vault:
7
+ url: http://localhost:8200
8
+ token: my_cool_token
9
+ transit_key: transit/keys/sanctum-test
10
+
11
+ sync:
12
+ - name: sanctum-test
13
+ prefix: sanctum-test #Refers to vault
14
+ path: vault/sanctum-test #Refers to local path relative to sanctum.yaml
@@ -28,21 +28,15 @@ module Sanctum
28
28
 
29
29
  private
30
30
  # TODO: Fix! This is a bit hacky, will update once vault-ruby gets updated with better support for v2 api
31
-
32
-
33
31
  # Internal: gets information about mounts that the user has permissions on
34
32
  # Returns: hash
35
33
  def mounts_info
36
34
  @mounts_info ||= vault_client.request(:get, "/v1/sys/internal/ui/mounts")
37
- rescue Vault::HTTPClientError
38
- warn red(
39
- "Unable to gather info about mounts this maybe due to vault connectivity or permissions"\
40
- "\nTo list info about mounts you have permissions to have following permissions added"\
41
- "\npath \"sys/internal/ui/mounts\" { capabilities = [\"read\"] }"\
42
- )
35
+ rescue Vault::VaultError
36
+ unable_to_determine_version
37
+ raise
43
38
  end
44
39
 
45
-
46
40
  # Internal: automatically detect the api version of the secrets mount
47
41
  # and adds :secrets_version to hash if it doesn't exist
48
42
  #
@@ -55,18 +49,13 @@ module Sanctum
55
49
  next if h.key?(:secrets_version)
56
50
 
57
51
  # If mount options is nil default to api version 1 otherwise use version value
52
+ # generic mounts will not have a version specified
58
53
  if mounts_hash.dig(:data, :secret, "#{h[:prefix]}/".to_sym, :options).nil?
59
54
  h[:secrets_version] = "1"
60
55
  else
61
56
  h[:secrets_version] = mounts_hash.dig(:data, :secret, "#{h[:prefix]}/".to_sym, :options, :version)
62
57
  end
63
58
  end
64
- rescue Vault::VaultError
65
- warn red(
66
- "Unable to automatically determine secrets_version. This maybe due to vault connectivity or permissions"\
67
- "\nTry again, or you could explicitly add `secrets_version:` to your sanctum.yaml to bypass auto detect"
68
- )
69
- raise
70
59
  end
71
60
 
72
61
  # Internal, add /data to prefix or path if secrets_version == "2"
@@ -80,6 +69,15 @@ module Sanctum
80
69
  h[:path] = h[:path].include?("/data") ? h[:path] : "#{h[:path]}/data"
81
70
  end
82
71
  end
72
+
73
+ def unable_to_determine_version
74
+ warn red(
75
+ "Unable to automatically gather info about mounts. This maybe due to vault connectivity or permissions"\
76
+ "\nTo list info about mounts you may need to have following permissions added"\
77
+ "\npath \"sys/internal/ui/mounts\" { capabilities = [\"read\"] }"\
78
+ "\nAlternitivley add `secrets_version: <version>` for each target specified in sanctum.yaml to bypass autodetect"
79
+ )
80
+ end
83
81
  end
84
82
  end
85
83
  end
@@ -51,9 +51,21 @@ module Sanctum
51
51
  end
52
52
  end
53
53
 
54
+ # Check if the path you are creating matches a target path
55
+ # if secrets_version == 2 /data will be added to the path
56
+ # See command/base.rb
57
+ def path_matches_a_target?(path)
58
+ targets.each do |h|
59
+ path.to_s.include?(h[:path]) ? (return true) : (return false)
60
+ end
61
+ end
62
+
54
63
  def validate_path(path)
55
64
  path = Pathname.new(path)
65
+ keys_to_print = targets.map { |h| h.slice(:name, :path) }
56
66
  raise yellow("File exists, use edit command") if path.exist?
67
+ raise yellow("No targets contain a :path key that matches the path you specified\n#{keys_to_print}") unless path_matches_a_target?(path)
68
+
57
69
  path.dirname.mkpath unless path.dirname.exist?
58
70
  end
59
71
 
@@ -4,17 +4,17 @@ module Sanctum
4
4
  module Command
5
5
  class Update < Base
6
6
  def run
7
- targets.each do |target|
8
- # Use command line if force: true
9
- if options[:cli][:force]
10
- force = options[:cli][:force]
11
- else
12
- force = target.fetch(:force) {options[:sanctum][:force]}
13
- end
14
-
15
- update_mount(target, force)
7
+ raise red("Please only specify one target") if targets.count > 1
8
+ target = targets.first
16
9
 
10
+ # Use command line if force: true
11
+ if options[:cli][:force]
12
+ force = options[:cli][:force]
13
+ else
14
+ force = target.fetch(:force) {options[:sanctum][:force]}
17
15
  end
16
+
17
+ update_mount(target, force)
18
18
  end
19
19
 
20
20
  private
@@ -24,30 +24,34 @@ module Sanctum
24
24
  pre_upgrade_warning
25
25
 
26
26
  if force
27
- warn yellow("\nUpgrading #{target[:prefix]}")
28
- upgrade_response = vault_client.request(:post, "/v1/sys/mounts/#{target[:prefix]}/tune", data)
29
- upgrade_response.nil? ? nothing_happened_warning : (warn yellow("#{upgrade_response}"))
27
+ # When force option is used we will try to run the upgrade command mount, even if it's already been upgraded
28
+ # Request will be a no-op and return null. So we need to remove `data` from the prefix if it's been added.
29
+ force_prefix = target[:prefix].include?("/data") ? target[:prefix].sub(/\/data/, "") : target[:prefix]
30
+ warn yellow("\nUpgrading #{force_prefix}")
31
+ upgrade_response = vault_client.request(:post, "/v1/sys/mounts/#{force_prefix}/tune", data)
30
32
  else
31
33
  already_upgraded_warning if target[:secrets_version] == "2"
32
- warn yellow("#{vault_client.request(:post, "/v1/sys/mounts/#{target[:prefix]}/tune", data)}") if confirm_upgrade?(target)
34
+ upgrade_response = confirm_upgrade?(target) ? vault_client.request(:post, "/v1/sys/mounts/#{target[:prefix]}/tune", data) : nil
33
35
  end
34
- post_upgrade_warning(target)
36
+ upgrade_response.nil? ? nothing_happened_warning : (warn yellow("#{upgrade_response}\n#{post_upgrade_warning}"))
37
+
38
+ post_upgrade_tasks(target)
35
39
  end
36
40
 
37
41
  def pre_upgrade_warning
38
42
  warn yellow(
39
43
  "\nPlease read 'Upgrading from Version 1' documentation BEFORE you upgrade"\
40
- "\nThe addition of `/data`, and `/metadata` endpoints will break applications that are depending on v1 endpoints"\
44
+ "\nThe addition of `/data`, and `/metadata` endpoints will break applications that are dependant on v1 endpoints"\
41
45
  "\nYou will want to update permissions policies, and applications BEFORE you upgrade"\
42
46
  "\nhttps://www.vaultproject.io/docs/secrets/kv/kv-v2.html#upgrading-from-version-1"\
43
47
  )
44
48
  additional_acl_warning
45
49
  end
46
50
 
47
- def post_upgrade_warning(target)
51
+ def post_upgrade_warning
48
52
  warn yellow(
49
- "\nOnce the upgrade has been completed, make sure you update your sanctum.yaml."\
50
- "\nPlease add the `secrets_version: 2` key to the #{target[:prefix]} config."
53
+ "\nOnce the upgrade has been completed update sanctum.yaml."\
54
+ "\nPlease add or update `secrets_version:` key to each configured target."\
51
55
  )
52
56
  end
53
57
 
@@ -55,12 +59,7 @@ module Sanctum
55
59
  warn yellow(
56
60
  "\nIf you use policies to limit secrets access you may need to have your permissions updated"\
57
61
  "\nSee https://www.vaultproject.io/docs/secrets/kv/kv-v2.html#acl-rules for more info"\
58
- "\nSpecifically you may need add something similar to the following:"\
59
- "\npath \"<secrets_mount>/data/*\" { capabilities = [\"list\",\"read\",\"create\",\"update\",\"delete\"] }"\
60
- "\npath \"<secrets_mount>/metadata/*\" { capabilities = [\"list\",\"read\",\"create\",\"update\",\"delete\"] }"\
61
- "\npath \"<secrets_mount>/destroy/*\" { capabilities = [\"update\"] }"\
62
- "\npath \"<secrets_mount>/delete/*\" { capabilities = [\"update\"] }"\
63
- "\npath \"<secrets_mount>/undelete/*\" { capabilities = [\"update\"] }"
62
+ "\nSee examples/single_target for updated policy example."\
64
63
  )
65
64
  end
66
65
 
@@ -74,12 +73,13 @@ module Sanctum
74
73
 
75
74
  def nothing_happened_warning
76
75
  warn yellow(
77
- "Request was successfull but returned a nil response, this generally means the mount has is already upgraded!"
76
+ "Request returned a nil response, which could mean mount is already upgraded"
78
77
  )
79
78
  end
80
79
 
81
80
  def confirm_upgrade?(target)
82
81
  warn yellow("\nUpgrading will make the mount temporarily unavailable")
82
+ warn red("\nPlease ensure you are fully synced(all secrets have been pushed/pulled)")
83
83
  warn yellow("Would you like to continue?: ")
84
84
  question = STDIN.gets.chomp.upcase
85
85
 
@@ -87,10 +87,34 @@ module Sanctum
87
87
  warn yellow("\nUpgrading #{target[:prefix]}")
88
88
  true
89
89
  else
90
- warn yellow("\nSkipping....\n")
90
+ raise yellow("\nSkipping....\n")
91
91
  false
92
92
  end
93
93
  end
94
+
95
+ # Post upgrade tasks if mount is being upgraded from generic mount or v1 mount to v2 mount
96
+ # Ensure local files mimic vault v2 by add `/data` to local path
97
+ def post_upgrade_tasks(target)
98
+ config_path = Pathname.new(config_file).dirname.to_s
99
+ full_target_path = "#{config_path}/#{target[:path]}"
100
+
101
+ old_path = full_target_path.include?("/data") ? full_target_path.sub(/\/data/, "") : full_target_path
102
+ new_path = full_target_path.include?("/data") ? full_target_path : "#{full_target_path}/data"
103
+
104
+ # If old path does not exist, chances are sanctum upgrade is being run before sanctum pull/push.
105
+ return unless File.directory?(old_path)
106
+
107
+ files_to_move = Dir.chdir(old_path) { Dir.glob('*') }.delete_if {|i| i == "data"}
108
+ unless files_to_move.empty?
109
+ FileUtils.mkdir_p(new_path) unless File.directory?(new_path)
110
+ files_to_move.each do |f|
111
+ FileUtils.mv("#{old_path}/#{f}", new_path, secure: true)
112
+ end
113
+ end
114
+ rescue
115
+ warn red("Post upgrade tasks failed")
116
+ raise
117
+ end
94
118
  end
95
119
  end
96
120
  end
@@ -12,7 +12,10 @@ module Sanctum
12
12
  # API version 2 uses /metadata path to list, but /data to read.
13
13
  #TODO Fix, change list_prefix back to prefix at some point. Use new kv from vault-ruby once it's updated
14
14
  def get_all
15
- raise yellow("Warning: Vault prefix: '#{prefix}' does not exist.. ") if invalid_prefix?
15
+ raise yellow(
16
+ "Vault prefix: '#{prefix}' does not exist, or doesn't contain any secrets to pull/check"\
17
+ "\nEnsure mount is enabled and use `sanctum create`, and `sanctum push` to add secrets"
18
+ ) if invalid_prefix?
16
19
 
17
20
  secrets_from_vault = Hash.new
18
21
  secrets_from_vault[prefix] = JSON(list_recursive(list_prefix).to_json)
@@ -1,3 +1,3 @@
1
1
  module Sanctum
2
- VERSION = "0.8.5.rc1"
2
+ VERSION = "0.8.5.rc2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanctum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5.rc1
4
+ version: 0.8.5.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corban Raun
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-14 00:00:00.000000000 Z
11
+ date: 2019-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: vault
@@ -160,6 +160,8 @@ files:
160
160
  - docker-compose.override.yml_sample
161
161
  - docker-compose.test.yml
162
162
  - docker-compose.yml
163
+ - examples/single_target/example_policy.hcl
164
+ - examples/single_target/sanctum.yaml
163
165
  - lib/sanctum.rb
164
166
  - lib/sanctum/cli.rb
165
167
  - lib/sanctum/colorize_string.rb