AWSTemplateFormatVersion: 2010-09-09
Description: IAM role for deploying Panther

Parameters:
  DeploymentRoleName:
    Type: String
    Description: Name of the deployment IAM role. If an empty string, the name will be autogenerated
    Default: PantherDeploymentRole
  IdentityAccountId:
    Type: String
    Description: The account ID for the account the deployment role will be assumed from
    Default: ''
  OpsAccountId:
    Type: String
    Description: The second account ID for the account the deployment role will be assumed from.  Used with new deployment tooling
    Default: ''
  InternalDeploy:
    Type: String
    Description: Is set to true when built locally through mage. Used to make the policy names regional.
    Default: 'false'

Conditions:
  IdentityAccountSpecified: !Not [!Equals [!Ref IdentityAccountId, '']]
  OpsAccountSpecified: !Not [!Equals [!Ref OpsAccountId, '']]
  RoleNameSpecified: !Not [!Equals [!Ref DeploymentRoleName, '']]
  InternalDeploySpecified: !Equals [!Ref InternalDeploy, 'true']

Resources:
  DeploymentRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !If [RoleNameSpecified, !Ref DeploymentRoleName, !Ref AWS::NoValue]
      Description: IAM role for deploying Panther
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS: !If
                - IdentityAccountSpecified
                - !Sub arn:${AWS::Partition}:iam::${IdentityAccountId}:root
                - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root
            Action: sts:AssumeRole
            Condition:
              Bool:
                aws:SecureTransport: true
          - !If
            - OpsAccountSpecified
            - Effect: Allow
              Principal:
                AWS: !Sub arn:${AWS::Partition}:iam::${OpsAccountId}:role/PulumiCodeBuild
              Action: sts:AssumeRole
              Condition:
                Bool:
                  aws:SecureTransport: true
            - !Ref AWS::NoValue
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              Bool:
                aws:SecureTransport: true
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
      Tags:
        - Key: panther:app
          Value: panther

  DeploymentPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: PantherInfraManagementPolicy
      Roles:
        - !Ref DeploymentRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: AWSRequiredStarCalls
            Effect: Allow
            Action:
              - cloudfront:UpdateDistribution # Required for API Gateway Domain name creation
              - ecs:CreateCluster
              - ecs:DeregisterTaskDefinition
              - kms:CreateKey
              - kms:TagResource
              - logs:CreateLogDelivery
              - logs:DeleteResourcePolicy
              - logs:PutResourcePolicy
              - s3:PutAccountPublicAccessBlock
              - s3:PutPublicAccessBlock
              - servicequotas:RequestServiceQuotaIncrease
              - tag:TagResources
            Resource: '*'
          - Sid: AWSRequiredKMSAuthor
            # This is required until we add PantherDeploymentRole to all kms keys to prevent the error:
            # MalformedPolicyDocumentException: The new key policy will not allow you to update the key policy in the future.
            # https://stackoverflow.com/a/65307337
            Effect: Allow
            Action: kms:*
            Resource: '*'
          - Sid: PantherCloudformation
            Effect: Allow
            Action:
              - cloudformation:CreateChangeSet
              - cloudformation:CreateStack
              - cloudformation:DeleteChangeSet
              - cloudformation:DeleteStack
              - cloudformation:DescribeStacks
              - cloudformation:ExecuteChangeSet
              - cloudformation:ListStackResources
              - cloudformation:UpdateStack
            Resource:
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/panther*
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/onboard-*
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:aws:transform/Serverless*
              # The following permissions are needed when self-onboarding is enabled.
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/onboard-log-processing-role-*
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/onboard-real-time-events-*
              - !Sub arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/onboard-compliance-roles-*
          - Sid: PantherCleanupNetworkInterfaces
            Effect: Allow
            Action:
              - ec2:DeleteNetworkInterface
            Resource: '*'
          - Sid: PantherEC2Create
            Effect: Allow
            Action:
              - ec2:AllocateAddress
              - ec2:CreateFlowLogs
              - ec2:CreateInternetGateway
              - ec2:CreateNatGateway
              - ec2:CreateRouteTable
              - ec2:CreateSecurityGroup
              - ec2:CreateSubnet
              - ec2:CreateTags
              - ec2:CreateVpc
              - ec2:CreateVpcEndpoint
              - ec2:RevokeSecurityGroupIngress
            Resource:
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:elastic-ip/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:internet-gateway/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:natgateway/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:route-table/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:subnet/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc-endpoint/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc-flow-log/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc/*
          - Sid: PantherEC2VPC
            Effect: Allow
            Action:
              - ec2:AssociateRouteTable
              - ec2:AssociateVpcCidrBlock
              - ec2:AttachInternetGateway
              - ec2:AuthorizeSecurityGroupEgress
              - ec2:AuthorizeSecurityGroupIngress
              - ec2:CreateRoute
              - ec2:DeleteFlowLogs
              - ec2:DeleteInternetGateway
              - ec2:DeleteNatGateway
              - ec2:DeleteRoute
              - ec2:DeleteRouteTable
              - ec2:DeleteSecurityGroup
              - ec2:DeleteSubnet
              - ec2:DeleteTags
              - ec2:DeleteVpcEndpoints
              - ec2:DisassociateRouteTable
              - ec2:DisassociateVpcCidrBlock
              - ec2:ModifySubnetAttribute
              - ec2:ModifyVpcAttribute
              - ec2:ModifyVpcEndpoint
              - ec2:ReleaseAddress
              - ec2:RevokeSecurityGroupEgress
            Resource:
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:elastic-ip/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:internet-gateway/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:natgateway/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:route-table/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:subnet/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc-endpoint/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc-flow-log/*
              - !Sub arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:vpc/*
            Condition:
              StringEquals:
                aws:ResourceTag/panther:app: panther
          - Sid: PantherALB
            Effect: Allow
            Action:
              - elasticloadbalancing:AddTags
              - elasticloadbalancing:CreateListener
              - elasticloadbalancing:CreateLoadBalancer
              - elasticloadbalancing:CreateRule
              - elasticloadbalancing:CreateTargetGroup
              - elasticloadbalancing:ModifyLoadBalancerAttributes
              - elasticloadbalancing:ModifyListener
              - elasticloadbalancing:ModifyListenerAttributes
              - elasticloadbalancing:ModifyTargetGroupAttributes
              - elasticloadbalancing:RegisterTargets
              - elasticloadbalancing:RemoveTags
              - elasticloadbalancing:SetWebACL
            Resource:
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:listener-rule/app/web/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:listener/app/http-ingest-alb/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:listener/app/web/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:loadbalancer/app/http-ingest-alb/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:loadbalancer/app/web/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:targetgroup/panther-http-ingest-target-group/*
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:targetgroup/panther-web/*
          - Sid: PantherCodebuild
            Effect: Allow
            Action:
              - codebuild:BatchGetBuilds
              - codebuild:BatchGetProjects
              - codebuild:CreateProject
              - codebuild:DeleteProject
              - codebuild:UpdateProject
              - codebuild:StartBuild
              - codebuild:RetryBuild
            Resource: !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:project/panther*
          - Sid: PantherRedshiftProvisioningServiceLinkedRole
            Effect: Allow
            Action:
              - iam:CreateServiceLinkedRole
            Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/redshift.amazonaws.com/AWSServiceRoleForRedshift
          - Sid: PantherRedshiftProvisioning
            Effect: Allow
            Action:
              - redshift-data:ExecuteStatement # used to set up permissions inside databases
              - redshift-serverless:CreateNamespace
              - redshift-serverless:CreateWorkgroup
              - redshift-serverless:DeleteNamespace
              - redshift-serverless:DeleteWorkgroup
              - redshift-serverless:GetCredentials
              - redshift-serverless:UpdateNamespace
              - redshift-serverless:UpdateWorkgroup
              - redshift-serverless:UntagResource
              - redshift-serverless:TagResource
            Resource:
              - !Sub arn:${AWS::Partition}:redshift-serverless:${AWS::Region}:${AWS::AccountId}:namespace/*
              - !Sub arn:${AWS::Partition}:redshift-serverless:${AWS::Region}:${AWS::AccountId}:workgroup/*
          - Sid: PantherRedshiftProvisioningDescribeStatement
            Effect: Allow
            Action:
              - redshift-data:DescribeStatement # used to set up permissions inside databases
            Resource: '*' # this action requires *
          - Sid: PantherStateMachine
            Effect: Allow
            Action:
              - states:CreateStateMachine
              - states:DeleteStateMachine
              - states:TagResource
              - states:UntagResource
              - states:UpdateStateMachine
            Resource: !Sub arn:${AWS::Partition}:states:${AWS::Region}:${AWS::AccountId}:stateMachine:panther*
          - Sid: PantherEvents
            Effect: Allow
            Action:
              - events:DeleteRule
              - events:PutRule
              - events:PutTargets
              - events:RemoveTargets
              - events:TagResource
              - events:UntagResource
            Resource:
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/ai-api-*-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/alert-search-rehydrate-api-rehydration-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/analysis-api-*-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/analysis-api-git-polling-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/analysis-api-schedule-polling-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/compliance-aggregator-refresh-all-delete-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/compliance-aggregator-refresh-all-no-delete-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/detection-processor-poll-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/enrichment-api-prune-generations-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/enrichment-api-sync-all-profile-pullers-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/experimental-detection-processor-poll-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/holding-tank-field-discovery-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/lambda-warmer-prewarm-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/onboard-real-time-events*
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/ops-tools-*-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/panther*
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/pulumi-api-cleanup-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/replay-api-schedule-cleanup-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/source-api-refresh-sources-health-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/system-status-monitor-ingestion-threshold-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/system-status-publish-sources-last-received-event-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/system-status-publish-sources-permission-status-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/system-status-refresh-log-type-metrics-cron
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/users-api-deactivate-support-users-cron
              # This is required when self-onboarding is enabled.
              - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/onboard-real-time-events-*
          - Sid: PantherAPIGateway
            Effect: Allow
            Action:
              - apigateway:DELETE
              - apigateway:PATCH
              - apigateway:POST
              - apigateway:PUT
              - apigateway:SetWebACL
              - apigateway:TagResource
              - apigateway:UntagResource
            Resource:
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/account
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/apis*
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/domainnames*
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/restapis*
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/tags/*
              - !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}::/usageplans*
            Condition:
              StringLikeIfExists:
                apigateway:Request/apiName: panther*

  DeploymentPolicy2:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName:
        !If [
          InternalDeploySpecified,
          !Sub 'PantherInfraManagementPolicy2-${AWS::Region}',
          PantherInfraManagementPolicy2,
        ]
      Roles:
        - !Ref DeploymentRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: PantherS3
            Effect: Allow
            Action:
              - s3:CreateBucket
              - s3:DeleteBucketPolicy
              - s3:PutBucketAcl
              - s3:PutBucketCors
              - s3:PutBucketLogging
              - s3:PutBucketNotification
              - s3:PutBucketOwnershipControls
              - s3:PutBucketPolicy
              - s3:PutBucketPublicAccessBlock
              - s3:PutBucketTagging
              - s3:PutBucketVersioning
              - s3:PutEncryptionConfiguration
              - s3:PutInventoryConfiguration
              - s3:PutLifecycleConfiguration
              - s3:PutMetricsConfiguration
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::analysis-bulk-uploads-*
              - !Sub arn:${AWS::Partition}:s3:::analysis-versions-*
              - !Sub arn:${AWS::Partition}:s3:::audit-logs-*
              - !Sub arn:${AWS::Partition}:s3:::dashboards-*
              - !Sub arn:${AWS::Partition}:s3:::data-archive-*
              - !Sub arn:${AWS::Partition}:s3:::datadog-aws-metric-stream-backup-*
              - !Sub arn:${AWS::Partition}:s3:::datalake-*
              - !Sub arn:${AWS::Partition}:s3:::input-data-*
              - !Sub arn:${AWS::Partition}:s3:::panther-*
              - !Sub arn:${AWS::Partition}:s3:::panther-audit-logs-*
              - !Sub arn:${AWS::Partition}:s3:::processed-data-*
              - !Sub arn:${AWS::Partition}:s3:::pulumi-state-*
              - !Sub arn:${AWS::Partition}:s3:::replay-data-*
              - !Sub arn:${AWS::Partition}:s3:::readiness-*
              - !Sub arn:${AWS::Partition}:s3:::temporary-processed-data-*
              - !Sub arn:${AWS::Partition}:s3:::unmonitored-audit-logs-*
              - !Sub arn:${AWS::Partition}:s3:::user-uploads-*
          - Sid: PantherS3PulumiStateBucketRemoverTemp
            # Allow deletion of the pulumi-state bucket. This can be removed after 1.115
            Effect: Allow
            Action:
              - s3:DeleteBucket
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::pulumi-state-*
          - Sid: PantherS3DevDeployment # Allow the deployment role to push build artifacts for the dev environment
            Effect: Allow
            Action:
              - s3:PutObject
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::panther-dev-sourcebucket-*
              - !Sub arn:${AWS::Partition}:s3:::panther-dev-backupbucket-*
          - Sid: PantherS3DevBackupCleanup # Allow the deployment role to clean up old backup objects
            Effect: Allow
            Action:
              - s3:DeleteObject
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::panther-dev-backupbucket-*
              - !Sub arn:${AWS::Partition}:s3:::panther-dev-backupbucket-*/*
          - Sid: PantherS3Deployment # Allow the deployment role to get build artifacts
            Effect: Allow
            Action:
              - s3:GetObject
            Resource:
              - !Sub arn:${AWS::Partition}:s3:::panther-enterprise*
              - !Sub arn:${AWS::Partition}:s3:::panther-internal-test*
          - Sid: PantherFirehose
            Effect: Allow
            Action:
              - firehose:CreateDeliveryStream
              - firehose:UpdateDestination
              - firehose:DeleteDeliveryStream
              - firehose:StartDeliveryStreamEncryption
              - firehose:TagDeliveryStream
              - firehose:UntagDeliveryStream
              - firehose:UpdateDestination
            Resource:
              - !Sub arn:aws:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/panther-*
              - !Sub arn:aws:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/http-ingest-*
          - Sid: PantherLambda
            Effect: Allow
            Action:
              - lambda:AddPermission
              - lambda:CreateFunction
              - lambda:DeleteFunction
              - lambda:DeleteFunctionConcurrency
              - lambda:DeleteFunctionEventInvokeConfig
              - lambda:DeleteLayerVersion
              - lambda:InvokeFunction
              - lambda:PublishLayerVersion
              - lambda:PutFunctionConcurrency
              - lambda:PutFunctionEventInvokeConfig
              - lambda:PutFunctionRecursionConfig
              - lambda:RemovePermission
              - lambda:TagResource
              - lambda:UntagResource
              - lambda:UpdateFunctionCode
              - lambda:UpdateFunctionConfiguration
            Resource:
              - !Sub arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:datadog-*
              - !Sub arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:panther*
              - !Sub arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:layer:panther*
          - Sid: PantherLambdaSourceMapping
            Effect: Allow
            Action:
              - lambda:CreateEventSourceMapping
              - lambda:DeleteEventSourceMapping
              - lambda:UpdateEventSourceMapping
            Resource: '*'
            Condition:
              StringLike:
                lambda:FunctionArn: !Sub arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:panther*
          - Sid: PantherSNS
            Effect: Allow
            Action:
              - sns:CreateTopic
              - sns:DeleteTopic
              - sns:SetTopicAttributes
              - sns:Subscribe
              - sns:TagResource
              - sns:Unsubscribe
              - sns:UntagResource
            Resource: !Sub arn:${AWS::Partition}:sns:${AWS::Region}:${AWS::AccountId}:panther*
          - Sid: PantherSQS
            Effect: Allow
            Action:
              - sqs:CreateQueue
              - sqs:DeleteQueue
              - sqs:SetQueueAttributes
              - sqs:TagQueue
              - sqs:UntagQueue
            Resource: !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:panther*
          - Sid: PantherDynamoDB
            Effect: Allow
            Action:
              - dynamodb:CreateTable
              - dynamodb:DeleteTable
              - dynamodb:UpdateTable
              # TODO: Remove this once we have successfully deleted Material.CaseCreated schema
              - dynamodb:DeleteItem
              - dynamodb:TagResource
              - dynamodb:UntagResource
              - dynamodb:Update*
            Resource: !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/panther*
          - Sid: PantherECR
            Effect: Allow
            Action:
              - ecr:BatchCheckLayerAvailability
              - ecr:CompleteLayerUpload
              - ecr:InitiateLayerUpload
              - ecr:PutImage
              - ecr:SetRepositoryPolicy
              - ecr:UploadLayerPart
              - ecr:BatchGetImage
            Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/panther*
          - Sid: PantherECRAdditional
            Effect: Allow
            Action:
              - ecr:GetAuthorizationToken
            Resource: '*'
          - Sid: PantherAssumeRoute53
            Effect: Allow
            Action: sts:AssumeRole
            Resource: arn:aws:iam::*:role/PulumiRoute53

  DeploymentPolicy3:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName:
        !If [
          InternalDeploySpecified,
          !Sub 'PantherInfraManagementPolicy3-${AWS::Region}',
          PantherInfraManagementPolicy3,
        ]
      Roles:
        - !Ref DeploymentRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: Bedrock
            Effect: Allow
            Action:
              - bedrock:GetUseCaseForModelAccess
              - bedrock:PutUseCaseForModelAccess
            Resource: '*'
          - Sid: PantherKMS
            Effect: Allow
            Action:
              - kms:CreateGrant
              - kms:Decrypt
              - kms:EnableKeyRotation
              - kms:Encrypt
              - kms:GenerateDataKey
              - kms:GenerateDataKeyWithoutPlaintext
              - kms:UpdateAlias
            Resource: !Sub arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/panther*
          - Sid: DevPulumiOktaSupport
            Effect: Allow
            Action: kms:Decrypt
            Resource: arn:aws:kms:us-west-2:246537256134:key/bc6a94a9-56a1-41b7-83aa-fddeb4df255e
          - Sid: PulumiOktaSecret
            Effect: Allow
            Action: secretsmanager:GetSecretValue
            Resource: arn:aws:secretsmanager:us-west-2:246537256134:secret:pulumi/okta-epd-login-app-management-token-05Mnkv
          - Sid: PantherManageSecrets
            Effect: Allow
            Action:
              - secretsmanager:CancelRotateSecret
              - secretsmanager:CreateSecret
              - secretsmanager:DeleteSecret
              - secretsmanager:GetSecretValue
              - secretsmanager:PutSecretValue
              - secretsmanager:RotateSecret
              - secretsmanager:TagResource
              - secretsmanager:UpdateSecret
            Resource: !Sub arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:panther*
          - Sid: PantherLogs
            Effect: Allow
            Action:
              - logs:AssociateKmsKey
              - logs:CreateLogGroup
              - logs:DeleteLogGroup
              - logs:PutRetentionPolicy
              - logs:PutSubscriptionFilter
              - logs:DeleteSubscriptionFilter
              - logs:TagLogGroup
              - logs:TagResource
              - logs:UntagResource
              - logs:UntagLogGroup
            Resource:
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/apigateway/welcome*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/batch/job*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/cloudtrail/*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/panther*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/gateway/panther*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda-insights*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/datadog-log-forwarder*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/panther*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/vpc*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:aws-waf-logs-*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:panther-*
              - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:alert-open-search*
          - Sid: PantherLogsResourcePolicy
            Effect: Allow
            Action:
              - logs:PutResourcePolicy
              - logs:DeleteResourcePolicy
              - logs:DescribeResourcePolicies
            Resource: '*'
          - Sid: PantherCognito
            Effect: Allow
            Action:
              - cognito-idp:CreateUserPool
              - cognito-idp:TagResource
            Resource: !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/*
          - Sid: PantherCognitoManagement
            Effect: Allow
            Action:
              - cognito-idp:CreateIdentityProvider
              - cognito-idp:CreateUserPoolClient
              - cognito-idp:CreateUserPoolDomain
              - cognito-idp:DeleteIdentityProvider
              - cognito-idp:SetUserPoolMfaConfig
              - cognito-idp:UntagResource
              - cognito-idp:UpdateIdentityProvider
              - cognito-idp:UpdateUserPool
              - cognito-idp:UpdateUserPoolClient
            Resource: !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/*
            Condition:
              StringEquals:
                aws:ResourceTag/panther:app: panther
          - Sid: PantherEFSCreate
            Effect: Allow
            Action:
              - elasticfilesystem:CreateFileSystem
              - elasticfilesystem:TagResource
            Resource: !Sub arn:${AWS::Partition}:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/*
          - Sid: PantherEFSManage
            Effect: Allow
            Action:
              - elasticfilesystem:CreateAccessPoint
              - elasticfilesystem:CreateMountTarget
              - elasticfilesystem:DeleteAccessPoint
              - elasticfilesystem:DeleteFileSystem
              - elasticfilesystem:DeleteMountTarget
              - elasticfilesystem:PutLifecycleConfiguration
              - elasticfilesystem:TagResource
              - elasticfilesystem:UntagResource
            Resource:
              - !Sub arn:${AWS::Partition}:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/*
              - !Sub arn:${AWS::Partition}:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:access-point/*
          - Sid: PantherBatch
            Effect: Allow
            Action:
              - batch:CreateComputeEnvironment
              - batch:CreateJobQueue
              - batch:DeleteComputeEnvironment
              - batch:DeleteJobQueue
              - batch:DeregisterJobDefinition
              - batch:RegisterJobDefinition
              - batch:TagResource
              - batch:UntagResource
              - batch:UpdateComputeEnvironment
              - batch:UpdateJobQueue
            Resource:
              - !Sub arn:${AWS::Partition}:batch:${AWS::Region}:${AWS::AccountId}:compute-environment/panther*
              - !Sub arn:${AWS::Partition}:batch:${AWS::Region}:${AWS::AccountId}:job-definition/panther*
              - !Sub arn:${AWS::Partition}:batch:${AWS::Region}:${AWS::AccountId}:job-queue/panther*
          - Sid: PantherECSManage
            Effect: Allow
            Action:
              - ecs:CreateService
              - ecs:DeleteCluster
              - ecs:DeleteService
              - ecs:RegisterTaskDefinition
              - ecs:TagResource
              - ecs:UntagResource
              - ecs:UpdateCluster
              - ecs:UpdateClusterSettings
              - ecs:UpdateService
            Resource:
              - !Sub arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:cluster/panther*
              - !Sub arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:service/panther-*
              - !Sub arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:task-definition/panther-*
          - Sid: PantherCWDashboard
            Effect: Allow
            Action: cloudwatch:PutDashboard
            Resource: !Sub arn:${AWS::Partition}:cloudwatch::${AWS::AccountId}:dashboard/Panther*
          - Sid: PantherUpdateSnowPipeCluster
            Effect: Allow
            Action:
              - iam:UpdateAssumeRolePolicy
            Resource:
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/panther-snowflake-logprocessing-role-${AWS::Region}

  DeploymentPolicy4:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName:
        !If [
          InternalDeploySpecified,
          !Sub 'PantherInfraManagementDenies-${AWS::Region}',
          PantherInfraManagementDenies,
        ]
      Roles:
        - !Ref DeploymentRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          # Do not delete sensitive resources, like DynamoDB tables and KMS aliases
          - Effect: Deny
            Action: elasticloadbalancing:DeleteLoadBalancer
            NotResource:
              - !Sub arn:${AWS::Partition}:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:loadbalancer/app/http-ingest-alb*
          - Effect: Deny
            Action: dynamodb:DeleteTable
            NotResource:
              - !Sub arn:${AWS::Partition}:dynamodb:*:${AWS::AccountId}:table/panther*
          - Effect: Deny
            Action: s3:DeleteBucket
            NotResource: # Allow deletion of the pulumi-state bucket. This 'notresource' can be removed after 1.115
              - !Sub arn:${AWS::Partition}:s3:::pulumi-state-*
          - Effect: Deny
            Action:
              - cognito-idp:DeleteUserPool*
              - dynamodb:DeleteBackup
              - dynamodb:DeleteTableReplica
            Resource: '*'
          - Sid: PantherIAM
            Effect: Allow
            Action:
              - iam:AttachRolePolicy
              - iam:CreatePolicy
              - iam:CreatePolicyVersion
              - iam:CreateRole
              - iam:CreateServiceLinkedRole
              - iam:DeletePolicy
              - iam:DeletePolicyVersion
              - iam:DeleteRole
              - iam:DeleteRolePolicy
              - iam:DetachRolePolicy
              - iam:DeleteServerCertificate
              - iam:PassRole
              - iam:PutRolePolicy
              - iam:TagPolicy
              - iam:TagRole
              - iam:TagServerCertificate
              - iam:UpdateRole*
              - iam:UpdateAssumeRolePolicy
              - iam:UploadServerCertificate
              - iam:UntagRole
              - iam:UntagPolicy
            Resource:
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:instance-profile/Panther*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/analytics-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/data-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/datadog-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/deny-data-access-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/dynamo-scaling-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/firehose-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/panther*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/Panther*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/read-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/support-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/write-to-firehose-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/batch.amazonaws.com/AWSServiceRoleForBatch
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/cloudtrail.amazonaws.com/AWSServiceRoleForCloudTrail
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/elasticfilesystem.amazonaws.com/AWSServiceRoleForAmazonElasticFileSystem
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/opensearchservice.amazonaws.com/AWSServiceRoleForAmazonOpenSearchService
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/ops.apigateway.amazonaws.com/AWSServiceRoleForAPIGateway
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/servicequotas.amazonaws.com/AWSServiceRoleForServiceQuotas
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/Datadog*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/datadog*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/dynamo-scaling-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/firehose-http-input-data-bucket-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/panther*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/Panther*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/pip-layer-builder-codebuild-*
              - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:server-certificate/panther/*
          - Sid: DomainCertificate
            Effect: Allow
            Action:
              - acm:RequestCertificate
              - acm:AddTagsToCertificate
              - acm:RemoveTagsFromCertificate
            Resource:
              - !Sub arn:${AWS::Partition}:acm:*:${AWS::AccountId}:certificate/*
          - Sid: PantherOpenSearch
            Effect: Allow
            Action:
              - es:AddTags
              - es:CreateDomain
              - es:DeleteDomain
              - es:DescribeDomain
              - es:RemoveTags
              - es:UpdateDomainConfig
              - es:UpgradeDomain
            Resource:
              - !Sub arn:${AWS::Partition}:es:${AWS::Region}:${AWS::AccountId}:domain/panther-*

  DeploymentPolicy5:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName:
        !If [
          InternalDeploySpecified,
          !Sub 'PantherInfraManagementPolicy5-${AWS::Region}',
          PantherInfraManagementPolicy5,
        ]
      Roles:
        - !Ref DeploymentRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: PantherCloudTrail
            Effect: Allow
            Action:
              - cloudtrail:CreateTrail
              - cloudtrail:DeleteTrail
              - cloudtrail:UpdateTrail
              - cloudtrail:StartLogging
              - cloudtrail:StopLogging
              - cloudtrail:PutEventSelectors
              - cloudtrail:AddTags
              - cloudtrail:RemoveTags
            Resource: !Sub arn:${AWS::Partition}:cloudtrail:${AWS::Region}:${AWS::AccountId}:trail/panther*
          - Sid: PantherBackup
            Effect: Allow
            Action:
              - backup:CreateBackupVault
              - backup:DeleteBackupVault
              - backup:PutBackupVaultAccessPolicy
              - backup:DeleteBackupVaultAccessPolicy
              - backup:PutBackupVaultNotifications
              - backup:CreateBackupPlan
              - backup:DeleteBackupPlan
              - backup:UpdateBackupPlan
              - backup:GetBackupPlan
              - backup:ListBackupPlans
              - backup:CreateBackupSelection
              - backup:TagResource
              - backup:UntagResource
            Resource:
              - !Sub arn:${AWS::Partition}:backup:${AWS::Region}:${AWS::AccountId}:backup-vault:panther-*
              - !Sub arn:${AWS::Partition}:backup:${AWS::Region}:${AWS::AccountId}:backup-plan:*
          - Sid: PantherBackupStorage
            Effect: Allow
            Action:
              - backup-storage:MountCapsule
            Resource: '*'
          - Sid: PantherWAF
            Effect: Allow
            Action:
              - wafv2:CreateWebACL
              - wafv2:DeleteWebACL
              - wafv2:UpdateWebACL
              - wafv2:GetWebACL
              - wafv2:ListWebACLs
              - wafv2:PutLoggingConfiguration
              - wafv2:TagResource
              - wafv2:UntagResource
              - wafv2:AssociateWebACL
              - wafv2:DisassociateWebACL
            Resource: '*'

Outputs:
  DeploymentRoleArn:
    Value: !GetAtt DeploymentRole.Arn
