AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  aiml-security-assessment

  SAM Template for aiml-security-assessment

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Assessment Options
        Parameters:
          - TargetRegions
          - MaxRegionConcurrency
    ParameterLabels:
      TargetRegions:
        default: AWS regions to scan
      MaxRegionConcurrency:
        default: Regional scan concurrency

Parameters:
  TargetRegions:
    Type: String
    Default: ""
    AllowedPattern: "^$|^all$|^[a-z]{2}(-gov)?-[a-z]+-[0-9]([,\\s]+[a-z]{2}(-gov)?-[a-z]+-[0-9])*$"
    ConstraintDescription: >
      TargetRegions must be empty, 'all', or a comma- or space-separated list of AWS
      region names (for example, us-east-1,us-west-2,eu-west-1 or
      us-east-1 us-west-2 eu-west-1).
    Description: >
      Comma- or space-separated list of AWS regions to scan (e.g.,
      us-east-1,us-west-2,eu-west-1 or us-east-1 us-west-2 eu-west-1).
      Use 'all' to scan all regions where the service is available.
      Leave empty to scan only the deployment region.
  MaxRegionConcurrency:
    Type: Number
    Default: 5
    MinValue: 1
    MaxValue: 40
    Description: >
      Maximum number of regions scanned in parallel by the Map state. Lower
      values reduce concurrent Lambda usage; higher values speed up large
      multi-region scans. Set to 1 for fully sequential scanning.
    ConstraintDescription: Must be between 1 and 40.

