Control: API Gateway rest API policies should prohibit public access
Description
Check if API Gateway rest API policies allow public access.
Usage
Run the control in your terminal:
powerpipe control run aws_perimeter.control.api_gateway_rest_api_policy_prohibit_public_accessSnapshot and share results via Turbot Pipes:
powerpipe loginpowerpipe control run aws_perimeter.control.api_gateway_rest_api_policy_prohibit_public_access --shareSteampipe Tables
SQL
    with wildcard_action_policies as (      select        api_id,        count(*) as statements_num      from        aws_api_gateway_rest_api,        jsonb_array_elements(policy_std -> 'Statement') as s      where        s ->> 'Effect' = 'Allow'        -- 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        api_id    )    select      r.api_id as resource,      case        when r.policy is null then 'info'        when p.api_id is null then 'ok'        else 'alarm'      end as status,      case        when r.policy is null then title || ' does not have a defined policy or has insufficient access to the policy.'        when p.api_id is null then title || ' policy does not allow public access.'        else title || ' policy contains ' || coalesce(p.statements_num, 0) ||        ' statement(s) that allow public access.'      end as reason            , region, account_id    from      aws_api_gateway_rest_api as r      left join wildcard_action_policies as p on p.api_id = r.api_id