AWSTemplateFormatVersion: 2010-09-09 Description: Create required infrastructure for SCP alternative solution in Security Account. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Global Variables Parameters: - Prefix - Label: default: Mandatory Variables Parameters: - OrganizationAccessRoleName - ManagementAccountAccessRoleName - ManagementAccountID - Label: default: Optional Variables Parameters: - Email - WhitelistRoleName Conditions: DisableEmailSub: !Equals [!Ref Email,''] ExistsWhitelistRoleName: !Not [!Equals [!Ref WhitelistRoleName,'']] Parameters: Prefix: Type: String Description: Enter the prefix for the instructure created in this stack. Default: scp-alt Email: Type: String Description: Enter the Email Address to subscribe the failures for the lambda execution. OrganizationAccessRoleName: Type: String Description: > Enter the AWS Organization Access Role Name used to assume to member accounts. The role name needs to be matched with the value in 010 cloudformation template. Default: OrganizationAccountAccessRole WhitelistRoleName: Type: String Description: > The IAM role name list which won't attach the IAM permission boundary policy for SCP. `OrganizationAccessRoleName` is in the list by default. Seperated by comma. Default: '' ManagementAccountAccessRoleName: Type: String Default: scp-cross-account-access-role-for-lambda Description: > Enter IAM role name for cross-account access for Lambda in Security Account. The role name needs to be matched with the value in 010 cloudformation template. ManagementAccountID: Type: String Description: The management Account ID of the organization. AllowedPattern: (\d{12}|^$) ConstraintDescription: Must be a valid AWS account ID. Resources: # system metadata to parameter store SSMManagementAccountID: Type: AWS::SSM::Parameter Properties: Name: /scp/management-account-id Type: String Value: !Ref ManagementAccountID Description: The Management Account ID of the organization. Tags: Owner: !Sub '${AWS::StackName}' Application: SCP S3BucketName: Type: AWS::SSM::Parameter Properties: Name: /scp/cloudformation-s3-bucket-name Type: String Value: !ImportValue CloudFormationBucketName Description: The S3 bucket name for CloudFormation templates Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPPermissionBoundaryName: Type: AWS::SSM::Parameter Properties: Name: /scp/permission-boundary-name Type: String Value: scp-enforce-policy Description: The SCP permission boundary policy name Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPOrganizationAccessRole: Type: AWS::SSM::Parameter Properties: Name: /scp/organization-access-role-name Type: String Value: !Ref OrganizationAccessRoleName Description: The AWS Organization Access Role name Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPWhitelistRoleName: Type: AWS::SSM::Parameter Properties: Name: /scp/whitelist-role-name-list Type: String Value: !If - ExistsWhitelistRoleName - !Ref WhitelistRoleName - "None" Description: The IAM Whitelist Role name. Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPReadPolicyStatementID: Type: AWS::SSM::Parameter Properties: Name: /scp/read-policy-statement-id Type: String Value: AllowReadFromMemberAccounts Description: The statement ID in event bus resource policy Tags: Owner: !Sub '${AWS::StackName}' Application: SCP DynamodbArn: Type: AWS::SSM::Parameter Properties: Name: /scp/dynamodb-arn Type: String Value: !GetAtt ScpTable.Arn Description: The Dynamodb Table Arn for SCP in security account Tags: Owner: !Sub '${AWS::StackName}' Application: SCP sScpAccountRegisterRoleArn: Type: AWS::SSM::Parameter Properties: Name: /scp/scp-account-register-role-arn Type: String Value: !GetAtt ScpAccountRegisterRole.Arn Description: The IAM role arn for SCP Account Register Lambda. Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SNSTopicArn: Type: AWS::SSM::Parameter Properties: Name: /scp/sns-topic-arn Type: String Value: !Ref SNSTopic Description: The SNS Topic for SCP in security account Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPEventBusArn: Type: AWS::SSM::Parameter Properties: Name: /scp/event-bus-arn Type: String Value: !GetAtt SCPIamEventDispatcherEventBridge.Arn Description: The Event Bridge for SCP in security account Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPEventRuleArn: Type: AWS::SSM::Parameter Properties: Name: /scp/event-rule-arn Type: String Value: !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/${SCPIamEventDispatcherEventBridge}/scp-alt-event-rule Description: The Event rule for SCP in security account Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPManagementAccountAccessRoleName: Type: AWS::SSM::Parameter Properties: Name: /scp/management-account-access-role Type: String Value: !Ref ManagementAccountAccessRoleName Description: The Management Account Access role for Security Account. Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPS3PermissionBoundary: Type: AWS::SSM::Parameter Properties: Name: /scp/permission-boundary-s3-bucket-name Type: String Value: !Ref ScpS3Bucket Description: The SCP bucket for permission boundary Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SCPS3ObjectFolder: Type: AWS::SSM::Parameter Properties: Name: /scp/s3-object-folder Type: String Value: permission-boundary-policy Description: The S3 Object Folder Tags: Owner: !Sub '${AWS::StackName}' Application: SCP SqsKmsKey: Type: AWS::KMS::Key Properties: EnableKeyRotation: true KeyPolicy: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root Action: "kms:*" Resource: "*" - Effect: Allow Principal: Service: - s3.amazonaws.com - events.amazonaws.com Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt* - kms:GenerateDataKey* - kms:DescribeKey Resource: "*" SnsKmsKey: Type: AWS::KMS::Key Properties: EnableKeyRotation: true KeyPolicy: Version: "2012-10-17" Statement: - Effect: Allow Principal: AWS: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root Action: "kms:*" Resource: "*" - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt* - kms:GenerateDataKey* - kms:DescribeKey Resource: "*" # s3 -> sqs -> lambda ScpS3Bucket: DependsOn: SCPS3EventDispatcherSQSQueuePolicy Type: 'AWS::S3::Bucket' Properties: BucketName: !Sub '${Prefix}-policy-${AWS::AccountId}' PublicAccessBlockConfiguration: BlockPublicAcls: yes BlockPublicPolicy: yes IgnorePublicAcls: yes RestrictPublicBuckets: yes VersioningConfiguration: Status: Enabled BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 NotificationConfiguration: QueueConfigurations: - Event: "s3:ObjectCreated:*" Queue: !GetAtt SCPS3EventDispatcherSQS.Arn Filter: S3Key: Rules: - Value: !Sub - "${BucketFolder}/" - BucketFolder: !GetAtt SCPS3ObjectFolder.Value Name: prefix - Value: .json Name: suffix ScpS3BucketPOL: Type: 'AWS::S3::BucketPolicy' Properties: Bucket: !Ref ScpS3Bucket PolicyDocument: Id: CrossAccessPolicy Version: "2012-10-17" Statement: - Sid: AllowReadFromUseCasesAccounts Action: - "s3:Get*" - "s3:List*" Effect: Allow Resource: - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}' - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}/*' Principal: AWS: - !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root' SCPS3EventDispatcherSQS: Type: "AWS::SQS::Queue" Properties: QueueName: !Sub '${Prefix}-policy-create' # Must be greater than the lambda execution timeout VisibilityTimeout: 900 MessageRetentionPeriod: 7200 # https://docs.aws.amazon.com/lambda/latest/operatorguide/sqs-retries.html RedrivePolicy: deadLetterTargetArn: !Sub ${SCPS3EventDispatcherDLQueue.Arn} maxReceiveCount: 1 KmsMasterKeyId: !Ref SqsKmsKey SCPS3EventDispatcherDLQueue: Type: AWS::SQS::Queue Properties: QueueName: !Sub '${Prefix}-policy-create-DLQ' KmsMasterKeyId: !Ref SqsKmsKey SCPS3EventDispatcherSQSQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: "s3.amazonaws.com" Action: - SQS:SendMessage Resource: !GetAtt SCPS3EventDispatcherSQS.Arn Condition: ArnLike: # Static BucketName used to avoid circular dependency with S3 bucket aws:SourceArn: !Sub 'arn:${AWS::Partition}:s3:::${Prefix}-policy-${AWS::AccountId}' Queues: - !Ref SCPS3EventDispatcherSQS # Lambda scp-s3-event-dispatcher SCPS3EventDispatcherLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: scp-s3-event-dispatcher-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: allowLambdaLogs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:* Resource: !Sub 'arn:${AWS::Partition}:logs:*:*:*' - PolicyName: allowSqs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sqs:ReceiveMessage - sqs:GetQueueAttributes - sqs:DeleteMessage Resource: !GetAtt SCPS3EventDispatcherSQS.Arn - PolicyName: allowDynamodb PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:GetItem - dynamodb:PutItem - dynamodb:UpdateItem - dynamodb:Query - dynamodb:Scan Resource: !GetAtt ScpTable.Arn - PolicyName: allowS3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:Get* - s3:List* Resource: - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}' - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}/*' - PolicyName: allowExternalS3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:Get* - s3:List* Resource: - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}/*' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - PolicyName: allowSns PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sns:Publish Resource: !Ref SNSTopic - PolicyName: allowAssumeRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sts:AssumeRole Resource: !Sub 'arn:${AWS::Partition}:iam::${ManagementAccountID}:role/${ManagementAccountAccessRoleName}' - PolicyName: allowDecryptKMS PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - "kms:Decrypt" - "kms:Encrypt" - "kms:GenerateDataKey" Resource: "*" SCPS3EventDispatcherLambda: Type: 'AWS::Lambda::Function' Properties: Handler: "scp-s3-event-dispatcher.main" Runtime: "python3.7" Role: !GetAtt SCPS3EventDispatcherLambdaExecutionRole.Arn Timeout: 900 TracingConfig: Mode: "Active" Code: S3Bucket: !ImportValue CloudFormationBucketName S3Key: "scp-s3-event-dispatcher.zip" Environment: Variables: "DYNAMODB_TABLE_ARN": !GetAtt ScpTable.Arn "SNS_TOPIC_ARN": !Ref SNSTopic "ORGANIZATION_ROLE": !Ref OrganizationAccessRoleName "WHITELIST_ROLE_NAME": !GetAtt SCPWhitelistRoleName.Value "PERMISSION_BOUNDARY_NAME": !GetAtt SCPPermissionBoundaryName.Value "MANAGEMENT_ACCOUNT_ID": !Ref ManagementAccountID "MANAGEMENT_ACCOUNT_ACCESS_ROLE": !Ref ManagementAccountAccessRoleName SCPS3EventDispatcherLambdaFunctionEventSourceMapping: Type: AWS::Lambda::EventSourceMapping Properties: BatchSize: 10 Enabled: true EventSourceArn: !GetAtt SCPS3EventDispatcherSQS.Arn FunctionName: !GetAtt SCPS3EventDispatcherLambda.Arn # Event Bus -> Event rule -> SQS -> Lambda SCPIamEventDispatcherEventBridge: Type: AWS::Events::EventBus Properties: Name: !Sub '${Prefix}-event-bus' # The event pattern for the policy will be updated accordingly once the account is registered. # To avoid the potential drifts, the lambda function is used instead to manage # the event rule. rSCPEventRuleLambdaCustomResource: Type: Custom::CreateEventRule Properties: ServiceToken: !GetAtt SCPIamEventRuleLambda.Arn EventBusArn: !GetAtt SCPEventBusArn.Value SqsArn: !GetAtt SCPIamEventDispatcherSQS.Arn SCPIamEventRuleLambda: Type: 'AWS::Lambda::Function' Properties: Code: ZipFile: !Sub | # Import statements import os import boto3 import cfnresponse import json from botocore.exceptions import ClientError def lambda_handler(event, context): print(event) props = event['ResourceProperties'] scp_event_rule_arn = os.environ["SCP_EVENT_RULE_ARN"] scp_event_bus_arn = props["EventBusArn"] scp_sqs_arn = props["SqsArn"] EVENT_PATTERN = { "detail-type": ["AWS API Call via CloudTrail"], "source": ["aws.iam"] } scp_event_rule_name = scp_event_rule_arn.split("/")[-1] scp_event_bus_name = scp_event_bus_arn.split("/")[-1] events_client = boto3.client('events') if (event['RequestType'] == 'Create'): try: events_client.put_rule( Name=scp_event_rule_name, EventPattern=json.dumps(EVENT_PATTERN), State='ENABLED', Description=f'Event rule for SCP Alternative Solution to capture IAM events from member accounts', EventBusName=scp_event_bus_name ) events_client.put_targets( Rule=scp_event_rule_name, EventBusName=scp_event_bus_name, Targets=[ { 'Id': scp_event_rule_name, 'Arn': scp_sqs_arn }, ] ) except ClientError as ex: print(ex.response['Error']['Message']) cfnresponse.send(event, context, cfnresponse.FAILED, ex.response) sys.exit(1) if(event['RequestType'] == 'Update'): print("Update event, skiping...") elif(event['RequestType'] == 'Delete'): try: events_client.remove_targets( Rule=scp_event_rule_name, EventBusName=scp_event_bus_name, Ids=[scp_event_rule_name], Force=True ) events_client.delete_rule( Name=scp_event_rule_name, EventBusName=scp_event_bus_name, Force=True ) except ClientError as ex: print(ex.response['Error']['Message']) cfnresponse.send(event, context, cfnresponse.FAILED, ex.response) sys.exit(1) cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) Handler: 'index.lambda_handler' MemorySize: 128 Role: !GetAtt 'rSCPIamEventRuleLambdaRole.Arn' Runtime: 'python3.7' Timeout: 60 Environment: Variables: "SCP_EVENT_RULE_ARN": !GetAtt SCPEventRuleArn.Value rSCPIamEventRuleLambdaRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: 'lambda.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' ManagedPolicyArns: - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' Policies: - PolicyName: allowPutRule PolicyDocument: Statement: - Effect: Allow Action: - events:PutRule - events:PutTargets - events:RemoveTargets - events:DeleteRule Resource: !GetAtt SCPEventRuleArn.Value # Lambda scp-iam-event-dispatcher SCPIamEventDispatcherLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: scp-iam-event-dispatcher-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: allowLambdaLogs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:* Resource: !Sub 'arn:${AWS::Partition}:logs:*:*:*' - PolicyName: allowSqs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sqs:ReceiveMessage - sqs:GetQueueAttributes - sqs:DeleteMessage Resource: !GetAtt SCPIamEventDispatcherSQS.Arn - PolicyName: allowDynamodb PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:GetItem - dynamodb:PutItem - dynamodb:UpdateItem - dynamodb:Query - dynamodb:Scan Resource: !GetAtt ScpTable.Arn - PolicyName: allowS3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:Get* - s3:List* Resource: - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}' - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}/*' - PolicyName: allowExternalS3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:Get* - s3:List* Resource: - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}/*' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - PolicyName: allowSns PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sns:Publish Resource: !Ref SNSTopic - PolicyName: allowAssumeRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sts:AssumeRole Resource: !Sub 'arn:${AWS::Partition}:iam::${ManagementAccountID}:role/${ManagementAccountAccessRoleName}' - PolicyName: allowDecryptKMS PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - "kms:Decrypt" - "kms:Encrypt" - "kms:GenerateDataKey" Resource: "*" SCPIamEventDispatcherLambda: Type: 'AWS::Lambda::Function' Properties: Handler: "scp-iam-event-dispatcher.main" Runtime: "python3.7" Role: !GetAtt SCPIamEventDispatcherLambdaExecutionRole.Arn Timeout: 600 TracingConfig: Mode: "Active" Code: S3Bucket: !ImportValue CloudFormationBucketName S3Key: "scp-iam-event-dispatcher.zip" Environment: Variables: "DYNAMODB_TABLE_ARN": !GetAtt ScpTable.Arn "SNS_TOPIC_ARN": !Ref SNSTopic "S3_BUCKET_NAME": !Ref ScpS3Bucket "ORGANIZATION_ROLE": !Ref OrganizationAccessRoleName "WHITELIST_ROLE_NAME": !GetAtt SCPWhitelistRoleName.Value "S3_OBJECT_FOLDER": !GetAtt SCPS3ObjectFolder.Value "PERMISSION_BOUNDARY_NAME": !GetAtt SCPPermissionBoundaryName.Value "MANAGEMENT_ACCOUNT_ID": !Ref ManagementAccountID "MANAGEMENT_ACCOUNT_ACCESS_ROLE": !Ref ManagementAccountAccessRoleName SCPIamEventDispatcherLambdaFunctionEventSourceMapping: Type: AWS::Lambda::EventSourceMapping Properties: BatchSize: 10 Enabled: true EventSourceArn: !GetAtt SCPIamEventDispatcherSQS.Arn FunctionName: !GetAtt SCPIamEventDispatcherLambda.Arn SCPIamEventDispatcherSQS: Type: "AWS::SQS::Queue" Properties: QueueName: !Sub '${Prefix}-policy-binding' # Must be greater than the lambda execution timeout VisibilityTimeout: 600 MessageRetentionPeriod: 7200 # https://docs.aws.amazon.com/lambda/latest/operatorguide/sqs-retries.html RedrivePolicy: deadLetterTargetArn: !Sub ${SCPIamEventDispatcherDLQueue.Arn} maxReceiveCount: 1 KmsMasterKeyId: !Ref SqsKmsKey SCPIamEventDispatcherDLQueue: Type: AWS::SQS::Queue Properties: QueueName: !Sub '${Prefix}-policy-binding-DLQ' MessageRetentionPeriod: 43200 KmsMasterKeyId: !Ref SqsKmsKey SCPIamEventDispatcherSQSQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: 'events.amazonaws.com' Action: - "SQS:SendMessage" - "SQS:ReceiveMessage" - "SQS:GetQueueAttributes" Resource: !GetAtt SCPIamEventDispatcherSQS.Arn Condition: ArnEquals: aws:SourceArn: !GetAtt SCPEventRuleArn.Value Queues: - !Ref SCPIamEventDispatcherSQS # DynamoDB table ScpTable: Type: AWS::DynamoDB::Table Properties: BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: AccountId KeyType: HASH AttributeDefinitions: - AttributeName: AccountId AttributeType: S TableName: !Sub '${Prefix}-dynamodb' SSESpecification: SSEEnabled: true SSEType: KMS # SNS topic SNSTopic: Type: AWS::SNS::Topic Properties: TopicName: !Sub '${Prefix}-sns' KmsMasterKeyId: !Ref SnsKmsKey Subscription: !If - DisableEmailSub - [] - - Endpoint: Ref: Email Protocol: email ScpAccountRegisterRole: Type: "AWS::IAM::Role" Properties: RoleName: scp-account-register-role AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: allowLambdaLogs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:* Resource: !Sub 'arn:${AWS::Partition}:logs:*:*:*' - PolicyName: allowDynamodb PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:GetItem - dynamodb:PutItem - dynamodb:UpdateItem - dynamodb:Query - dynamodb:Scan - dynamodb:DeleteItem Resource: !GetAtt ScpTable.Arn - PolicyName: allowS3 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:Get* - s3:List* Resource: - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - !Sub - 'arn:${Partition}:s3:::${ImportBucketName}/*' - Partition: !Ref AWS::Partition ImportBucketName: !ImportValue CloudFormationBucketName - Effect: Allow Action: - s3:Get* - s3:List* - s3:PutBucketPolicy Resource: - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}' - !Sub 'arn:${AWS::Partition}:s3:::${ScpS3Bucket}/*' - PolicyName: allowSns PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sns:Publish Resource: !Ref SNSTopic - PolicyName: eventBus PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - events:DescribeEventBus - events:PutPermission Resource: !GetAtt SCPIamEventDispatcherEventBridge.Arn - PolicyName: eventRule PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - events:DescribeRule - events:PutRule Resource: !GetAtt SCPEventRuleArn.Value - PolicyName: allowAssumeRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sts:AssumeRole Resource: !Sub 'arn:${AWS::Partition}:iam::${ManagementAccountID}:role/${ManagementAccountAccessRoleName}' - PolicyName: allowDecryptKMS PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - "kms:Decrypt" - "kms:Encrypt" - "kms:GenerateDataKey" Resource: "*" Outputs: ScpS3Bucket: Description: The bucket name for SCP polily files. Value: !Ref ScpS3Bucket rWhitelistRoleName: Description: The Whitelist Role name for SCP. Value: !Ref WhitelistRoleName rScpAccountRegisterRoleArn: Description: The IAM role arn for SCP Account Register Lambda. Value: !GetAtt ScpAccountRegisterRole.Arn Export: Name: scp-account-register-role-arn rSCPS3EventDispatcherLambdaExecutionRoleArn: Description: The IAM role arn for SCP S3 Event Dispatcher Lambda. Value: !GetAtt SCPS3EventDispatcherLambdaExecutionRole.Arn Export: Name: scp-s3-event-dispatcher-role-arn rSCPIamEventDispatcherLambdaExecutionRoleArn: Description: The IAM role arn for IAM Event Dispatcher Lambda. Value: !GetAtt SCPIamEventDispatcherLambdaExecutionRole.Arn Export: Name: scp-iam-event-dispatcher-role-arn