---
title: About the shadow Resource
platform: linux
---
# shadow
Use the `shadow` InSpec audit resource to test the contents of `/etc/shadow`, which contains password details that are only readable by the `root` user. The format for `/etc/shadow` includes:
* A username
* The password for that user (on newer systems passwords should be stored in `/etc/shadow` )
* The last time a password was changed
* The minimum number of days a password must exist, before it may be changed
* The maximum number of days after which a password must be changed
* The number of days a user is warned about an expiring password
* The number of days a user must be inactive before the user account is disabled
* The number of days a user account has been disabled
These entries are defined as a colon-delimited row in the file, one row per user:
dannos:Gb7crrO5CDF.:10063:0:99999:7:::
## Syntax
A `shadow` resource block declares one (or more) users and associated user information to be tested:
describe shadow do
its('users') { should_not include 'forbidden_user' }
end
or with a single query:
describe shadow.users('root') do
its('count') { should eq 1 }
end
or with a filter:
describe shadow.filter(min_days: '0', max_days: '99999') do
its('count') { should eq 1 }
end
The following properties are available:
* `users`
* `passwords`
* `last_changes`
* `min_days`
* `max_days`
* `warn_days`
* `inactive_days`
* `expiry_date`
* `reserved`
Properties can be used as a single query or can be joined together with the `.filter` method.
## Examples
The following examples show how to use this InSpec audit resource.
### Test for a forbidden user
describe shadow do
its('users') { should_not include 'forbidden_user' }
end
### Test that a user appears one time
describe shadow.users('bin') do
its('passwords') { should cmp 'x' }
its('count') { should eq 1 }
end
## Matchers
For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).
### count
The `count` matcher tests the number of times the named user appears in `/etc/shadow`:
its('count') { should eq 1 }
This matcher is best used in conjunction with filters. For example:
describe shadow.users('dannos') do
its('count') { should eq 1 }
end
### expiry_dates
The `expiry_dates` matcher tests the number of days a user account has been disabled:
its('expiry_dates') { should eq '' }
### inactive_days
The `inactive_days` matcher tests the number of days a user must be inactive before the user account is disabled:
its('inactive_days') { should eq '' }
### last_changes
The `last_changes` matcher tests the last time a password was changed:
its('last_changes') { should eq '' }
### max_days
The `max_days` matcher tests the maximum number of days after which a password must be changed:
its('max_days') { should eq 90 }
### min_days
The `min_days` matcher tests the minimum number of days a password must exist, before it may be changed:
its('min_days') { should eq 0 }
### passwords
The `passwords` matcher returns the encrypted password string from the shadow file. The returned string may not be an encrypted password, but rather a `*` or similar which indicates that direct logins are not allowed.
For example:
its('passwords') { should cmp '*' }
### users
The `users` matcher tests if the user name exists `/etc/shadow`:
its('users') { should eq 'root' }
### warn_days
The `warn_days` matcher tests the number of days a user is warned about an expiring password:
its('warn_days') { should eq 7 }