inspec/lib/resources/aws/aws_iam_root_user.rb
Paul Welch 27203110cd Add AWS hardware MFA matcher (#2892)
* Add AWS hardware MFA matcher
Adding a hardware as well as a virtual MFA matcher for aws_iam_root_user
resource

* Add New AWS Root Matcher Docs
- Add documentation for new root MFA matchers
- Fix logic for checking MFA devices from feedback on PR

* Add Integration tests for MFA matchers
- Add integration tests for virtual and hardware MFA matchers
- Clean up logic for has_virtual_mfa_enabled? method

Signed-off-by: Paul Welch <pwelch@chef.io>
2018-04-03 09:13:52 -04:00

78 lines
2.5 KiB
Ruby

class AwsIamRootUser < Inspec.resource(1)
name 'aws_iam_root_user'
desc 'Verifies settings for AWS root account'
example "
describe aws_iam_root_user do
it { should have_access_key }
end
"
supports platform: 'aws'
# TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
def initialize(conn = nil)
@client = conn ? conn.iam_client : inspec_runner.backend.aws_client(Aws::IAM::Client)
end
# TODO: DRY up, see https://github.com/chef/inspec/issues/2633
# Copied from resource_support/aws/aws_resource_mixin.rb
def catch_aws_errors
yield
rescue Aws::Errors::MissingCredentialsError
# The AWS error here is unhelpful:
# "unable to sign request without credentials set"
Inspec::Log.error "It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://www.inspec.io/docs/reference/platforms for details."
fail_resource('No AWS credentials available')
rescue Aws::Errors::ServiceError => e
fail_resource e.message
end
# TODO: DRY up, see https://github.com/chef/inspec/issues/2633
# Copied from resource_support/aws/aws_singular_resource_mixin.rb
def inspec_runner
# When running under inspec-cli, we have an 'inspec' method that
# returns the runner. When running under unit tests, we don't
# have that, but we still have to call this to pass something
# (nil is OK) to the backend.
# TODO: remove with https://github.com/chef/inspec-aws/issues/216
# TODO: remove after rewrite to include AwsSingularResource
inspec if respond_to?(:inspec)
end
def has_access_key?
summary_account['AccountAccessKeysPresent'] == 1
end
def has_mfa_enabled?
summary_account['AccountMFAEnabled'] == 1
end
# if the root account has a Virtual MFA device then it will have a special
# serial number ending in 'root-account-mfa-device'
def has_virtual_mfa_enabled?
mfa_device_pattern = %r{arn:aws:iam::\d{12}:mfa\/root-account-mfa-device}
virtual_mfa_devices.any? { |d| mfa_device_pattern =~ d['serial_number'] }
end
def has_hardware_mfa_enabled?
has_mfa_enabled? && !has_virtual_mfa_enabled?
end
def to_s
'AWS Root-User'
end
private
def summary_account
catch_aws_errors do
@summary_account ||= @client.get_account_summary.summary_map
end
end
def virtual_mfa_devices
catch_aws_errors do
@__virtual_devices ||= @client.list_virtual_mfa_devices.virtual_mfa_devices
end
end
end