def test_get_policies(self): data = { "settings": { "additional_policies": [{ "action": "s3:GetObject", "resource": "arn:aws:s3:::mybucketname/*", }] } } role = Role(data, region="us-east-1", account_id="111222333") actual = role.get_policies() expected = [{ "PolicyName": "inline_policy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Action": "s3:GetObject", "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucketname/*"], }], }, }] self.assertEqual(actual, expected)
def test_update_statements_cf(self): statements = [{ "Effect": "Allow", "Action": "kms:Decrypt", "Resource": "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/my-key", }] role = Role({}, region="us-east-1", account_id="111222333", partition="aws") actual = role._update_statements(statements, cf_sub_func=True) expected = [{ "Effect": "Allow", "Action": "kms:Decrypt", "Resource": [{ "Fn::Sub": "arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/my-key" }], }] self.assertEqual(actual, expected)
def test_analyze_policies(self): data = { "settings": { "principal_service": ["ec2", "ec2", "lambda"], "policies": ["default_role_policy"], "additional_policies": [{ "action": "s3:GetObject", "resource": "arn:aws:s3:::mybucketname" }], } } role = Role(data) actual = [] for analyzed_policy in role.analyze_policies(): for finding in analyzed_policy.findings: actual.append(str(finding)) expected = [ "RESOURCE_MISMATCH" " - [{'action': 's3:GetObject', 'required_format': 'arn:*:s3:::*/*'}]" " - {'actions': ['s3:GetObject'], 'filepath': None}" ] self.assertEqual(actual, expected)
def test_valid_managed_policy(self): data = { "settings": { "managed_policy_arns": ["AmazonEKSWorkerNodePolicy"] } } role = Role(data) actual = role.analyze_policies() expected = [] self.assertEqual(actual, expected)
def test_invalid_managed_policy(self): data = {"settings": {"managed_policy_arns": ["AdministratorAccess"]}} role = Role(data) actual = [str(finding) for finding in role.analyze_policies()] expected = [ "DENIED_POLICIES" " - Managed policies are not approved for use" " - {'managed_policy_arns': ['AdministratorAccess']}" ] self.assertEqual(actual, expected)
def lambda_handler(event, context=None): LOGGER.debug(f"event: {event}") if not event: LOGGER.error("No event found in request") return {"result": "UNSUPPORTED"} role_type = event.get("type") if role_type != "iam": return {"result": "UNSUPPORTED"} stack_name = event.get("stack_name") account_id = event.get("account_id") region = event.get("region") roles = validate_yaml(event.get("roles")) if not roles: return {"result": "NON_COMPLIANT"} all_findings = [] for role_dict in roles: role = Role(role_dict, region, account_id) analyzed_polices = role.analyze_policies() role_findings = [] for analyzed_policy in analyzed_polices: role_findings.extend(analyzed_policy.findings) if not role_findings: findings = simulate_policies(account_id, analyzed_polices) role_findings.extend(findings) all_findings.extend(role_findings) if all_findings: for finding in all_findings: LOGGER.error(str(finding)) return {"result": "NON_COMPLIANT"} output = { "result": "COMPLIANT", "roles": roles, "account_id": account_id, "region": region, "stack_name": stack_name, } return output
def test_update_statements_cf(self): statements = [{ "Effect": "Allow", "Action": "kms:Decrypt", "Resource": "arn:aws:kms:us-east-1:111222333:key/my-key", }] role = Role({}) actual = role._update_statements(statements, is_cf=True) expected = [{ "Effect": "Allow", "Action": "kms:Decrypt", "Resource": ["arn:aws:kms:us-east-1:111222333:key/my-key"], }] self.assertEqual(actual, expected)
def test_principal_service_none(self): data = {"settings": {}} role = Role(data) actual = role.principal_service expected = [] self.assertEqual(actual, expected)
def test_principal_service_single(self): data = {"settings": {"principal_service": "ec2"}} role = Role(data) actual = role.principal_service expected = ["ec2"] self.assertEqual(actual, expected)
def test_principal_service_multiple(self): data = {"settings": {"principal_service": ["ec2", "lambda"]}} role = Role(data) actual = role.principal_service expected = ["ec2", "lambda"] self.assertEqual(actual, expected)
def create_template_body(roles: list) -> str: """ Create the IAM role CloudFormation template """ template_body = { "AWSTemplateFormatVersion": "2010-09-09", "Description": "IAM roles created by the Role Creation Service", } resources = {} for role_dict in roles: role = Role(role_dict) resource = role.to_cf_json() resources = {**resources, **resource} template_body["Resources"] = resources params = {"indent": None, "sort_keys": True, "separators": (",", ":")} return json.dumps(template_body, **params)
def test_get_default_policies(self): data = {"settings": {"principal_service": "lambda"}} role = Role(data, region="us-east-1", account_id="111222333") actual = role.get_default_policies() expected = [{ "PolicyName": "default_lambda_policy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "ENI", "Effect": "Allow", "Action": [ "ec2:CreateNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DeleteNetworkInterface", ], "Resource": ["*"], }, { "Sid": "CloudWatchLogGroup", "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": ["*"], }, { "Sid": "CloudWatchLogStream", "Effect": "Allow", "Action": ["logs:CreateLogStream", "logs:PutLogEvents"], "Resource": [ "arn:aws:logs:us-east-1:111222333:log-group:/aws/lambda/*" ], }, { "Sid": "XRay", "Effect": "Allow", "Action": [ "xray:PutTraceSegments", "xray:PutTelemetryRecords", "xray:GetSamplingRules", "xray:GetSamplingTargets", "xray:GetSamplingStatisticSummaries", ], "Resource": ["*"], }, { "Sid": "KMS", "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey", ], "Resource": ["arn:aws:kms:us-east-1:111222333:key/AccountKey"], }, ], }, }] self.assertEqual(actual, expected)