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 +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
|