inspec-vault 0.0.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7afd48c6772df42d77ed99c42c5492030ec90610
4
- data.tar.gz: e8f71d4de6c89af85203da46215bca95fb5a1766
2
+ SHA256:
3
+ metadata.gz: cfbbbb425fb095bdf5a4124f20a3475f87f6d983074339889156e70eccb1cbc7
4
+ data.tar.gz: c45dcca2381837fbb2380467ac66eae9321fce02ef23d5ab8cea27403ce9ca21
5
5
  SHA512:
6
- metadata.gz: 422c66def196ccc63ed1cffbd1f6f52e16c2259b89b89d43c67a28d04a441bde0fcb816c985ab7fb739e49045d36b5d97cdc912e93607e4430e676f3adb14370
7
- data.tar.gz: 6569769e23f6fd1320f9228e6f4cd2630d10bf0d6e5f8ca17640e516e11bd73d17600e2300a40a843c844179c68e8d049dabd354b5fae127817556e16110ccf2
6
+ metadata.gz: fe1329781eca561a3788ed933bc5a46729447819be483e047095217caf4ae53d233e23936bf0201729e99b5c3cfc3a7096b7b9586c58a52908dec34fdaa88684
7
+ data.tar.gz: 803e458ad47d5f518691b0e265c997689ffa045c3c144be241361436e342669f4fc4229f3c888c411b1c97657b19f2f01a391ca6e5601d277fffcb6cbb3bbbe6
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
5
+
6
+ gem "inspec-bin"
7
+
8
+ group :development do
9
+ gem "chefstyle", "0.13.0"
10
+ gem "m"
11
+ gem "bundler"
12
+ gem "byebug"
13
+ gem "minitest"
14
+ gem "rake"
15
+ gem "rubocop"
16
+ end
@@ -0,0 +1,114 @@
1
+ # inspec-vault Plugin
2
+
3
+ This is a plugin for [Chef InSpec](https://www.inspec.io/) that allows [Inputs](https://www.inspec.io/docs/reference/inputs/) to be read from [HashiCorp Vault](https://www.vaultproject.io/).
4
+
5
+ * **Project State: Active** (but EXPERIMENTAL)
6
+ * **Issues Response SLA: 3 business days**
7
+ * **Pull Request Response SLA: 3 business days**
8
+
9
+ For more information on project states and SLAs, see [this documentation](https://github.com/chef/chef-oss-practices/blob/master/repo-management/repo-states.md).
10
+
11
+ ## Notice - Experimental Project
12
+
13
+ This Chef InSpec plugin is in the early stages of research and development. Functionality may be defective, incomplete, or be withdrawn in the future. If you are interested in helping this project mature, please join the conversation or contribute code at the [inspec-vault project](https://github.com/inspec/inspec-vault).
14
+
15
+ ## To Install This Plugin
16
+
17
+ Assuming it has been published to RubyGems, you can install this gem using:
18
+
19
+ ```
20
+ you@machine $ inspec plugin install inspec-vault
21
+ ```
22
+
23
+ ## Loading Secrets into Vault
24
+
25
+ A full introduction to Vault is beyond the scope of this document, but begin by downloading a recent version from https://www.vaultproject.io . Then, start a Vault dev-mode server with the following command:
26
+
27
+ ```
28
+ $ vault server -dev
29
+ ```
30
+
31
+ From there, you can then store an input. For example, look at the command below to store an input named `my_input` with the value of 2, for the `my_profile` profile. Once entered, Vault responds with metadata about the entry.
32
+
33
+ ```
34
+ [cwolfe@lodi inspec-vault]$ vault kv put secret/inspec/my_profile my_input=2
35
+ Key Value
36
+ --- -----
37
+ created_time 2019-09-10T17:54:16.237055Z
38
+ deletion_time n/a
39
+ destroyed false
40
+ version 1
41
+ ```
42
+
43
+ With that value stored, Chef InSpec will now be able to retrieve the value.
44
+
45
+ ## What This Plugin Does
46
+
47
+ With the inspec-vault plugin enabled, Chef InSpec will contact the Vault server whenever an `input()` DSL call appears in profile control code. For example, whenever profile code like this is encountered:
48
+
49
+ ```ruby
50
+ # In profile "my_profile"
51
+ describe input("some_input") do
52
+ it { should cmp "some_expected_value" }
53
+ end
54
+ ```
55
+
56
+ Chef InSpec will determine a secret lookup path and access Vault. With no other settings, Chef InSpec will look for a Vault secret located at `secret/inspec/my_profile` with a key named "some_input". Chef InSpec will use the Vault secret if found, but otherwise it will fall back to other means of resolving the input, such as the profile metadata or CLI values.
57
+
58
+ ## Configuring the Plugin
59
+
60
+ Each plugin option may be set either as an environment variable, or as a plugin option in your Chef InSpec configuration file at `~/.inspec/config.json`. For example, to set the `prefix_path` option in the config file, lay out the config file as follows:
61
+
62
+ ```json
63
+ {
64
+ "version": "1.2",
65
+ "plugins":{
66
+ "inspec-vault":{
67
+ "prefix_path":"my-profiles"
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ Config file option names are always lowercase.
74
+
75
+ This plugin supports the following options:
76
+
77
+ ### INSPEC_VAULT_MOUNT_POINT
78
+
79
+ ### mount_point
80
+
81
+ A string that indicates where the key-value path should begin; default value is "secret". The path is constructed as `<mount_point>/data/<path_prefix>/<profile_name>`.
82
+
83
+ ### INSPEC_VAULT_PATH_PREFIX
84
+
85
+ ### path_prefix
86
+
87
+ A string that indicates the latter portion of the key-value path; default value is "inspec". The path is constructed as `<mount_point>/data/<path_prefix>/<profile_name>`.
88
+
89
+ ### INSPEC_VAULT_PRIORITY
90
+
91
+ ### priority
92
+
93
+ A number between 0 and 100, default 60. When two input provides both provide a value for the same input name, the priority determines which providers' value is used, with the higher priority prevailing. Core Chef InSpec providers only range up to 50, so inspec-vault will (by default) override any other input provider.
94
+
95
+ ### VAULT_ADDR
96
+
97
+ ### vault_addr
98
+
99
+ This environment variable is the URL and port of your Vault installation. Default is http://127.0.0.1:8200.
100
+
101
+ ### VAULT_TOKEN
102
+
103
+ This value is the secret used to authenticate to Vault. Required, no default provided.
104
+
105
+ ## Developing This Plugin
106
+
107
+ Please have a look at our CONTRIBUTING.md for general guidelines.
108
+
109
+ ### Testing
110
+
111
+ Run `bundle exec rake test:lint` for linting, `bundle exec rake test:unit` for unit tests, and `bundle exec rake test:integration` for integration tests.
112
+
113
+ Note that integration tests will download and run Vault server locally.
114
+
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ # As plugins are usually packaged and distributed as a RubyGem,
4
+ # we have to provide a .gemspec file, which controls the gembuild
5
+ # and publish process. This is a fairly generic gemspec.
6
+
7
+ # It is traditional in a gemspec to dynamically load the current version
8
+ # from a file in the source tree. The next three lines make that happen.
9
+ lib = File.expand_path("../lib", __FILE__)
10
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
11
+ require "inspec-vault/version"
12
+
13
+ Gem::Specification.new do |spec|
14
+ # Importantly, all InSpec plugins must be prefixed with `inspec-` (most
15
+ # plugins) or `train-` (plugins which add new connectivity features).
16
+ spec.name = "inspec-vault"
17
+
18
+ # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
19
+ spec.version = InspecPlugins::Vault::VERSION
20
+ spec.authors = ["InSpec Core Engineering"]
21
+ spec.email = ["inspec@chef.io"]
22
+ spec.summary = "Use HashiCorp Vault data in your InSpec profiles"
23
+ spec.description = "This plugin allows InSpec 'inputs' to be provided by a HashiCorp Vault installation. This enables you to unify your secrets management with your compliance automation."
24
+ spec.homepage = "https://github.com/inspec/inspec-vault"
25
+ spec.license = "Apache-2.0"
26
+
27
+ # Though complicated-looking, this is pretty standard for a gemspec.
28
+ # It just filters what will actually be packaged in the gem (leaving
29
+ # out tests, etc)
30
+ spec.files = %w{
31
+ README.md inspec-vault.gemspec Gemfile
32
+ } + Dir.glob(
33
+ "lib/**/*", File::FNM_DOTMATCH
34
+ ).reject { |f| File.directory?(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ # If you rely on any other gems, list them here with any constraints.
38
+ # This is how `inspec plugin install` is able to manage your dependencies.
39
+ spec.add_dependency "vault", "~> 0.12"
40
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ # This file is known as the "entry point."
4
+ # This is the file InSpec will try to load if it
5
+ # thinks your plugin is installed.
6
+
7
+ # The *only* thing this file should do is setup the
8
+ # load path, then load the plugin definition file.
9
+
10
+ # Next two lines simply add the path of the gem to the load path.
11
+ # This is not needed when being loaded as a gem; but when doing
12
+ # plugin development, you may need it. Either way, it's harmless.
13
+ libdir = File.dirname(__FILE__)
14
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
15
+
16
+ require "inspec-vault/plugin"
@@ -0,0 +1,79 @@
1
+ require "vault"
2
+
3
+ # See https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md#implementing-input-plugins
4
+
5
+ module InspecPlugins::Vault
6
+ class Input < Inspec.plugin(2, :input)
7
+
8
+ attr_reader :plugin_conf
9
+ attr_reader :mount_point
10
+ attr_reader :path_prefix
11
+ attr_reader :vault
12
+ attr_reader :priority
13
+
14
+ def initialize
15
+ @plugin_conf = Inspec::Config.cached.fetch_plugin_config("inspec-vault")
16
+
17
+ @mount_point = fetch_plugin_setting("mount_point", "secret")
18
+ @path_prefix = fetch_plugin_setting("path_prefix", "inspec")
19
+
20
+ # We need priority to be numeric; even though env vars or JSON may present it as string - hence the to_i
21
+ @priority = fetch_plugin_setting("priority", 60).to_i
22
+
23
+ @vault = Vault::Client.new(
24
+ address: fetch_vault_setting("vault_addr"),
25
+ token: fetch_vault_setting("vault_token")
26
+ )
27
+ end
28
+
29
+ # What priority should an input value recieve from us?
30
+ # This plgin does not currently allow setting this on a per-input basis,
31
+ # so they all recieve the same "default" value.
32
+ # Implements https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md#default_priority
33
+ def default_priority
34
+ priority
35
+ end
36
+
37
+ # returns Array of input names as strings
38
+ def list_inputs(profile_name)
39
+ vault.with_retries(Vault::HTTPConnectionError) do
40
+ path = logical_path_for_profile(profile_name)
41
+ doc = vault.logical.read(path)
42
+ return [] unless doc
43
+ return doc.data[:data].keys.map(&:to_s)
44
+ end
45
+ end
46
+
47
+ # Fetch a value of a single input from Vault
48
+ # Assumption: inputs have been stored on documents named for their
49
+ # profiles, and each input has a key-value pair in the document.
50
+ # TODO we should probably cache these - https://github.com/inspec/inspec-vault/issues/15
51
+ def fetch(profile_name, input_name)
52
+ path = logical_path_for_profile(profile_name)
53
+ vault.with_retries(Vault::HTTPConnectionError) do
54
+ doc = vault.logical.read(path)
55
+ # Keys from vault are always symbolized
56
+ return doc.data[:data][input_name.to_sym] if doc
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def logical_path_for_profile(profile_name)
63
+ # When you actually read a value, on the KV2 backend you must
64
+ # read secret/data/path, not secret/path (as on the CLI)
65
+ # https://www.vaultproject.io/api/secret/kv/kv-v2.html#read-secret-version
66
+ # Is this true for all backends?
67
+ "#{mount_point}/data/#{path_prefix}/#{profile_name}"
68
+ end
69
+
70
+ def fetch_plugin_setting(setting_name, default = nil)
71
+ env_var_name = "INSPEC_VAULT_#{setting_name.upcase}"
72
+ ENV[env_var_name] || plugin_conf[setting_name] || default
73
+ end
74
+
75
+ def fetch_vault_setting(setting_name)
76
+ ENV[setting_name.upcase] || plugin_conf[setting_name]
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ # Plugin Definition file
4
+ # The purpose of this file is to declare to InSpec what plugin_types (capabilities)
5
+ # are included in this plugin, and provide hooks that will load them as needed.
6
+
7
+ # It is important that this file load successfully and *quickly*.
8
+ # Your plugin's functionality may never be used on this InSpec run; so we keep things
9
+ # fast and light by only loading heavy things when they are needed.
10
+
11
+ # Presumably this is light
12
+ require "inspec-vault/version"
13
+ module InspecPlugins
14
+ module Vault
15
+ class Plugin < ::Inspec.plugin(2)
16
+ # Internal machine name of the plugin. InSpec will use this in errors, etc.
17
+ plugin_name :'inspec-vault'
18
+
19
+ # Define an Input plugin type.
20
+ input :vault do
21
+ require_relative "input.rb"
22
+ InspecPlugins::Vault::Input
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: UTF-8
2
+
3
+ # This file simply makes it easier for CI engines to update
4
+ # the version stamp, and provide a clean way for the gemspec
5
+ # to learn the current version.
6
+ module InspecPlugins
7
+ module Vault
8
+ VERSION = "0.3.2".freeze
9
+ end
10
+ end
metadata CHANGED
@@ -1,23 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec-vault
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
- - Jared Quick
7
+ - InSpec Core Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-19 00:00:00.000000000 Z
12
- dependencies: []
13
- description:
11
+ date: 2019-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: vault
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.12'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.12'
27
+ description: This plugin allows InSpec 'inputs' to be provided by a HashiCorp Vault
28
+ installation. This enables you to unify your secrets management with your compliance
29
+ automation.
14
30
  email:
15
- - jquick@chef.io
31
+ - inspec@chef.io
16
32
  executables: []
17
33
  extensions: []
18
34
  extra_rdoc_files: []
19
- files: []
20
- homepage: https://github.com/inspec/inspec
35
+ files:
36
+ - Gemfile
37
+ - README.md
38
+ - inspec-vault.gemspec
39
+ - lib/inspec-vault.rb
40
+ - lib/inspec-vault/input.rb
41
+ - lib/inspec-vault/plugin.rb
42
+ - lib/inspec-vault/version.rb
43
+ homepage: https://github.com/inspec/inspec-vault
21
44
  licenses:
22
45
  - Apache-2.0
23
46
  metadata: {}
@@ -36,9 +59,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
36
59
  - !ruby/object:Gem::Version
37
60
  version: '0'
38
61
  requirements: []
39
- rubyforge_project:
40
- rubygems_version: 2.6.14
62
+ rubygems_version: 3.0.3
41
63
  signing_key:
42
64
  specification_version: 4
43
- summary: inspec-vault plugin UNDER CONSTRUCTION
65
+ summary: Use HashiCorp Vault data in your InSpec profiles
44
66
  test_files: []