Resources:
  AIMLAssessmentStateMachine:
    Type: AWS::Serverless::StateMachine # More info about State Machine Resource: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html
    Properties:
      DefinitionUri: statemachine/assessments.asl.json
      DefinitionSubstitutions:
        CleanupBucketFunction: !GetAtt CleanupBucketFunction.Arn
        IAMPermissionCachingFunction: !GetAtt IAMPermissionCachingFunction.Arn
        ResolveRegionsFunction: !GetAtt ResolveRegionsFunction.Arn
        BedrockSecurityAssessmentFunction: !GetAtt BedrockSecurityAssessmentFunction.Arn
        SagemakerSecurityAssessmentFunction: !GetAtt SagemakerSecurityAssessmentFunction.Arn
        AgentCoreSecurityAssessmentFunction: !GetAtt AgentCoreSecurityAssessmentFunction.Arn
        FinServSecurityAssessmentFunction: !GetAtt FinServSecurityAssessmentFunction.Arn
        GenerateConsolidatedReportFunction: !GetAtt GenerateConsolidatedReportFunction.Arn
        AIMLAssessmentBucketName: !Ref AIMLAssessmentBucket
        MaxRegionConcurrency: !Ref MaxRegionConcurrency
      Policies:
        - LambdaInvokePolicy:
            FunctionName: !Ref CleanupBucketFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref IAMPermissionCachingFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref ResolveRegionsFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref BedrockSecurityAssessmentFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref SagemakerSecurityAssessmentFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref AgentCoreSecurityAssessmentFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref FinServSecurityAssessmentFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref GenerateConsolidatedReportFunction
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket

  ResolveRegionsFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-ResolveRegions'
      CodeUri: functions/security/resolve_regions/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 60
      MemorySize: 256
      Environment:
        Variables:
          TARGET_REGIONS: !Ref TargetRegions

  CleanupBucketFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-CleanupBucket'
      CodeUri: functions/security/cleanup_bucket/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 300
      MemorySize: 512
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket

  IAMPermissionCachingFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-IAMPermissionCaching'
      CodeUri: functions/security/iam_permission_caching/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 600 # 10 minutes
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
        - Statement:
            - Sid: IAMPermissions
              Effect: Allow
              Action:
                - iam:ListRoles
                - iam:ListUsers
                - iam:ListAttachedRolePolicies
                - iam:ListAttachedUserPolicies
                - iam:ListRolePolicies
                - iam:ListUserPolicies
                - iam:GetRolePolicy
                - iam:GetUserPolicy
                - iam:GetPolicy
                - iam:GetPolicyVersion
                - iam:GenerateServiceLastAccessedDetails
                - iam:GetServiceLastAccessedDetails
                - sts:GetCallerIdentity
              Resource: '*'
  GenerateConsolidatedReportFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-GenerateReport'
      CodeUri: functions/security/generate_consolidated_report/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 600 # 10 minutes
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
          TARGET_REGIONS: !Ref TargetRegions
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
  BedrockSecurityAssessmentFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-BedrockAssessment'
      CodeUri: functions/security/bedrock_assessments/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 600 # 10 minutes
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
          TARGET_REGIONS: !Ref TargetRegions
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
        - Statement:
            - Sid: IAMPermissions
              Effect: Allow
              Action:
                - iam:ListRoles
                - iam:ListUsers
                - iam:ListAttachedRolePolicies
                - iam:ListAttachedUserPolicies
                - iam:ListRolePolicies
                - iam:ListUserPolicies
                - iam:GetRolePolicy
                - iam:GetUserPolicy
                - iam:GetPolicy
                - iam:GetPolicyVersion
                - iam:GenerateServiceLastAccessedDetails
                - iam:GetServiceLastAccessedDetails
                - sts:GetCallerIdentity
              Resource: '*'
            - Sid: BedrockAssessmentPermissions
              Effect: Allow
              Action:
                - bedrock:ListGuardrails
                - bedrock:GetGuardrail
                - bedrock:GetModelInvocationLoggingConfiguration
                - bedrock:ListPrompts
                - bedrock:GetPrompt
                - bedrock:ListAgents
                - bedrock:GetAgent
                - bedrock:ListCustomModels
                - bedrock:GetCustomModel
                - bedrock:GetModelCustomizationJob
                - bedrock:ListFlows
                - bedrock:GetFlow
                - bedrock:ListKnowledgeBases
                - bedrock:GetKnowledgeBase
              Resource: '*'
            - Sid: S3BucketEncryptionPermissions
              Effect: Allow
              Action:
                - s3:GetBucketEncryption
                - s3:GetEncryptionConfiguration
              Resource: 'arn:aws:s3:::*'
            - Sid: CloudTrailPermissions
              Effect: Allow
              Action:
                - cloudtrail:ListTrails
                - cloudtrail:GetTrail
                - cloudtrail:GetEventSelectors
                - cloudtrail:GetTrailStatus
              Resource: '*'
            - Sid: LambdaPermissions
              Effect: Allow
              Action:
                - lambda:ListFunctions
              Resource: '*'
            - Sid: ECSPermissions
              Effect: Allow
              Action:
                - ecs:ListClusters
                - ecs:ListTasks
                - ecs:DescribeTasks
              Resource: '*'
            - Sid: EC2Permissions
              Effect: Allow
              Action:
                - ec2:DescribeVpcEndpoints
                - ec2:DescribeVpcs # Added this permission
              Resource: '*'
  SagemakerSecurityAssessmentFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-SagemakerAssessment'
      CodeUri: functions/security/sagemaker_assessments/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 600 # 10 minutes
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
          TARGET_REGIONS: !Ref TargetRegions
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
        - Statement:
            - Sid: IAMPermissions
              Effect: Allow
              Action:
                - iam:ListRoles
                - iam:ListUsers
                - iam:ListAttachedRolePolicies
                - iam:ListAttachedUserPolicies
                - iam:ListRolePolicies
                - iam:ListUserPolicies
                - iam:GetRolePolicy
                - iam:GetUserPolicy
                - iam:GetPolicy
                - iam:GetPolicyVersion
                - iam:GenerateServiceLastAccessedDetails
                - iam:GetServiceLastAccessedDetails
                - sts:GetCallerIdentity
              Resource: '*'
            - Sid: LambdaPermissions
              Effect: Allow
              Action:
                - lambda:ListFunctions
              Resource: '*'
        - Statement:
            - Sid: SageMakerPermissions
              Effect: Allow
              Action:
                - sagemaker:ListNotebookInstances
                - sagemaker:DescribeNotebookInstance
                - sagemaker:ListDomains
                - sagemaker:DescribeDomain
                - sagemaker:ListTrainingJobs
                - sagemaker:DescribeTrainingJob
                - kms:DescribeKey
                - kms:ListAliases
                - sagemaker:ListModelPackageGroups
                - sagemaker:ListModelPackages
                - sagemaker:DescribeModelPackage
                - sagemaker:ListFeatureGroups
                - sagemaker:DescribeFeatureGroup
                - sagemaker:ListPipelines
                - sagemaker:ListPipelineExecutions
                - sagemaker:ListProcessingJobs
                - sagemaker:DescribeProcessingJob
                - sagemaker:ListMonitoringSchedules
                - sagemaker:DescribeMonitoringSchedule
                - sagemaker:ListModels
                - sagemaker:DescribeModel
                - sagemaker:ListEndpoints
                - sagemaker:DescribeEndpoint
                - sagemaker:ListDataQualityJobDefinitions
                - sagemaker:DescribeDataQualityJobDefinition
                - sagemaker:ListTransformJobs
                - sagemaker:DescribeTransformJob
                - sagemaker:ListHyperParameterTuningJobs
                - sagemaker:DescribeHyperParameterTuningJob
                - sagemaker:ListCompilationJobs
                - sagemaker:DescribeCompilationJob
                - sagemaker:ListAutoMLJobs
                - sagemaker:DescribeAutoMLJob
                - sagemaker:ListExperiments
                - sagemaker:DescribeExperiment
                - sagemaker:ListTrials
                - sagemaker:DescribeTrial
                - sagemaker:ListAssociations
              Resource: '*'
        - Statement:
            - Sid: GuardDutyPermissions
              Effect: Allow
              Action:
                - guardduty:GetFindings
                - guardduty:ListFindings
                - guardduty:ListDetectors
                - guardduty:GetDetector
                - guardduty:GetFindingsStatistics
                - guardduty:ListPublishingDestinations
                - guardduty:ListTagsForResource
                - guardduty:GetMemberDetectors
                - guardduty:DescribeMalwareScans
                - guardduty:GetRemainingFreeTrialDays
                - guardduty:GetUsageStatistics
              Resource: '*'
        - Statement:
            - Sid: EC2Permissions
              Effect: Allow
              Action:
                - ec2:DescribeVpcEndpoints
                - ec2:DescribeVpcs # Added this permission
              Resource: '*'

  AgentCoreSecurityAssessmentFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-AgentCoreAssessment'
      CodeUri: functions/security/agentcore_assessments/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 600 # 10 minutes
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
          TARGET_REGIONS: !Ref TargetRegions
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
        - Statement:
            - Sid: IAMPermissions
              Effect: Allow
              Action:
                - iam:ListRoles
                - iam:ListUsers
                - iam:ListAttachedRolePolicies
                - iam:ListAttachedUserPolicies
                - iam:ListRolePolicies
                - iam:ListUserPolicies
                - iam:GetRolePolicy
                - iam:GetUserPolicy
                - iam:GetPolicy
                - iam:GetPolicyVersion
                - iam:GenerateServiceLastAccessedDetails
                - iam:GetServiceLastAccessedDetails
                - sts:GetCallerIdentity
              Resource: '*'
            - Sid: AgentCorePermissions
              Effect: Allow
              Action:
                - bedrock-agentcore:ListAgentRuntimes
                - bedrock-agentcore:GetAgentRuntime
                - bedrock-agentcore:ListMemories
                - bedrock-agentcore:GetMemory
                - bedrock-agentcore:ListGateways
                - bedrock-agentcore:GetGateway
                - bedrock-agentcore:ListPolicyEngines
                - bedrock-agentcore:GetPolicyEngine
                - bedrock-agentcore:GetResourcePolicy
              Resource: '*'
            - Sid: IAMRolePermissions
              Effect: Allow
              Action:
                - iam:GetRole
              Resource: 'arn:aws:iam::*:role/AWSServiceRoleForBedrockAgentCoreNetwork'
            - Sid: EC2Permissions
              Effect: Allow
              Action:
                - ec2:DescribeSubnets
                - ec2:DescribeRouteTables
                - ec2:DescribeVpcEndpoints
                - ec2:DescribeNatGateways
                - ec2:DescribeVpcs
              Resource: '*'
            - Sid: ECRPermissions
              Effect: Allow
              Action:
                - ecr:DescribeRepositories
                - ecr:GetRepositoryPolicy
              Resource: '*'
            - Sid: LogsPermissions
              Effect: Allow
              Action:
                - logs:DescribeLogGroups
                - logs:DescribeLogStreams
              Resource: '*'
            - Sid: XRayPermissions
              Effect: Allow
              Action:
                - xray:GetTraceSummaries
              Resource: '*'
            - Sid: CloudWatchPermissions
              Effect: Allow
              Action:
                - cloudwatch:ListMetrics
                - cloudwatch:PutMetricData
              Resource: '*'
            - Sid: S3BucketPermissions
              Effect: Allow
              Action:
                - s3:ListBucket
                - s3:GetBucketEncryption
                - s3:GetBucketVersioning
                - s3:GetBucketTagging
                - s3:HeadBucket
              Resource: 'arn:aws:s3:::*'


  FinServSecurityAssessmentFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'aiml-security-${AWS::StackName}-FinServAssessment'
      CodeUri: functions/security/finserv_assessments/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
      Timeout: 900 # 15 minutes (Lambda max) — headroom for large accounts; ASL Catch keeps the report generating if exceeded
      MemorySize: 1024
      Environment:
        Variables:
          AIML_ASSESSMENT_BUCKET_NAME: !Ref AIMLAssessmentBucket
          TARGET_REGIONS: !Ref TargetRegions
      Policies:
        - S3CrudPolicy:
            BucketName: !Ref AIMLAssessmentBucket
        - Statement:
            - Sid: IAMPermissions
              Effect: Allow
              Action:
                - iam:ListRoles
                - iam:ListUsers
                - iam:ListAttachedRolePolicies
                - iam:ListAttachedUserPolicies
                - iam:ListRolePolicies
                - iam:ListUserPolicies
                - iam:GetRolePolicy
                - iam:GetUserPolicy
                - iam:GetPolicy
                - iam:GetPolicyVersion
                - iam:GetRole
                - iam:GetUser
                - sts:GetCallerIdentity
              Resource: '*'
            - Sid: WAFShieldPermissions
              Effect: Allow
              Action:
                - wafv2:ListWebACLs
                - wafv2:GetWebACL
                - shield:DescribeSubscription
              Resource: '*'
            - Sid: APIGatewayPermissions
              Effect: Allow
              Action:
                - apigateway:GET
              Resource: '*'
            - Sid: ServiceQuotasPermissions
              Effect: Allow
              Action:
                - servicequotas:ListServiceQuotas
                - servicequotas:ListAWSDefaultServiceQuotas
              Resource: '*'
            - Sid: CostBudgetPermissions
              Effect: Allow
              Action:
                - ce:GetAnomalyMonitors
                - budgets:ViewBudget
              Resource: '*'
            - Sid: CloudWatchPermissions
              Effect: Allow
              Action:
                - cloudwatch:DescribeAlarms
                - cloudwatch:ListMetrics
              Resource: '*'
            - Sid: LogsPermissions
              Effect: Allow
              Action:
                - logs:DescribeAccountPolicies
                - logs:DescribeLogGroups
              Resource: '*'
            - Sid: BedrockPermissions
              Effect: Allow
              Action:
                - bedrock:ListGuardrails
                - bedrock:GetGuardrail
                - bedrock:ListFoundationModels
                - bedrock:ListCustomModels
                - bedrock:ListEvaluationJobs
                - bedrock:GetModelInvocationLoggingConfiguration
                - bedrock:ListTagsForResource
                - bedrock:ListAutomatedReasoningPolicies
              Resource: '*'
            - Sid: BedrockAgentPermissions
              Effect: Allow
              Action:
                - bedrock:ListAgents
                - bedrock:GetAgent
                - bedrock:ListKnowledgeBases
                - bedrock:GetKnowledgeBase
                - bedrock:ListDataSources
                - bedrock:GetDataSource
              Resource: '*'
            - Sid: BedrockAgentCorePermissions
              Effect: Allow
              Action:
                - bedrock-agentcore:ListAgentRuntimes
                - bedrock-agentcore:GetAgentRuntime
              Resource: '*'
            - Sid: SageMakerPermissions
              Effect: Allow
              Action:
                - sagemaker:ListMonitoringSchedules
                - sagemaker:ListModelPackageGroups
                - sagemaker:ListModelPackages
                - sagemaker:ListFeatureGroups
                - sagemaker:ListModels
                - sagemaker:ListModelCards
                - sagemaker:ListTags
              Resource: '*'
            - Sid: LambdaStatesPermissions
              Effect: Allow
              Action:
                - lambda:ListFunctions
                - lambda:GetFunctionConcurrency
                - states:ListStateMachines
                - states:DescribeStateMachine
              Resource: '*'
            - Sid: OrganizationsPermissions
              Effect: Allow
              Action:
                - organizations:ListPolicies
                - organizations:DescribePolicy
              Resource: '*'
            - Sid: ECRPermissions
              Effect: Allow
              Action:
                - ecr:DescribeRepositories
              Resource: '*'
            - Sid: CloudTrailPermissions
              Effect: Allow
              Action:
                - cloudtrail:ListTrails
                - cloudtrail:GetTrail
                - cloudtrail:GetTrailStatus
                - cloudtrail:GetEventSelectors
              Resource: '*'
            - Sid: OpenSearchServerlessPermissions
              Effect: Allow
              Action:
                - aoss:ListSecurityPolicies
              Resource: '*'
            - Sid: MaciePermissions
              Effect: Allow
              Action:
                - macie2:GetMacieSession
              Resource: '*'
            - Sid: EventsConfigPermissions
              Effect: Allow
              Action:
                - events:ListRules
                - scheduler:ListSchedules
                - config:DescribeConfigRules
              Resource: '*'
            - Sid: S3BucketPermissions
              Effect: Allow
              Action:
                - s3:ListAllMyBuckets
                - s3:ListBucket
                - s3:GetBucketVersioning
                - s3:GetBucketTagging
                - s3:GetBucketEncryption
                - s3:GetBucketNotification
              Resource: 'arn:aws:s3:::*'

  # Add a S3 bucket to store the AIML assessment results
  AIMLAssessmentBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      VersioningConfiguration:
        Status: Enabled
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: aws:kms
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  AssessmentBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref AIMLAssessmentBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: SecureTransport
            Effect: Deny
            Principal: '*'
            Action: s3:*
            Resource:
              - !Sub '${AIMLAssessmentBucket.Arn}/*'
              - !GetAtt AIMLAssessmentBucket.Arn
            Condition:
              Bool:
                aws:SecureTransport: false

Outputs:
  AIMLAssessmentStateMachineArn:
    Description: "AIML Assessment State Machine"
    Value: !Ref AIMLAssessmentStateMachine
  AssessmentBucketName:
    Description: Name of the S3 bucket where assessment reports are stored
    Value: !Ref AIMLAssessmentBucket
