sanctum 0.8.5.rc1 → 0.8.5.rc2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/examples/single_target/example_policy.hcl +54 -0
- data/examples/single_target/sanctum.yaml +14 -0
- data/lib/sanctum/command/base.rb +13 -15
- data/lib/sanctum/command/create.rb +12 -0
- data/lib/sanctum/command/update.rb +50 -26
- data/lib/sanctum/vault_secrets.rb +4 -1
- data/lib/sanctum/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6dc55aef33e0ba6113e5577b80799818e64a8953d0643d6b029335b84a5edc23
|
|
4
|
+
data.tar.gz: 52638d7d39ccb21cb830288081d9ca23017e3582e991603ec8f084175f0f3034
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 475976714b4229cd2e9a4dce401ed6aada1decbb2da6e73f55e7de3ba95e8ea17ef0aa0e4b84be9225713d8cacfe2260236b75cc75e21d396bcb6d63403463f5
|
|
7
|
+
data.tar.gz: 16b9465d78eeceb1580c8203eb8c21096d6a398d3b2c6c023f8c4e68bbfbe698c21be2cc9f52daf81175d35706f2a95b89a07214ccba1f4dde38ed7ef4303e8e
|
data/Gemfile.lock
CHANGED
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
|
data/lib/sanctum/command/base.rb
CHANGED
|
@@ -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::
|
|
38
|
-
|
|
39
|
-
|
|
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.
|
|
8
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
51
|
+
def post_upgrade_warning
|
|
48
52
|
warn yellow(
|
|
49
|
-
"\nOnce the upgrade has been completed
|
|
50
|
-
"\nPlease add
|
|
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
|
-
"\
|
|
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
|
|
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
|
-
|
|
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(
|
|
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)
|
data/lib/sanctum/version.rb
CHANGED
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.
|
|
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-
|
|
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
|