inspec 0.35.0 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -2
  3. data/Gemfile +6 -0
  4. data/Rakefile +3 -55
  5. data/docs/README.md +20 -0
  6. data/docs/cli.rst +6 -0
  7. data/docs/dsl_inspec.md +245 -0
  8. data/docs/dsl_resource.md +93 -0
  9. data/docs/inspec_and_friends.md +102 -0
  10. data/docs/matchers.md +136 -0
  11. data/docs/plugin_kitchen_inspec.html.md +55 -0
  12. data/docs/profiles.md +271 -0
  13. data/docs/resources.rst +1 -1
  14. data/docs/shell.md +150 -0
  15. data/inspec.gemspec +1 -1
  16. data/lib/bundles/inspec-compliance/api.rb +28 -18
  17. data/lib/bundles/inspec-compliance/cli.rb +19 -27
  18. data/lib/fetchers/git.rb +4 -0
  19. data/lib/fetchers/local.rb +16 -1
  20. data/lib/fetchers/mock.rb +4 -0
  21. data/lib/fetchers/url.rb +40 -12
  22. data/lib/inspec/base_cli.rb +4 -0
  23. data/lib/inspec/cli.rb +6 -8
  24. data/lib/inspec/control_eval_context.rb +8 -0
  25. data/lib/inspec/dependencies/{vendor_index.rb → cache.rb} +5 -4
  26. data/lib/inspec/dependencies/dependency_set.rb +8 -14
  27. data/lib/inspec/dependencies/requirement.rb +10 -20
  28. data/lib/inspec/dependencies/resolver.rb +2 -2
  29. data/lib/inspec/dsl.rb +9 -0
  30. data/lib/inspec/fetcher.rb +1 -1
  31. data/lib/inspec/objects/test.rb +8 -2
  32. data/lib/inspec/plugins/fetcher.rb +11 -12
  33. data/lib/inspec/plugins/resource.rb +3 -0
  34. data/lib/inspec/profile.rb +60 -14
  35. data/lib/inspec/profile_context.rb +28 -7
  36. data/lib/inspec/resource.rb +17 -2
  37. data/lib/inspec/rspec_json_formatter.rb +80 -35
  38. data/lib/inspec/runner.rb +42 -18
  39. data/lib/inspec/shell.rb +5 -16
  40. data/lib/inspec/version.rb +1 -1
  41. data/lib/resources/apache_conf.rb +1 -1
  42. data/lib/resources/gem.rb +1 -0
  43. data/lib/resources/oneget.rb +1 -0
  44. data/lib/resources/os.rb +1 -1
  45. data/lib/resources/package.rb +3 -1
  46. data/lib/resources/pip.rb +1 -1
  47. data/lib/resources/ssl.rb +9 -11
  48. metadata +15 -15
  49. data/docs/dsl_inspec.rst +0 -259
  50. data/docs/dsl_resource.rst +0 -90
  51. data/docs/inspec_and_friends.rst +0 -85
  52. data/docs/matchers.rst +0 -137
  53. data/docs/profiles.rst +0 -169
  54. data/docs/readme.rst +0 -105
  55. data/docs/shell.rst +0 -130
  56. data/docs/template.rst +0 -51
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: Resource DSL
3
+ ---
4
+
5
+ # Resource DSL
6
+
7
+ InSpec provides a mechanism for defining custom resources. These become
8
+ available with their respective names and provide easy functionality to
9
+ profiles.
10
+
11
+ ## Resource location
12
+
13
+ Resources may be added to profiles in the libraries folder:
14
+
15
+ ```bash
16
+ $ tree examples/profile
17
+ examples/profile
18
+ ...
19
+ ├── libraries
20
+ │   └── gordon_config.rb
21
+ ```
22
+
23
+ ## Resource structure
24
+
25
+ The smallest possible resource takes this form:
26
+
27
+ ```ruby
28
+ class Tiny < Inspec.resource(1)
29
+ name 'tiny'
30
+ end
31
+ ```
32
+
33
+ Resources are written as a regular Ruby class which inherits from
34
+ Inspec.resource. The number (1) specifies the version this resource
35
+ plugin targets. As InSpec evolves, this interface may change and may
36
+ require a higher version.
37
+
38
+ The following attributes can be configured:
39
+
40
+ * name - Identifier of the resource (required)
41
+ * desc - Description of the resource (optional)
42
+ * example - Example usage of the resource (optional)
43
+
44
+ The following methods are available to the resource:
45
+
46
+ * inspec - Contains a registry of all other resources to interact with the operating system or target in general.
47
+ * skip\_resource - A resource may call this method to indicate, that requirements aren't met. All tests that use this resource will be marked as skipped.
48
+
49
+ The following example shows a full resource using attributes and methods
50
+ to provide simple access to a configuration file:
51
+
52
+ ```ruby
53
+ class GordonConfig < Inspec.resource(1)
54
+ name 'gordon_config'
55
+
56
+ desc '
57
+ Resource description ...
58
+ '
59
+
60
+ example '
61
+ describe gordon_config do
62
+ its("signal") { should eq "on" }
63
+ end
64
+ '
65
+
66
+ # Load the configuration file on initialization
67
+ def initialize(path = nil)
68
+ @path = path || '/etc/gordon.conf'
69
+ @params = SimpleConfig.new( read_content )
70
+ end
71
+
72
+ # Expose all parameters of the configuration file.
73
+ def method_missing(name)
74
+ @params[name]
75
+ end
76
+
77
+ private
78
+
79
+ def read_content
80
+ f = inspec.file(@path)
81
+ # Test if the path exist and that it's a file
82
+ if f.file?
83
+ # Retrieve the file's contents
84
+ f.content
85
+ else
86
+ # If the file doesn't exist, skip all tests that use gordon_config
87
+ skip_resource "Can't read config from #{@path}."
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
93
+ For a full example, see our [example resource](../examples/profile/libraries/gordon_config.rb).
@@ -0,0 +1,102 @@
1
+ ---
2
+ title: InSpec and friends
3
+ ---
4
+
5
+ # InSpec and friends
6
+
7
+ ## RSpec
8
+
9
+ RSpec is an awesome framework that is widely used to test Ruby code. It
10
+ enables test-driven development (TDD) and helps developers to write
11
+ better code every day.
12
+
13
+ InSpec is built on top of RSpec and uses it as the underlying foundation
14
+ to execute tests. It uses the key strengths of RSpec, easily execute
15
+ tests and a DSL to write tests, but extends the functionality for use as
16
+ compliance audits. InSpec ships with custom audit resources that make it
17
+ easy to write audit checks and with the ability to run those checks on
18
+ remote servers. These audit resources provided know the differences
19
+ between operating systems and help you abstract from the local operating
20
+ system, similar to other resources you might use in your Chef recipes.
21
+
22
+ A complete InSpec rule looks like:
23
+
24
+ ```ruby
25
+ control "sshd-11" do
26
+ impact 1.0
27
+ title "Server: Set protocol version to SSHv2"
28
+ desc "Set the SSH protocol version to 2. Don't use legacy
29
+ insecure SSHv1 connections anymore."
30
+ tag security: "level-1"
31
+ tag "openssh-server"
32
+ ref "Server Security Guide v.1.0", url: "http://..."
33
+
34
+ describe sshd_config do
35
+ its('Protocol') { should eq('2') }
36
+ end
37
+ end
38
+ ```
39
+
40
+ ## Serverspec
41
+
42
+ Serverspec can be credited as the first extension of RSpec that enabled
43
+ users to run RSpec tests on servers to verify deployed artifacts. It was
44
+ created in March 2013 by Gosuke Miyashita and has been widely adopted.
45
+ It is also one of the core test frameworks within test-kitchen and has
46
+ been widely used within the Chef ecosystem. InSpec takes lessons learned
47
+ implementing and using Serverspec and builds on them to make auditing
48
+ and compliance easier.
49
+
50
+ Lessons learned from Serverspec include:
51
+
52
+ * IT, compliance, and security professional require metadata beyond what Serverspec offers, such as criticality, to fully describe controls.
53
+ * Setting up and running the same tests across multiple machines must be easy.
54
+ * It must be easy to locate, debug, and extend operating system-dependent code.
55
+ * It must be easy to extend the language and create custom resources.
56
+ * It must run multiple tests simultaneously.
57
+ * Support for Windows is a first-class requirement.
58
+ * A command line interface (CLI) is required for faster iteration of test code.
59
+
60
+ ### How is InSpec different than Serverspec
61
+
62
+ One of the key differences is that InSpec targets more user groups. It
63
+ is optimized for DevOps, Security, and Compliance professionals.
64
+ Additional metadata, such as impact, title, and description, make it
65
+ easier to fully describe the controls which makes it easier to share the
66
+ controls with other departments. This enables Security departments to
67
+ prioritize rules. DevOps teams use this information to focus on the most
68
+ critical issues to remediate.
69
+
70
+ ```ruby
71
+ control "sshd-11" do
72
+ impact 1.0
73
+ title "Server: Set protocol version to SSHv2"
74
+ desc "Set the SSH protocol version to 2. Don't use legacy
75
+ insecure SSHv1 connections anymore."
76
+ tag security: "level-1"
77
+ tag "openssh-server"
78
+ ref "Server Security Guide v.1.0" url: "http://..."
79
+
80
+ describe sshd_config do
81
+ its('Protocol') { should cmp 2 }
82
+ end
83
+ end
84
+ ```
85
+
86
+ **Why not fork Serverspec?**
87
+
88
+ InSpec started as an extension of Serverspec. As the extension grew, it
89
+ became clear that a new library was required. Creating and maintaining a
90
+ fork was not practical so a new project was born.
91
+
92
+ **Will InSpec only work on machines managed by Chef?**
93
+
94
+ No, InSpec can be used on any machine. It doesn’t matter if that machine
95
+ was configured by Chef or configured lovingly by the hands of your local
96
+ System Administrator.
97
+
98
+ **Is InSpec a replacement of Serverspec?**
99
+
100
+ InSpec is intended to be a drop-in replacement of Serverspec. Popular
101
+ Serverspec resources have been ported to InSpec. It changed some
102
+ behaviour as documented in our migration guide.
data/docs/matchers.md ADDED
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: InSpec Matchers Reference
3
+ ---
4
+
5
+ # InSpec Matchers Reference
6
+
7
+ Inspec uses matchers to help compare resource values to expectations.
8
+ The following matchers are available:
9
+
10
+ * `be`
11
+ * `cmp`
12
+ * `eq`
13
+ * `include`
14
+ * `match`
15
+
16
+ ## be
17
+
18
+ This matcher can be followed by many different comparison operators.
19
+ Always make sure to use numbers, not strings, for these comparisons.
20
+
21
+ ```ruby
22
+ describe file('/proc/cpuinfo') do
23
+ its('size') { should be >= 10 }
24
+ its('size') { should be < 1000 }
25
+ end
26
+ ```
27
+
28
+ ## cmp
29
+
30
+ Unlike `eq`, cmp is a matcher for less-restrictive comparisons. It will
31
+ try to fit the actual value to the type you are comparing it to. This is
32
+ meant to relieve the user from having to write type-casts and
33
+ resolutions.
34
+
35
+ ```ruby
36
+ describe sshd_config do
37
+ its('Protocol') { should cmp 2 }
38
+ end
39
+
40
+ describe passwd.uid(0) do
41
+ its('users') { should cmp 'root' }
42
+ end
43
+ ```
44
+
45
+ `cmp` behaves in the following way:
46
+
47
+ * Compare strings to numbers
48
+
49
+ ```ruby
50
+ describe sshd_config do
51
+ its('Protocol') { should eq '2' }
52
+
53
+ its('Protocol') { should cmp '2' }
54
+ its('Protocol') { should cmp 2 }
55
+ end
56
+ ```
57
+
58
+ * String comparisons are not case-sensitive
59
+
60
+ ```ruby
61
+ describe auditd_conf do
62
+ its('log_format') { should cmp 'raw' }
63
+ its('log_format') { should cmp 'RAW' }
64
+ end
65
+ ```
66
+
67
+ * Compare arrays with only one entry to a value
68
+
69
+ ```ruby
70
+ describe passwd.uids(0) do
71
+ its('users') { should cmp 'root' }
72
+ its('users') { should cmp ['root'] }
73
+ end
74
+ ```
75
+
76
+ * Single-value arrays of strings may also be compared to a regex
77
+
78
+ ```ruby
79
+ describe auditd_conf do
80
+ its('log_format') { should cmp /raw/i }
81
+ end
82
+ ```
83
+
84
+ * Improved printing of octal comparisons
85
+
86
+ ```ruby
87
+ describe file('/proc/cpuinfo') do
88
+ its('mode') { should cmp '0345' }
89
+ end
90
+
91
+ expected: 0345
92
+ got: 0444
93
+ ```
94
+
95
+ ## eq
96
+
97
+ Test for exact equality of two values.
98
+
99
+ ```ruby
100
+ describe sshd_config do
101
+ its('RSAAuthentication') { should_not eq 'no' }
102
+ its('Protocol') { should eq '2' }
103
+ end
104
+ ```
105
+
106
+ It fails if types don't match. Please keep this in mind, when comparing
107
+ configuration entries that are numbers:
108
+
109
+ ```ruby
110
+ its('Port') { should eq '22' } # ok
111
+
112
+ its('Port') { should eq 22 }
113
+ # fails: '2' != 2 (string vs int)
114
+ ```
115
+
116
+ For less restrictive comparisons, please use `cmp`.
117
+
118
+ ## include
119
+
120
+ Verifies if a value is included in a list.
121
+
122
+ ```ruby
123
+ describe passwd do
124
+ its('users') { should include 'my_user' }
125
+ end
126
+ ```
127
+
128
+ ## match
129
+
130
+ Check if a string matches a regular expression.
131
+
132
+ ```ruby
133
+ describe sshd_config do
134
+ its('Ciphers') { should_not match /cbc/ }
135
+ end
136
+ ```
@@ -0,0 +1,55 @@
1
+ ---
2
+ title: About kitchen-inspec
3
+ ---
4
+
5
+ # kitchen-inspec
6
+
7
+ The `kitchen-inspec` driver enables InSpec to be used as a verifier within Kitchen.
8
+
9
+ To use InSpec as a verifier, add it to the kitchen.yml file:
10
+
11
+ verifier:
12
+ name: inspec
13
+
14
+ To define a suite that pulls its run-list from the Chef Compliance server:
15
+
16
+ suites:
17
+ - name: compliance
18
+ run_list:
19
+ - recipe[ssh-hardening]
20
+ verifier:
21
+ inspec_tests:
22
+ - compliance://base/ssh
23
+
24
+ and then run the following command:
25
+
26
+ $ inspec compliance login https://compliance.test --user admin --insecure --token ''
27
+
28
+ where `--insecure` is required when using self-signed certificates.
29
+
30
+ To define a suite that pulls its run-list from the Chef Supermarket:
31
+
32
+ suites:
33
+ - name: supermarket
34
+ run_list:
35
+ - recipe[ssh-hardening]
36
+ verifier:
37
+ inspec_tests:
38
+ - supermarket://hardening/ssh-hardening
39
+
40
+ The `kitchen-inspec` driver expects tests to be located in the `test/integration` directory in a cookbook. For example::
41
+
42
+ .
43
+ ├── Berksfile
44
+ ├── Gemfile
45
+ ├── README.md
46
+ ├── metadata.rb
47
+ ├── recipes
48
+ │ ├── default.rb
49
+ │ └── nginx.rb
50
+ └── test
51
+ └── integration
52
+ └── default
53
+ ├── controls
54
+ ├── inspec.yml
55
+ └── libraries
data/docs/profiles.md ADDED
@@ -0,0 +1,271 @@
1
+ ---
2
+ title: About InSpec Profiles
3
+ ---
4
+
5
+ # InSpec Profiles
6
+
7
+ InSpec supports the creation of complex test and compliance profiles, which organize controls to support dependency management and code reuse. Each profile is a standalone structure with its own distribution and execution flow.
8
+
9
+ # Profile Structure
10
+
11
+ A profile should have the following structure::
12
+
13
+ examples/profile
14
+ ├── README.md
15
+ ├── controls
16
+ │ ├── example.rb
17
+ │ └── control_etc.rb
18
+ ├── libraries
19
+ │ └── extension.rb
20
+ └── inspec.yml
21
+
22
+ where:
23
+
24
+ * `inspec.yml` includes the profile description (required)
25
+ * `controls` is the directory in which all tests are located (required)
26
+ * `libraries` is the directory in which all InSpec resource extensions are located (optional)
27
+ * `README.md` should be used to explain the profile, its scope, and usage
28
+
29
+ See a complete example profile in the InSpec open source repository: https://github.com/chef/inspec/tree/master/examples/profile
30
+
31
+ ## inspec.yml
32
+
33
+ Each profile must have an `inspec.yml` file that defines the following information:
34
+
35
+ * Use `name` to specify a unique name for the profile. Required.
36
+ * Use `title` to specify a human-readable name for the profile.
37
+ * Use `maintainer` to specify the profile maintainer.
38
+ * Use `copyright` to specify the copyright holder.
39
+ * Use `copyright_email` to specify support contact information for the profile, typically an email address.
40
+ * Use `license` to specify the license for the profile.
41
+ * Use `summary` to specify a one line summary for the profile.
42
+ * Use `description` to specify a multiple line description of the profile.
43
+ * Use `version` to specify the profile version.
44
+ * Use `supports` to specify a list of supported platform targets.
45
+ * Use `depends` to define a list of profiles on which this profile depends.
46
+
47
+ `name` is required; all other profile settings are optional. For example:
48
+
49
+ name: ssh
50
+ title: Basic SSH
51
+ maintainer: Chef Software, Inc.
52
+ copyright: Chef Software, Inc.
53
+ copyright_email: support@chef.io
54
+ license: Proprietary, All rights reserved
55
+ summary: Verify that SSH Server and SSH Client are configured securely
56
+ version: 1.0.0
57
+ supports:
58
+ - os-family: linux
59
+ depends:
60
+ - name: profile
61
+ path: ../path/to/profile
62
+
63
+ ## Verify Profiles
64
+
65
+ Use the `inspec check` command to verify the implementation of a profile:
66
+
67
+ $ inspec check examples/profile
68
+
69
+ # Platform Support
70
+
71
+ Use the `supports` setting in the `inspec.yml` file to specify one (or more) platforms for which a profile is targeting. The list of supported platforms may contain simple names, names and versions, or detailed flags, and may be combined arbitrarily. For example, to target anything running Debian Linux:
72
+
73
+ name: ssh
74
+ supports:
75
+ - os-name: debian
76
+
77
+ and to target only Ubuntu version 14.04
78
+
79
+ name: ssh
80
+ supports:
81
+ - os-name: ubuntu
82
+ release: 14.04
83
+
84
+ and to target the entire RedHat platform (including CentOS and Oracle Linux):
85
+
86
+ name: ssh
87
+ supports:
88
+ - os-family: redhat
89
+
90
+ and to target anything running on Amazon AWS:
91
+
92
+ name: ssh
93
+ supports:
94
+ - platform: aws
95
+
96
+ and to target all of these examples in a single `inspec.yml` file:
97
+
98
+ name: ssh
99
+ supports:
100
+ - os-name: debian
101
+ supports:
102
+ - os-name: ubuntu
103
+ release: 14.04
104
+ supports:
105
+ - os-family: redhat
106
+ supports:
107
+ - platform: aws
108
+
109
+
110
+ # Profile Dependencies
111
+
112
+ Use the `depends` setting in the `inspec.yml` file to specify one (or more) profiles on which this profile depends. A profile dependency may be sourced from a path, URL, a git repo, a cookbook located on Chef Supermarket or on GitHub, or a profile located on the Chef Compliance server.
113
+
114
+ ## Path
115
+
116
+ The `path` setting defines a profile that is located on disk. This setting is typically used during development of profiles and when debugging profiles. This setting does not support version constraints. If the location of the profile does not exist, an error is returned.
117
+
118
+ For example:
119
+
120
+ depends:
121
+ - name: my-profile
122
+ path: /absolute/path
123
+ - name: another
124
+ path: ../relative/path
125
+
126
+ ## URL
127
+
128
+ The `url` setting specifies a profile that is located at an HTTP- or HTTPS-based URL. The profile must be accessible via a HTTP GET operation and must be a valid profile archive (zip, tar, tar.gz format). If the download fails, the profile is inaccessible, or not in the correct format, an error is returned.
129
+
130
+ For example:
131
+
132
+ depends:
133
+ - name: my-profile
134
+ url: https://my.domain/path/to/profile.tgz
135
+
136
+ ## git
137
+
138
+ A `git` setting specifies a profile that is located in a git repository, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
139
+
140
+ For example:
141
+
142
+ depends:
143
+ - name: git-profile
144
+ git: http://url/to/repo
145
+ branch: desired_branch
146
+ tag: desired_version
147
+ commit: pinned_commit
148
+ version: semver_via_tags
149
+
150
+ ## Chef Supermarket
151
+
152
+ A `supermarket` setting specifies a profile that is located in a cookbook hosted on Chef Supermarket, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
153
+
154
+ For example:
155
+
156
+ depends:
157
+ - name: supermarket-profile
158
+ git: username/profile
159
+ branch: desired_branch
160
+ tag: desired_version
161
+ commit: pinned_commit
162
+ version: semver_via_tags
163
+
164
+ ## GitHub
165
+
166
+ A `github` setting specifies a profile that is located in a repository hosted on GitHub, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
167
+
168
+ For example:
169
+
170
+ depends:
171
+ - name: gh-profile
172
+ git: username/project
173
+ branch: desired_branch
174
+ tag: desired_version
175
+ commit: pinned_commit
176
+ version: semver_via_tags
177
+
178
+ ## Chef Compliance
179
+
180
+ A `compliance` setting specifies a profile that is located on the Chef Compliance server.
181
+
182
+ For example:
183
+
184
+ depends:
185
+ - name: linux
186
+ compliance: base/linux
187
+
188
+
189
+ ## Define in inspec.yml
190
+
191
+ Use the `depends` setting in the `inspec.yml` file to define any combination of profile dependencies. For example:
192
+
193
+ depends:
194
+ - name: ssh-hardening
195
+ supermarket: hardening/ssh-hardening
196
+ - name: os-hardening
197
+ url: https://github.com/dev-sec/tests-os-hardening/archive/master.zip
198
+ - name: ssl-benchmark
199
+ git: https://github.com/dev-sec/ssl-benchmark.git
200
+ - name: windows-patch-benchmark
201
+ git: https://github.com/chris-rock/windows-patch-benchmark.git
202
+ - name: linux
203
+ compliance: base/linux
204
+
205
+ # Profile Inheritance
206
+
207
+ When a profile is run, it may include controls that are defined in other profiles. Controls may also be required.
208
+
209
+ ## include_controls
210
+
211
+ The `include_controls` keyword may be used in a profile to import all rules from the named profile.
212
+
213
+ For example, to include controls from the `cis-level-1` profile when running the `cis-fs-2.7` profile:
214
+
215
+ include_controls 'cis-level-1' do
216
+
217
+ control "cis-fs-2.7" do
218
+ impact 1.0
219
+ ...
220
+
221
+ end
222
+
223
+ To include controls from the `cis-level-1` profile, but skipping two controls within that profile:
224
+
225
+ include_controls 'cis-level-1' do
226
+
227
+ skip_control "cis-fs-2.1"
228
+ skip_control "cis-fs-2.2"
229
+
230
+ end
231
+
232
+ ## require_controls
233
+
234
+ The `require_controls` keyword may be used to load only specific controls from the named profile.
235
+
236
+ For example, to require that controls `cis-fs-2.1` and `cis-fs-2.2` be loaded from the `cis-level-1` profile:
237
+
238
+ require_controls 'cis-level-1' do
239
+
240
+ control "cis-fs-2.1"
241
+ control "cis-fs-2.2"
242
+
243
+ end
244
+
245
+ # Profile Attributes
246
+
247
+ Attributes may be used in profiles to define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. First specify a variable in the control for each secret, then add the secret to a Yaml file located on the local machine, and then run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
248
+
249
+ For example, a control:
250
+
251
+ val_user = attribute('user', default: 'alice', description: 'An identification for the user')
252
+ val_password = attribute('password', description: 'A value for the password')
253
+
254
+ describe val_user do
255
+ it { should eq 'bob' }
256
+ end
257
+
258
+ describe val_password do
259
+ it { should eq 'secret' }
260
+ end
261
+
262
+ And a Yaml file named `profile-attribute.yml`:
263
+
264
+ user: bob
265
+ password: secret
266
+
267
+ The following command runs the tests and applies the secrets specified in `profile-attribute.yml`:
268
+
269
+ $ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
270
+
271
+ See the full example in the InSpec open source repository: https://github.com/chef/inspec/tree/master/examples/profile-attribute