def policy_document_not_principal(): return PolicyDocument( **{ "Statement": [ { "Action": [ "iam:Delete*", "s3:GetObject*", ], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": { "AWS": ["156460612806"] }, }, { "Action": [ "s3:List*", ], "Effect": "Deny", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": { "AWS": ["156460612806"] }, }, ] })
def test_multi_statements(): pd = { "doc": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ec2.amazonaws.com"], "AWS": "arn:aws:iam::324320755747:root" }, "Action": ["sts:AssumeRole"] }, { "Effect": "bar", "Principal": { "Service": ["ec2.amazonaws.com"], "AWS": "arn:aws:iam::324320755747:root" }, "Action": ["sts:AssumeRole"] }] } } document = PolicyDocument(pd["doc"]) statement1 = document.statements[0] assert statement1.effect == "Allow" statement2 = document.statements[1] assert statement2.effect == "bar"
def invoke(self, cfmodel: CFModel, extras: Optional[Dict] = None) -> Result: result = Result() for logical_id, resource in cfmodel.Resources.items(): for policy in resource.policy_documents: self._check_policy_document(result, logical_id, policy.policy_document, policy.name, extras) if isinstance(resource, IAMRole): self._check_policy_document( result, logical_id, resource.Properties.AssumeRolePolicyDocument, None, extras) elif isinstance(resource, KMSKey): self._check_policy_document(result, logical_id, resource.Properties.KeyPolicy, None, extras) elif isinstance(resource, GenericResource): if hasattr(resource, "Properties"): policy_document = resource.Properties.get("PolicyDocument") if policy_document: self._check_policy_document( result, logical_id, PolicyDocument(**policy_document), None, extras) return result
def policy_document_one_statement(): return PolicyDocument( **{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"Service": ["ec2.amazonaws.com"], "AWS": "arn:aws:iam::324320755747:root"}, "Action": ["sts:AssumeRole"], }, } )
def policy_document_wildcard_actions(): return PolicyDocument( **{ "Statement": [{ "Action": ["s3:*"], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket2/*", "Principal": { "AWS": "*" }, }] })
def policy_document_star_resource(): return PolicyDocument( **{ "Statement": [{ "Action": ["*"], "Effect": "Allow", "Resource": "*", "Principal": { "AWS": ["156460612806"] } }] })
def policy_document_not_principal(): return PolicyDocument( **{ "Statement": [{ "Action": ["IAM:Delete*"], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": { "AWS": ["156460612806"] }, }] })
def resource_invoke(self, resource: Resource, logical_id: str, extras: Optional[Dict] = None) -> Result: """ Checks each policy of a given resource. If it's an IAMRole, it will check its AssumeRolePolicyDocument as well. There are some cases where GenericResource contains a property called PolicyDocument that can be a str and therefore, it's not being retrieved in the initial for loop. For those cases, we run another check transforming the str to a PolicyDocument. """ result = Result() for policy in resource.policy_documents: self._check_policy_document(result, logical_id, policy.policy_document, policy.name, extras, resource_type=resource.Type) if isinstance(resource, IAMRole): self._check_policy_document( result, logical_id, resource.Properties.AssumeRolePolicyDocument, None, extras, resource_type=resource.Type, ) elif isinstance(resource, GenericResource): policy_document = getattr(resource.Properties, "PolicyDocument", None) if policy_document: try: formatted_policy_document = ( json.loads(policy_document) if isinstance( policy_document, str) else policy_document) self._check_policy_document( result, logical_id, PolicyDocument(**formatted_policy_document), None, extras, resource_type=resource.Type, ) except Exception: logger.warning( f"Could not process the PolicyDocument {policy_document} on {logical_id}", stack_info=True) return result
def policy_document_condition_with_source_ip(): return PolicyDocument( **{ "Statement": [ { "Action": ["s3:ListBucket"], "Condition": {"IpAddress": {"aws:SourceIp": ["116.202.65.160", "116.202.68.32/27"]}}, "Effect": "Allow", "Principal": {"AWS": "*"}, "Resource": "arn:aws:s3:::fakebucketfakebucket/*", }, ], } )
def policy_document_condition_with_source_vpce(): return PolicyDocument( **{ "Statement": [ { "Action": ["s3:ListBucket"], "Condition": {"IpAddress": {"aws:SourceVpce": ["vpce-123456"]}}, "Effect": "Allow", "Principal": {"AWS": "*"}, "Resource": "arn:aws:s3:::fakebucketfakebucket/*", }, ], } )
def test_not_principla(): pd = { "PolicyDocument": { "Statement": [{ "Action": ["*"], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": { "AWS": ["156460612806"] } }] } } document = PolicyDocument(pd["PolicyDocument"]) assert len(document.allows_not_principal()) == 1
def test_star_resource(): pd = { "PolicyDocument": { "Statement": [{ "Action": ["*"], "Effect": "Allow", "Resource": "*", "Principal": { "AWS": ["156460612806"] } }] } } document = PolicyDocument(pd["PolicyDocument"]) assert len(document.star_resource_statements()) == 1
def policy_document_not_action(): return PolicyDocument( **{ "Statement": [ { "NotAction": [ "rds:*", ], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": {"AWS": ["156460612806"]}, }, ] } )
def test_can_obtain_policy_documents_from_inherited_method(valid_opensearch_domain_with_access_policies): assert len(valid_opensearch_domain_with_access_policies.policy_documents) == 1 assert valid_opensearch_domain_with_access_policies.policy_documents == [ OptionallyNamedPolicyDocument( policy_document=PolicyDocument( Statement=[ Statement( Effect="Allow", Action="es:*", Resource="arn:aws:es:us-east-1:123456789012:domain/test/*", Principal=Principal(AWS="arn:aws:iam::123456789012:user/opensearch-user"), ) ] ), name=None, ), ]
def test_wildcard_actions(): pd = { "PolicyDocument": { "Statement": [{ "Action": ["s3:*"], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket2/*", "Principal": { "AWS": "*" } }] } } document = PolicyDocument(pd["PolicyDocument"]) assert len(document.wildcard_allowed_actions()) == 1 assert len( document.wildcard_allowed_actions(pattern=r"^(\w*:){0,1}\*$")) == 1
def test_get_iam_actions(): correct_list = [ "IAM:DeleteAccountPasswordPolicy", "IAM:DeleteServiceLinkedRole", "IAM:DeleteRole", "IAM:DeleteOpenIDConnectProvider", "IAM:DeleteGroup", "IAM:DeleteRolePolicy", "IAM:DeleteSSHPublicKey", "IAM:DeleteLoginProfile", "IAM:DeleteServiceSpecificCredential", "IAM:DeleteUserPolicy", "IAM:DeleteVirtualMFADevice", "IAM:DeletePolicyVersion", "IAM:DeleteGroupPolicy", "IAM:DeleteAccountAlias", "IAM:DeleteSigningCertificate", "IAM:DeleteUser", "IAM:DeletePolicy", "IAM:DeleteSAMLProvider", "IAM:DeleteAccessKey", "IAM:DeleteServerCertificate", "IAM:DeleteInstanceProfile", ] pd = { "PolicyDocument": { "Statement": [{ "Action": ["IAM:Delete*"], "Effect": "Allow", "Resource": "arn:aws:s3:::fakebucketfakebucket/*", "NotPrincipal": { "AWS": ["156460612806"] } }] } } document = PolicyDocument(pd["PolicyDocument"]) actions = document.get_iam_actions() assert len(actions) == 21 assert correct_list == actions
def invoke(self, cfmodel: CFModel, extras: Optional[Dict] = None) -> Result: result = Result() for logical_id, resource in cfmodel.Resources.items(): if isinstance(resource, IAMPolicy): self._check_policy_document(result, logical_id, resource.Properties.PolicyDocument, resource.Properties.PolicyName, extras) elif isinstance(resource, (IAMManagedPolicy, S3BucketPolicy, SNSTopicPolicy, SQSQueuePolicy)): self._check_policy_document(result, logical_id, resource.Properties.PolicyDocument, None, extras) elif isinstance(resource, IAMRole): self._check_policy_document( result, logical_id, resource.Properties.AssumeRolePolicyDocument, None, extras) if resource.Properties.Policies: for policy in resource.Properties.Policies: self._check_policy_document(result, logical_id, policy.PolicyDocument, policy.PolicyName, extras) elif isinstance( resource, IAMUser ) and resource.Properties and resource.Properties.Policies: for policy in resource.Properties.Policies: self._check_policy_document(result, logical_id, policy.PolicyDocument, policy.PolicyName, extras) elif isinstance(resource, KMSKey): self._check_policy_document(result, logical_id, resource.Properties.KeyPolicy, None, extras) elif isinstance(resource, GenericResource): if hasattr(resource, "Properties"): policy_document = resource.Properties.get("PolicyDocument") if policy_document: self._check_policy_document( result, logical_id, PolicyDocument(**policy_document), None, extras) return result
"Statement": [{ "Effect": "Allow", "Action": ["service:GetService"], "Resource": "*", }], }, }, } }, }, [ OptionallyNamedPolicyDocument( policy_document=PolicyDocument(Statement=[ Statement( Effect="Allow", Action=["service:GetService"], Resource="*", ) ]), name=None, ) ], 1, ), ( { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Test resolving a nonexistent resource to Resource class", "Resources": { "NonexistentResource": {
def policy_document_kms_key(): return PolicyDocument( **{ "Version": "2012-10-17", "Id": "key-consolepolicy-2", "Statement": [ { "Sid": "Enable IAM policies", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111122223333:root"}, "Action": "kms:*", "Resource": "*", }, { "Sid": "Allow access for Key Administrators", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::111122223333:user/KMSAdminUser", "arn:aws:iam::111122223333:role/KMSAdminRole", ] }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:TagResource", "kms:UntagResource", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion", ], "Resource": "*", }, { "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::111122223333:user/ExampleUser", "arn:aws:iam::111122223333:role/ExampleRole", "arn:aws:iam::444455556666:root", ] }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey", ], "Resource": "*", }, { "Sid": "Allow attachment of persistent resources", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::111122223333:user/ExampleUser", "arn:aws:iam::111122223333:role/ExampleRole", "arn:aws:iam::444455556666:root", ] }, "Action": ["kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant"], "Resource": "*", "Condition": {"Bool": {"kms:GrantIsForAWSResource": True}}, }, ], } )