secret_hub 0.1.1 → 0.1.2
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/README.md +71 -14
- data/lib/secret_hub/commands/bulk.rb +37 -26
- data/lib/secret_hub/config-template.yml +19 -0
- data/lib/secret_hub/config.rb +54 -0
- data/lib/secret_hub/exceptions.rb +1 -1
- data/lib/secret_hub/github_client.rb +1 -1
- data/lib/secret_hub/refinements/string_obfuscation.rb +23 -0
- data/lib/secret_hub/version.rb +1 -1
- data/lib/secret_hub.rb +1 -0
- metadata +18 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 828e88613986422e9673539e45727e6de237e6697e596885a652851554236824
|
4
|
+
data.tar.gz: dca45482c12ef6e81e8663407defd185c8f0cce831ef561872c81187af4e63e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d7bee2f48361069776dbc7709f9d9328c0991ae6c8e2c2a20764fab20d36ac50105b1eb61a7f08b8ff3e502fca1c0ef68a68b01d450b159de012141eff16124
|
7
|
+
data.tar.gz: 79926a14f52b2fd06ccbae331fcc6ab863531896a8f8027deb53c12ad5d61f226beccf433e543bb195768311dcb0308cc29f42b95769a61706d0e7acd9e45bae
|
data/README.md
CHANGED
@@ -41,38 +41,45 @@ SecretHub has two families of commands:
|
|
41
41
|
1. Commands that operate on a single repository.
|
42
42
|
2. Commands that operate on multiple repositories, and multiple secrets.
|
43
43
|
|
44
|
-
|
44
|
+
Most commands are self explanatory, and described by the CLI.
|
45
45
|
|
46
|
-
|
46
|
+
```shell
|
47
|
+
$ secrethub --help
|
48
|
+
```
|
49
|
+
|
50
|
+
Single repository operations
|
51
|
+
--------------------------------------------------
|
52
|
+
|
53
|
+
### Show the secret keys in a repository
|
47
54
|
|
48
55
|
```shell
|
49
56
|
# secrethub list REPO
|
50
57
|
$ secrethub list you/your-repo
|
51
58
|
```
|
52
59
|
|
53
|
-
|
60
|
+
### Create or update a secret in a repository
|
54
61
|
|
55
62
|
```shell
|
56
63
|
# secrethub save REPO KEY VALUE
|
57
64
|
$ secrethub list you/your-repo SECRET "there is no spoon"
|
58
65
|
```
|
59
66
|
|
60
|
-
|
67
|
+
### Delete a secret from a repository
|
61
68
|
|
62
69
|
```shell
|
63
70
|
# secrethub delete REPO KEY
|
64
71
|
$ secrethub list you/your-repo SECRET
|
65
72
|
```
|
66
73
|
|
67
|
-
### Bulk operations
|
68
74
|
|
69
|
-
|
75
|
+
Bulk operations
|
76
|
+
--------------------------------------------------
|
70
77
|
|
71
|
-
|
72
|
-
|
73
|
-
|
78
|
+
All the bulk operations function by using a simple YAML configuration file.
|
79
|
+
The configuration file includes a list of GitHub repositories, each with a
|
80
|
+
list of its secrets.
|
74
81
|
|
75
|
-
|
82
|
+
For example:
|
76
83
|
|
77
84
|
```yaml
|
78
85
|
# secrethub.yml
|
@@ -86,21 +93,71 @@ user/another-repo:
|
|
86
93
|
- SECRET_KEY
|
87
94
|
```
|
88
95
|
|
89
|
-
|
96
|
+
Each list of secrets can either be an array, or a hash.
|
97
|
+
|
98
|
+
### Using array syntax
|
99
|
+
|
100
|
+
All secrets must be defined as environment variables.
|
101
|
+
|
102
|
+
```yaml
|
103
|
+
user/repo:
|
104
|
+
- SECRET
|
105
|
+
- PASSWORD
|
106
|
+
```
|
107
|
+
|
108
|
+
### Using hash syntax
|
109
|
+
|
110
|
+
Each secret may define its value, or leave it blank. When a secret value is
|
111
|
+
blank, it will be loaded from the environment.
|
112
|
+
|
113
|
+
```yaml
|
114
|
+
user/another-repo:
|
115
|
+
SECRET:
|
116
|
+
PASSWORD: p4ssw0rd
|
117
|
+
```
|
118
|
+
|
119
|
+
### Using YAML anchors
|
120
|
+
|
121
|
+
SecretHub ignores any key that does not look like a repository (does not
|
122
|
+
include a slash `/`). Using this feature, you can define reusable YAML
|
123
|
+
anchors:
|
124
|
+
|
125
|
+
```yaml
|
126
|
+
docker: &docker
|
127
|
+
DOCKER_USER:
|
128
|
+
DOCKER_PASSWORD:
|
129
|
+
|
130
|
+
user/another-repo:
|
131
|
+
<<: *docker
|
132
|
+
SECRET:
|
133
|
+
PASSWORD: p4ssw0rd
|
134
|
+
```
|
135
|
+
|
136
|
+
Note that YAML anchors only work with the hash syntax.
|
137
|
+
|
138
|
+
|
139
|
+
### Create a sample configuration file
|
90
140
|
|
91
141
|
```shell
|
92
142
|
# secrethub bulk init [CONFIG]
|
93
143
|
$ secrethub bulk init mysecrets.yml
|
94
144
|
```
|
95
145
|
|
96
|
-
|
146
|
+
### Show the configuration file and its secrets
|
147
|
+
|
148
|
+
```shell
|
149
|
+
# secrethub bulk show [CONFIG --visible]
|
150
|
+
$ secrethub bulk show mysecrets.yml
|
151
|
+
```
|
152
|
+
|
153
|
+
### Show all secrets stored on GitHub in all repositories
|
97
154
|
|
98
155
|
```shell
|
99
156
|
# secrethub bulk list [CONFIG]
|
100
157
|
$ secrethub bulk list mysecrets.yml
|
101
158
|
```
|
102
159
|
|
103
|
-
|
160
|
+
### Save multiple secrets to multiple repositories
|
104
161
|
|
105
162
|
```shell
|
106
163
|
# secrethub bulk save [CONFIG --clean]
|
@@ -111,7 +168,7 @@ Using the `--clean` flag, you can ensure that the repositories do not have
|
|
111
168
|
any secrets that you are unaware of. This flag will delete any secret that is
|
112
169
|
not specified in your config file.
|
113
170
|
|
114
|
-
|
171
|
+
### Delete secrets from multiple repositories unless they are specified in the config file
|
115
172
|
|
116
173
|
```shell
|
117
174
|
# secrethub bulk clean [CONFIG]
|
@@ -1,26 +1,33 @@
|
|
1
|
-
require '
|
1
|
+
require 'fileutils'
|
2
|
+
require 'secret_hub/refinements/string_obfuscation'
|
2
3
|
|
3
4
|
module SecretHub
|
4
5
|
module Commands
|
5
6
|
class Bulk < Base
|
7
|
+
using StringObfuscation
|
8
|
+
|
6
9
|
summary "Update or delete multiple secrets from multiple repositories"
|
7
10
|
|
8
11
|
usage "secrethub bulk init [CONFIG]"
|
12
|
+
usage "secrethub bulk show [CONFIG --visible]"
|
9
13
|
usage "secrethub bulk list [CONFIG]"
|
10
14
|
usage "secrethub bulk save [CONFIG --clean]"
|
11
15
|
usage "secrethub bulk clean [CONFIG]"
|
12
16
|
usage "secrethub bulk (-h|--help)"
|
13
17
|
|
14
18
|
command "init", "Create a sample configuration file in the current directory"
|
19
|
+
command "show", "Show the configuration file"
|
15
20
|
command "save", "Save multiple secrets to multiple repositories"
|
16
21
|
command "clean", "Delete secrets from multiple repositories unless they are specified in the config file"
|
17
22
|
command "list", "Show all secrets in all repositories"
|
18
23
|
|
19
|
-
option "-c, --clean", "Also delete any other secret not defined in the
|
24
|
+
option "-c, --clean", "Also delete any other secret not defined in the configuration file"
|
25
|
+
option "-v, --visible", "Also show secret values"
|
20
26
|
|
21
27
|
param "CONFIG", "Path to the configuration file [default: secrethub.yml]"
|
22
28
|
|
23
29
|
example "secrethub bulk init"
|
30
|
+
example "secrethub bulk show --visible"
|
24
31
|
example "secrethub bulk clean"
|
25
32
|
example "secrethub bulk list mysecrets.yml"
|
26
33
|
example "secrethub bulk save mysecrets.yml"
|
@@ -28,18 +35,24 @@ module SecretHub
|
|
28
35
|
|
29
36
|
def init_command
|
30
37
|
raise SecretHubError, "File #{config_file} already exists" if File.exist? config_file
|
38
|
+
FileUtils.cp config_template, config_file
|
39
|
+
say "!txtgrn!Saved #{config_file}"
|
40
|
+
end
|
31
41
|
|
32
|
-
|
33
|
-
|
34
|
-
"user/another-repo" => %w[SECRET SECRET_KEY],
|
35
|
-
}
|
42
|
+
def show_command
|
43
|
+
visible = args['--visible']
|
36
44
|
|
37
|
-
|
38
|
-
|
45
|
+
config.each do |repo, secrets|
|
46
|
+
say "!txtblu!#{repo}:"
|
47
|
+
secrets.each do |key, value|
|
48
|
+
value = value.obfuscate unless visible
|
49
|
+
say " !txtpur!#{key}: !txtcyn!#{value}"
|
50
|
+
end
|
51
|
+
end
|
39
52
|
end
|
40
53
|
|
41
54
|
def list_command
|
42
|
-
config.
|
55
|
+
config.each_repo do |repo|
|
43
56
|
say "!txtblu!#{repo}:"
|
44
57
|
github.secrets(repo).each do |secret|
|
45
58
|
say "- !txtpur!#{secret}"
|
@@ -50,17 +63,17 @@ module SecretHub
|
|
50
63
|
def save_command
|
51
64
|
clean = args['--clean']
|
52
65
|
|
53
|
-
config.each do |repo,
|
66
|
+
config.each do |repo, secrets|
|
54
67
|
say "!txtblu!#{repo}"
|
55
|
-
update_repo repo,
|
56
|
-
clean_repo repo, keys if clean
|
68
|
+
update_repo repo, secrets
|
69
|
+
clean_repo repo, secrets.keys if clean
|
57
70
|
end
|
58
71
|
end
|
59
72
|
|
60
73
|
def clean_command
|
61
|
-
config.each do |repo,
|
74
|
+
config.each do |repo, secrets|
|
62
75
|
say "!txtblu!#{repo}"
|
63
|
-
clean_repo repo, keys
|
76
|
+
clean_repo repo, secrets.keys
|
64
77
|
end
|
65
78
|
end
|
66
79
|
|
@@ -71,32 +84,30 @@ module SecretHub
|
|
71
84
|
delete_candidates = repo_keys - keys
|
72
85
|
|
73
86
|
delete_candidates.each do |key|
|
74
|
-
say "delete
|
87
|
+
say "delete !txtpur!#{key} "
|
75
88
|
success = github.delete_secret repo, key
|
76
89
|
say "!txtgrn!OK"
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
80
|
-
def update_repo(repo,
|
81
|
-
|
82
|
-
say "save
|
83
|
-
github.put_secret repo, key,
|
93
|
+
def update_repo(repo, secrets)
|
94
|
+
secrets.each do |key, value|
|
95
|
+
say "save !txtpur!#{key} "
|
96
|
+
github.put_secret repo, key, value
|
84
97
|
say "!txtgrn!OK"
|
85
98
|
end
|
86
99
|
end
|
87
100
|
|
88
|
-
def secret_value(key)
|
89
|
-
ENV[key] || raise(EnvironmentError, "Please set the #{key} environment variable")
|
90
|
-
end
|
91
|
-
|
92
101
|
def config_file
|
93
102
|
args['CONFIG'] || 'secrethub.yml'
|
94
103
|
end
|
95
104
|
|
96
105
|
def config
|
97
|
-
|
98
|
-
|
99
|
-
|
106
|
+
@config ||= Config.load config_file
|
107
|
+
end
|
108
|
+
|
109
|
+
def config_template
|
110
|
+
File.expand_path '../config-template.yml', __dir__
|
100
111
|
end
|
101
112
|
end
|
102
113
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Ignored keys
|
2
|
+
# Keys that do not include '/' will be ignored
|
3
|
+
# Can be used to set some reusable YAML anchors
|
4
|
+
docker: &docker
|
5
|
+
DOCKER_USER:
|
6
|
+
DOCKER_PASSWORD:
|
7
|
+
|
8
|
+
# Array syntax
|
9
|
+
# All secrets must be defined as environment variables
|
10
|
+
user/repo:
|
11
|
+
- SECRET
|
12
|
+
- PASSWORD
|
13
|
+
|
14
|
+
# Hash syntax
|
15
|
+
# Empty secrets will be loaded from environment variables
|
16
|
+
user/another-repo:
|
17
|
+
<<: *docker
|
18
|
+
SECRET:
|
19
|
+
PASSWORD: p4ssw0rd
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module SecretHub
|
4
|
+
class Config
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def self.load(config_file)
|
8
|
+
raise ConfigurationError, "Config file not found #{config_flie}" unless File.exist? config_file
|
9
|
+
new YAML.load_file config_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(data)
|
13
|
+
@data = data
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_h
|
17
|
+
@to_h ||= to_h!
|
18
|
+
end
|
19
|
+
|
20
|
+
def each(&block)
|
21
|
+
to_h.each &block
|
22
|
+
end
|
23
|
+
|
24
|
+
def each_repo(&block)
|
25
|
+
to_h.keys.each &block
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def to_h!
|
31
|
+
result = {}
|
32
|
+
data.each do |repo, secrets|
|
33
|
+
next unless repo.include? '/'
|
34
|
+
result[repo] = resolve_secrets secrets
|
35
|
+
end
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
def resolve_secrets(secrets)
|
40
|
+
secrets = [] unless secrets
|
41
|
+
|
42
|
+
if secrets.is_a? Hash
|
43
|
+
secrets.map { |key, value| [key, value || value_from_env(key)] }.to_h
|
44
|
+
elsif secrets.is_a? Array
|
45
|
+
secrets.map { |key| [key, value_from_env(key)] }.to_h
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def value_from_env(key)
|
51
|
+
ENV[key] || raise(MissingSecretError, "Please set the #{key} environment variable")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'string-obfuscator'
|
2
|
+
|
3
|
+
module SecretHub
|
4
|
+
module StringObfuscation
|
5
|
+
refine String do
|
6
|
+
def obfuscate
|
7
|
+
text = dup
|
8
|
+
trim = false
|
9
|
+
|
10
|
+
if text.size > 40
|
11
|
+
trim = true
|
12
|
+
text = text[0..40]
|
13
|
+
end
|
14
|
+
|
15
|
+
result = StringObfuscator.obfuscate text,
|
16
|
+
percent: 60,
|
17
|
+
min_obfuscated_length: 5
|
18
|
+
|
19
|
+
trim ? "#{result}..." : result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/secret_hub/version.rb
CHANGED
data/lib/secret_hub.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: secret_hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '7.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: string-obfuscator
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.1'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.1'
|
83
97
|
description: Command line interface for managing GitHub secrets in bulk
|
84
98
|
email: db@dannyben.com
|
85
99
|
executables:
|
@@ -96,8 +110,11 @@ files:
|
|
96
110
|
- lib/secret_hub/commands/delete.rb
|
97
111
|
- lib/secret_hub/commands/list.rb
|
98
112
|
- lib/secret_hub/commands/save.rb
|
113
|
+
- lib/secret_hub/config-template.yml
|
114
|
+
- lib/secret_hub/config.rb
|
99
115
|
- lib/secret_hub/exceptions.rb
|
100
116
|
- lib/secret_hub/github_client.rb
|
117
|
+
- lib/secret_hub/refinements/string_obfuscation.rb
|
101
118
|
- lib/secret_hub/sodium.rb
|
102
119
|
- lib/secret_hub/version.rb
|
103
120
|
homepage: https://github.com/dannyben/secret_hub
|