ssssh 1.2.1 → 1.3.0
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/.rubocop.yml +47 -0
- data/Gemfile +2 -1
- data/README.md +37 -0
- data/Rakefile +0 -1
- data/bin/ssssh +52 -15
- data/lib/ssssh/version.rb +1 -1
- data/ssssh.gemspec +7 -8
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec83c64bc73fb62f33c58e3d27dc8cef20b26d7c
|
4
|
+
data.tar.gz: 1aa27d50991b8b39e64c9cfe283ba933eba4c774
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c541acd7989e44f795e47e273ec33efce13dfea19a6136d48f12cab94d637aa65d1ee803417dc8b2048acb32144c174c670e83dcf64dd5acb503bce37f7952a
|
7
|
+
data.tar.gz: 0d34316967b4225e652ec721a7cce6133379440e8a9c3230ed79c643361eb371b8eac5935aa7cbcd53829bfa8a71d9d8c54a92078aedad09123c0c4c3d6e35ff
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Eval:
|
2
|
+
Exclude:
|
3
|
+
- "Rakefile"
|
4
|
+
|
5
|
+
Metrics/AbcSize:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Metrics/LineLength:
|
9
|
+
Max: 120
|
10
|
+
|
11
|
+
Metrics/MethodLength:
|
12
|
+
Max: 30
|
13
|
+
|
14
|
+
Style/ClassAndModuleChildren:
|
15
|
+
EnforcedStyle: nested
|
16
|
+
Exclude:
|
17
|
+
- "spec/**/*"
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Exclude:
|
21
|
+
- "spec/**/*"
|
22
|
+
|
23
|
+
Style/EmptyLinesAroundBlockBody:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/EmptyLinesAroundClassBody:
|
27
|
+
EnforcedStyle: empty_lines
|
28
|
+
|
29
|
+
Style/EmptyLinesAroundModuleBody:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/Encoding:
|
33
|
+
EnforcedStyle: when_needed
|
34
|
+
Enabled: true
|
35
|
+
|
36
|
+
Style/FileName:
|
37
|
+
Exclude:
|
38
|
+
- "bin/*"
|
39
|
+
|
40
|
+
Style/HashSyntax:
|
41
|
+
EnforcedStyle: hash_rockets
|
42
|
+
|
43
|
+
Style/StringLiterals:
|
44
|
+
EnforcedStyle: double_quotes
|
45
|
+
|
46
|
+
Style/WordArray:
|
47
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -20,6 +20,34 @@ Naturally, suitable AWS credentials must be provided (via environment variables,
|
|
20
20
|
|
21
21
|
"ssssh" can only encrypt small amounts of data; up to 4 KB.
|
22
22
|
|
23
|
+
## Use as a command shim
|
24
|
+
|
25
|
+
"ssssh exec" is a command shim that makes it easy to use secrets transported
|
26
|
+
via the (Unix) process environment. It decrypts any environment variables
|
27
|
+
prefixed by "`KMS_ENCRYPTED_`", and executes a specified command.
|
28
|
+
|
29
|
+
For example:
|
30
|
+
|
31
|
+
```
|
32
|
+
$ export KMS_ENCRYPTED_DB_PASSWORD=$(ssssh encrypt alias/app-secrets 'seasame')
|
33
|
+
$ ssssh exec -- env | grep PASSWORD
|
34
|
+
KMS_ENCRYPTED_DB_PASSWORD=CiAbQLOo2VC4QTV/Ng986wsDSJ0srAe6oZnLyzRT6pDFWRKOAQEBAgB4G0CzqNlQuEE1fzYPfOsLA0idLKwHuqGZy8s0U+qQxVkAAABlMGMGCSqGSIb3DQEHBqBWMFQCAQAwTwYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAzfFR0tsHRq18JUhMcCARCAImvuMNYuHUut3BT7sZs9a31qWcmOBUBXYEsD+kx2GxUxBPE=
|
35
|
+
DB_PASSWORD=seasame
|
36
|
+
```
|
37
|
+
|
38
|
+
In this example, "ssssh exec":
|
39
|
+
|
40
|
+
- found `$KMS_ENCRYPTED_DB_PASSWORD` in the environment
|
41
|
+
- decrypted the contents
|
42
|
+
- put the result in `$DB_PASSWORD`
|
43
|
+
- executed `env`
|
44
|
+
|
45
|
+
"ssssh exec" works well as an entrypoint for Docker images, e.g.
|
46
|
+
|
47
|
+
# Include "ssssh" to decode KMS_ENCRYPTED_STUFF
|
48
|
+
RUN gem install ssssh
|
49
|
+
ENTRYPOINT ["ssssh", "exec", "--"]
|
50
|
+
|
23
51
|
## See also
|
24
52
|
|
25
53
|
If you'd rather install a Python interpreter than a Ruby one, secrets may also be decrypted using the AWS CLI.
|
@@ -27,8 +55,17 @@ If you'd rather install a Python interpreter than a Ruby one, secrets may also b
|
|
27
55
|
base64 -d < secrets.encrypted > /tmp/secrets.bin
|
28
56
|
aws kms decrypt --ciphertext-blob fileb:///tmp/secrets.bin --output text --query Plaintext | base64 -d > secrets.txt
|
29
57
|
|
58
|
+
If you'd rather not install an interpreter at all, there's a Go-lang port of "ssssh":
|
59
|
+
|
60
|
+
* https://github.com/realestate-com-au/shush
|
61
|
+
|
30
62
|
## Changes
|
31
63
|
|
64
|
+
### 1.3.0 (2016-10-26)
|
65
|
+
|
66
|
+
* Add `ssssh exec` subcommand.
|
67
|
+
* Add support for `$KMS_ENCRYPTION_CONTEXT`.
|
68
|
+
|
32
69
|
### 1.2.0 (2015-04-27)
|
33
70
|
|
34
71
|
* Add support for encryption contexts (`--context` option).
|
data/Rakefile
CHANGED
data/bin/ssssh
CHANGED
@@ -12,7 +12,8 @@ Clamp do
|
|
12
12
|
|
13
13
|
option ["-C", "--context"], "KEY=VALUE",
|
14
14
|
"add to encryption context\n (may be specified multiple times)",
|
15
|
-
:multivalued => true
|
15
|
+
:multivalued => true,
|
16
|
+
:environment_variable => "KMS_ENCRYPTION_CONTEXT"
|
16
17
|
|
17
18
|
option ["--region"], "REGION", "AWS region",
|
18
19
|
:environment_variable => "AWS_REGION", :required => true
|
@@ -41,8 +42,8 @@ Clamp do
|
|
41
42
|
parameter "[PLAINTEXT]", "plaintext", :default => "STDIN"
|
42
43
|
|
43
44
|
def execute
|
44
|
-
result =
|
45
|
-
result.
|
45
|
+
result = encrypt(plaintext, key_id)
|
46
|
+
result.delete!("\n") unless wrap?
|
46
47
|
puts result
|
47
48
|
end
|
48
49
|
|
@@ -60,7 +61,7 @@ Clamp do
|
|
60
61
|
|
61
62
|
def execute
|
62
63
|
return if ciphertext.empty?
|
63
|
-
puts decrypt(
|
64
|
+
puts decrypt(ciphertext)
|
64
65
|
end
|
65
66
|
|
66
67
|
private
|
@@ -71,6 +72,46 @@ Clamp do
|
|
71
72
|
|
72
73
|
end
|
73
74
|
|
75
|
+
subcommand "exec", "Execute a command" do
|
76
|
+
|
77
|
+
option "--prefix", "PREFIX", "environment variable prefix",
|
78
|
+
:default => "KMS_ENCRYPTED_"
|
79
|
+
|
80
|
+
parameter "COMMAND ...", "command to execute", :attribute_name => :command
|
81
|
+
|
82
|
+
def execute
|
83
|
+
exec(decrypted_env, *command)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def decrypted_env
|
89
|
+
{}.tap do |result|
|
90
|
+
ENV.each do |name, ciphertext|
|
91
|
+
next unless name.start_with?(prefix)
|
92
|
+
begin
|
93
|
+
plaintext_name = name[prefix.length .. -1]
|
94
|
+
plaintext = decrypt(ciphertext)
|
95
|
+
result[plaintext_name] = plaintext
|
96
|
+
rescue Aws::KMS::Errors::InvalidCiphertextException => e
|
97
|
+
signal_error("cannot decrypt $#{name}; invalid ciphertext", :status => 1)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def run(*args)
|
106
|
+
super(*args)
|
107
|
+
rescue Aws::Errors::MissingCredentialsError
|
108
|
+
signal_error "no credentials provided"
|
109
|
+
rescue Aws::KMS::Errors::InvalidCiphertextException => e
|
110
|
+
signal_error("invalid ciphertext", :status => 1)
|
111
|
+
rescue Aws::KMS::Errors::ServiceError => e
|
112
|
+
signal_error(e.message, :status => 9)
|
113
|
+
end
|
114
|
+
|
74
115
|
protected
|
75
116
|
|
76
117
|
def default_region
|
@@ -90,7 +131,7 @@ Clamp do
|
|
90
131
|
:session_token => session_token,
|
91
132
|
:region => region,
|
92
133
|
:logger => logger, :log_level => :debug
|
93
|
-
}.reject { |
|
134
|
+
}.reject { |_k, v| v.nil? || v == "" }
|
94
135
|
end
|
95
136
|
|
96
137
|
def ec2_instance_metadata
|
@@ -107,10 +148,6 @@ Clamp do
|
|
107
148
|
|
108
149
|
def with_kms
|
109
150
|
yield Aws::KMS::Client.new(aws_config)
|
110
|
-
rescue Aws::KMS::Errors::InvalidCiphertextException
|
111
|
-
signal_error("Invalid Ciphertext", :status => 1)
|
112
|
-
rescue Aws::KMS::Errors::ServiceError => e
|
113
|
-
signal_error(e.message, :status => 9)
|
114
151
|
end
|
115
152
|
|
116
153
|
def encryption_context
|
@@ -118,11 +155,11 @@ Clamp do
|
|
118
155
|
end
|
119
156
|
|
120
157
|
def append_to_context_list(context_string)
|
121
|
-
|
122
|
-
|
123
|
-
raise ArgumentError, "KEY=VALUE expected"
|
158
|
+
context_string.split(",").each do |pair|
|
159
|
+
key, value = pair.split("=", 2)
|
160
|
+
raise ArgumentError, "KEY=VALUE expected" if value.nil?
|
161
|
+
encryption_context[key] = value
|
124
162
|
end
|
125
|
-
encryption_context[key] = value
|
126
163
|
end
|
127
164
|
|
128
165
|
def encrypt(plaintext, key_id)
|
@@ -132,14 +169,14 @@ Clamp do
|
|
132
169
|
:plaintext => plaintext,
|
133
170
|
:encryption_context => encryption_context
|
134
171
|
}
|
135
|
-
kms.encrypt(encryption_params).ciphertext_blob
|
172
|
+
Base64.encode64(kms.encrypt(encryption_params).ciphertext_blob)
|
136
173
|
end
|
137
174
|
end
|
138
175
|
|
139
176
|
def decrypt(ciphertext)
|
140
177
|
with_kms do |kms|
|
141
178
|
decryption_params = {
|
142
|
-
:ciphertext_blob => ciphertext,
|
179
|
+
:ciphertext_blob => Base64.decode64(ciphertext),
|
143
180
|
:encryption_context => encryption_context
|
144
181
|
}
|
145
182
|
kms.decrypt(decryption_params).plaintext
|
data/lib/ssssh/version.rb
CHANGED
data/ssssh.gemspec
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "ssssh/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
|
8
7
|
spec.name = "ssssh"
|
9
8
|
spec.version = Ssssh::VERSION
|
10
|
-
spec.summary =
|
11
|
-
spec.description =
|
12
|
-
|
9
|
+
spec.summary = "It's a secret!"
|
10
|
+
spec.description = '"ssssh" is a small tool that can be used to encrypt and decrypt secrets, using the AWS "Key Management Service" (KMS).
|
11
|
+
'
|
13
12
|
spec.license = "MIT"
|
14
13
|
|
15
14
|
spec.authors = ["Mike Williams"]
|
@@ -22,10 +21,10 @@ Gem::Specification.new do |spec|
|
|
22
21
|
spec.require_paths = ["lib"]
|
23
22
|
|
24
23
|
spec.add_runtime_dependency "aws-sdk-core", "~> 2.0"
|
25
|
-
spec.add_runtime_dependency "clamp", ">= 0
|
24
|
+
spec.add_runtime_dependency "clamp", ">= 1.0"
|
26
25
|
spec.add_runtime_dependency "multi_json"
|
27
26
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 1.
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
29
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
30
29
|
|
31
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ssssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-core
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: multi_json
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1.
|
61
|
+
version: '1.13'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1.
|
68
|
+
version: '1.13'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,8 +80,10 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '10.0'
|
83
|
-
description:
|
84
|
-
|
83
|
+
description: '"ssssh" is a small tool that can be used to encrypt and decrypt secrets,
|
84
|
+
using the AWS "Key Management Service" (KMS).
|
85
|
+
|
86
|
+
'
|
85
87
|
email:
|
86
88
|
- mdub@dogbiscuit.org
|
87
89
|
executables:
|
@@ -90,6 +92,7 @@ extensions: []
|
|
90
92
|
extra_rdoc_files: []
|
91
93
|
files:
|
92
94
|
- ".gitignore"
|
95
|
+
- ".rubocop.yml"
|
93
96
|
- Gemfile
|
94
97
|
- LICENSE.txt
|
95
98
|
- README.md
|
@@ -117,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
120
|
version: '0'
|
118
121
|
requirements: []
|
119
122
|
rubyforge_project:
|
120
|
-
rubygems_version: 2.
|
123
|
+
rubygems_version: 2.6.7
|
121
124
|
signing_key:
|
122
125
|
specification_version: 4
|
123
126
|
summary: It's a secret!
|