cipherpipe 0.2.4 → 0.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/Gemfile.lock +3 -1
- data/README.md +12 -3
- data/cipherpipe.gemspec +6 -5
- data/lib/cipherpipe/configuration.rb +4 -8
- data/lib/cipherpipe/external_source.rb +10 -6
- data/lib/cipherpipe/one_password.rb +17 -0
- data/lib/cipherpipe/one_password/download.rb +38 -0
- data/lib/cipherpipe/one_password/upload.rb +39 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fbd9abc8551bd0d9d03d7fd91e1d4eb1c57ca0bffd8d12c0d8a13412fc23e8e
|
4
|
+
data.tar.gz: cbfee38900e2ed2bd30328c1789532fa53f3aa6f27b8ea56c0296948e97a9439
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae3d44347e9f054c72bc838e83ff29d50e848dc46f47ab4aa78dbf0c114749141184037488452b48c986e13cc48a82fb93df594dbeaa4836632df366644bc35
|
7
|
+
data.tar.gz: '0079cb88864cd97ffea062d65ffdbd96ce20d3a4ab3b7fc0c5c44be67bc135102926d6ac939ebf39f13129654729f893466363f8a1555430fff7afad35b82257'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cipherpipe (0.
|
4
|
+
cipherpipe (0.3.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -29,6 +29,7 @@ GEM
|
|
29
29
|
rspec-support (~> 3.7.0)
|
30
30
|
rspec-support (3.7.1)
|
31
31
|
safe_yaml (1.0.4)
|
32
|
+
shell_mock (0.3.3)
|
32
33
|
vault (0.11.0)
|
33
34
|
aws-sigv4
|
34
35
|
webmock (3.4.2)
|
@@ -44,6 +45,7 @@ DEPENDENCIES
|
|
44
45
|
cipherpipe!
|
45
46
|
rake (~> 12.0)
|
46
47
|
rspec (~> 3.7)
|
48
|
+
shell_mock (~> 0.3.3)
|
47
49
|
vault (~> 0.11)
|
48
50
|
webmock (~> 3.4)
|
49
51
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Cipherpipe
|
2
2
|
|
3
|
-
Cipherpipe transfers secrets from stores (such as Vault) onto your local machine, or into the `ENV` of a Ruby app. You can then make changes and upload these back into the store - all of which is done only when you have valid access.
|
3
|
+
Cipherpipe transfers secrets from stores (such as Vault and 1Password) onto your local machine, or into the `ENV` of a Ruby app. You can then make changes and upload these back into the store - all of which is done only when you have valid access.
|
4
4
|
|
5
5
|
## Why?
|
6
6
|
|
@@ -34,11 +34,13 @@ Cipherpipe::Commands::Load.call
|
|
34
34
|
|
35
35
|
If you're using Vault's EC2 authentication and have specified an `ec2_role` value for the primary source (as noted in the configuration example below), then loading the secrets will automatically authenticate against Vault using the EC2 instance's PKCS7-signed identity.
|
36
36
|
|
37
|
+
If you're using 1Password, you'll want to have [their command-line tool](https://support.1password.com/command-line-getting-started/) installed (testing has been conducted with v0.4.1). Any time you use cipherpipe commands that interact with 1Password, you'll have to be authenticated first (`op signin team-subdomain.1password.com me@myemail.com A3-XXXXXX-XXXXXX-XXXXX-XXXXX-XXXXX-XXXXX`).
|
38
|
+
|
37
39
|
## Configuration
|
38
40
|
|
39
41
|
Everything for Cipherpipe is managed in a YAML configuration file `.cipherpipe.yml` which you should place in the root of your project. You'll need to specify at least one source (and mark it as the primary). Having an output file/format is optional, but likely useful.
|
40
42
|
|
41
|
-
When setting a Vault source, the destination is a key-value store (v2) and the `secret/` prefix is added automatically.
|
43
|
+
When setting a Vault source, the destination is a key-value store (v2) and the `secret/` prefix is added automatically. When setting up 1Password, the destination is the name of the document, and you'll want to specify a vault as well.
|
42
44
|
|
43
45
|
Here's an example for a Rails application using `dotenv` (and `ENVIRONMENT` is automatically translated to the appropriate Rails environment, as based on the RAILS_ENV variable):
|
44
46
|
|
@@ -49,6 +51,9 @@ sources:
|
|
49
51
|
- type: vault
|
50
52
|
destination: apps/myapp/ENVIRONMENT
|
51
53
|
primary: true
|
54
|
+
- type: 1password
|
55
|
+
destination: "Apps: myapp ENVIRONMENT"
|
56
|
+
vault: Developers
|
52
57
|
```
|
53
58
|
|
54
59
|
If you're running this on EC2 servers that are set up to authenticate with Vault via a specific role, you can provide that with the `ec2_role` setting and it'll automatically be used:
|
@@ -85,6 +90,8 @@ sources:
|
|
85
90
|
primary: true
|
86
91
|
```
|
87
92
|
|
93
|
+
Note that you must have one primary source - the primary source is where data is downloaded from. Other sources are only for uploading (i.e. as a backup).
|
94
|
+
|
88
95
|
## Usage
|
89
96
|
|
90
97
|
Once you've got things configured, you can use the `cipherpipe` executable to download or upload configuration.
|
@@ -105,7 +112,9 @@ If you're using Vault's EC2 authentication and have specified an `ec2_role` valu
|
|
105
112
|
|
106
113
|
## Dependencies
|
107
114
|
|
108
|
-
If you're using Vault
|
115
|
+
If you're using Vault, you'll need to make sure it's using the V2 kv secrets engine.
|
116
|
+
|
117
|
+
If you're using 1Password, you'll need [their command-line tool](https://support.1password.com/command-line-getting-started/) installed (v0.4.1 or newer is recommended).
|
109
118
|
|
110
119
|
## Contributing
|
111
120
|
|
data/cipherpipe.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "cipherpipe"
|
3
|
-
spec.version = "0.
|
3
|
+
spec.version = "0.3.0"
|
4
4
|
spec.authors = ["Pat Allan"]
|
5
5
|
spec.email = ["pat@freelancing-gods.com"]
|
6
6
|
|
@@ -15,8 +15,9 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.executables = spec.files.grep(%r{^exe/}) { |file| File.basename(file) }
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
-
spec.add_development_dependency "bundler",
|
19
|
-
spec.add_development_dependency "rake",
|
20
|
-
spec.add_development_dependency "rspec",
|
21
|
-
spec.add_development_dependency "
|
18
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
19
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
20
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
21
|
+
spec.add_development_dependency "shell_mock", "~> 0.3.3"
|
22
|
+
spec.add_development_dependency "webmock", "~> 3.4"
|
22
23
|
end
|
@@ -49,15 +49,11 @@ class Cipherpipe::Configuration
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def parse_source(hash)
|
52
|
-
|
53
|
-
|
52
|
+
hash.each do |key, value|
|
53
|
+
hash[key] = value.gsub("ENVIRONMENT", environment) if value.is_a?(String)
|
54
|
+
end
|
54
55
|
|
55
|
-
Cipherpipe::ExternalSource.new
|
56
|
-
hash["type"],
|
57
|
-
hash["destination"].gsub("ENVIRONMENT", environment),
|
58
|
-
hash["primary"],
|
59
|
-
role
|
60
|
-
)
|
56
|
+
Cipherpipe::ExternalSource.new hash
|
61
57
|
end
|
62
58
|
|
63
59
|
def yaml
|
@@ -1,13 +1,14 @@
|
|
1
1
|
class Cipherpipe::ExternalSource
|
2
2
|
UnknownProviderError = Class.new Cipherpipe::Error
|
3
3
|
|
4
|
-
attr_reader :type, :destination, :primary, :ec2_role
|
4
|
+
attr_reader :type, :destination, :primary, :ec2_role, :options
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@type = type
|
8
|
-
@destination = destination
|
9
|
-
@primary = primary
|
10
|
-
@ec2_role = ec2_role
|
6
|
+
def initialize(options = {})
|
7
|
+
@type = options.delete "type"
|
8
|
+
@destination = options.delete "destination"
|
9
|
+
@primary = options.delete "primary"
|
10
|
+
@ec2_role = options.delete "ec2_role"
|
11
|
+
@options = options
|
11
12
|
end
|
12
13
|
|
13
14
|
def download
|
@@ -37,6 +38,9 @@ class Cipherpipe::ExternalSource
|
|
37
38
|
when "vault"
|
38
39
|
require_relative "vault"
|
39
40
|
Cipherpipe::Vault
|
41
|
+
when "1password"
|
42
|
+
require_relative "one_password"
|
43
|
+
Cipherpipe::OnePassword
|
40
44
|
else
|
41
45
|
raise UnknownProviderError, "unknown provider #{type}"
|
42
46
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Cipherpipe::OnePassword
|
2
|
+
def self.available?
|
3
|
+
!`which op`.empty?
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.download(external_source)
|
7
|
+
require_relative "one_password/download"
|
8
|
+
|
9
|
+
Cipherpipe::OnePassword::Download.call external_source
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.upload(external_source, settings)
|
13
|
+
require_relative "one_password/upload"
|
14
|
+
|
15
|
+
Cipherpipe::OnePassword::Upload.call external_source, settings
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
class Cipherpipe::OnePassword::Download
|
4
|
+
UnknownDocument = Class.new Cipherpipe::Error
|
5
|
+
|
6
|
+
def self.call(external_source)
|
7
|
+
new(external_source).call
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(external_source)
|
11
|
+
@external_source = external_source
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
hash = documents.detect do |document|
|
16
|
+
document["overview"]["title"] == external_source.destination
|
17
|
+
end
|
18
|
+
|
19
|
+
if hash.nil?
|
20
|
+
raise UnknownDocument,
|
21
|
+
"Cannot find #{external_source.destination} in 1Password vault #{vault}"
|
22
|
+
end
|
23
|
+
|
24
|
+
JSON.load `op get document \"#{hash["uuid"]}\" --vault \"#{vault}\"`
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :external_source
|
30
|
+
|
31
|
+
def documents
|
32
|
+
JSON.load `op list documents --vault \"#{vault}\"`
|
33
|
+
end
|
34
|
+
|
35
|
+
def vault
|
36
|
+
external_source.options["vault"]
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
class Cipherpipe::OnePassword::Upload
|
5
|
+
def self.call(external_source, variables)
|
6
|
+
new(external_source, variables).call
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(external_source, variables)
|
10
|
+
@external_source = external_source
|
11
|
+
@variables = variables
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
documents.each do |document|
|
16
|
+
next unless document["overview"]["title"] == external_source.destination
|
17
|
+
|
18
|
+
`op delete item "#{document["uuid"]}" --vault="#{vault}"`
|
19
|
+
end
|
20
|
+
|
21
|
+
Dir.mktmpdir do |directory|
|
22
|
+
File.write "#{directory}/cipherpipe.json", JSON.dump(variables)
|
23
|
+
|
24
|
+
`op create document "#{directory}/cipherpipe.json" --title="#{external_source.destination}" --vault="#{vault}"`
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :external_source, :variables
|
31
|
+
|
32
|
+
def documents
|
33
|
+
JSON.load `op list documents --vault "#{vault}"`
|
34
|
+
end
|
35
|
+
|
36
|
+
def vault
|
37
|
+
external_source.options["vault"]
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cipherpipe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: shell_mock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.3.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.3.3
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: webmock
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,6 +113,9 @@ files:
|
|
99
113
|
- lib/cipherpipe/formatters/env.rb
|
100
114
|
- lib/cipherpipe/formatters/hcl.rb
|
101
115
|
- lib/cipherpipe/formatters/json.rb
|
116
|
+
- lib/cipherpipe/one_password.rb
|
117
|
+
- lib/cipherpipe/one_password/download.rb
|
118
|
+
- lib/cipherpipe/one_password/upload.rb
|
102
119
|
- lib/cipherpipe/vault.rb
|
103
120
|
- lib/cipherpipe/vault/api.rb
|
104
121
|
- lib/cipherpipe/vault/download.rb
|