turbot/steampipe-mod-aws-compliance

Control: KMS CMK policies should prohibit public access

Description

Manage access to resources in the AWS Cloud by ensuring AWS KMS CMK cannot be publicly accessed.

Usage

Run the control in your terminal:

powerpipe control run aws_compliance.control.kms_cmk_policy_prohibit_public_access

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run aws_compliance.control.kms_cmk_policy_prohibit_public_access --share

SQL

This control uses a named query:

with wildcard_action_policies as (
select
arn,
count(*) as statements_num
from
aws_kms_key,
jsonb_array_elements(policy_std -> 'Statement') as s
where
s ->> 'Effect' = 'Allow'
-- kms:CallerAccount
and s -> 'Condition' -> 'StringEquals' -> 'kms:calleraccount' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'kms:calleraccount' is null
and (
s -> 'Condition' -> 'StringLike' -> 'kms:calleraccount' is null
or s -> 'Condition' -> 'StringLike' -> 'kms:calleraccount' ? '*'
)
-- aws:SourceOwner
and s -> 'Condition' -> 'StringEquals' -> 'aws:sourceowner' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:sourceowner' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:sourceowner' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:sourceowner' ? '*'
)
-- aws:SourceAccount
and s -> 'Condition' -> 'StringEquals' -> 'aws:sourceaccount' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:sourceaccount' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:sourceaccount' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:sourceaccount' ? '*'
)
-- aws:PrincipalOrgID
and s -> 'Condition' -> 'StringEquals' -> 'aws:principalorgid' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:principalorgid' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:principalorgid' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:principalorgid' ? '*'
)
-- aws:PrincipalAccount
and s -> 'Condition' -> 'StringEquals' -> 'aws:principalaccount' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:principalaccount' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:principalaccount' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:principalaccount' ? '*'
)
-- aws:PrincipalArn
and s -> 'Condition' -> 'StringEquals' -> 'aws:principalarn' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:principalarn' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:principalarn' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:principalarn' ? '*'
)
and (
s -> 'Condition' -> 'ArnEquals' -> 'aws:principalarn' is null
or s -> 'Condition' -> 'ArnEquals' -> 'aws:principalarn' ? '*'
)
and (
s -> 'Condition' -> 'ArnLike' -> 'aws:principalarn' is null
or s -> 'Condition' -> 'ArnLike' -> 'aws:principalarn' ? '*'
)
-- aws:SourceArn
and s -> 'Condition' -> 'StringEquals' -> 'aws:sourcearn' is null
and s -> 'Condition' -> 'StringEqualsIgnoreCase' -> 'aws:sourcearn' is null
and (
s -> 'Condition' -> 'StringLike' -> 'aws:sourcearn' is null
or s -> 'Condition' -> 'StringLike' -> 'aws:sourcearn' ? '*'
)
and (
s -> 'Condition' -> 'ArnEquals' -> 'aws:sourcearn' is null
or s -> 'Condition' -> 'ArnEquals' -> 'aws:sourcearn' ? '*'
)
and (
s -> 'Condition' -> 'ArnLike' -> 'aws:sourcearn' is null
or s -> 'Condition' -> 'ArnLike' -> 'aws:sourcearn' ? '*'
)
and (
s -> 'Principal' -> 'AWS' = '["*"]'
or s ->> 'Principal' = '*'
)
group by
arn
)
select
k.arn as resource,
case
when p.arn is null then 'ok'
else 'alarm'
end status,
case
when p.arn is null then title || ' does not allow public access.'
else title || ' contains ' || coalesce(p.statements_num, 0) ||
' statements that allow public access.'
end as reason
, k.region, k.account_id
from
aws_kms_key as k
left join wildcard_action_policies as p on p.arn = k.arn
where
key_manager = 'CUSTOMER';

Tags