AWSTemplateFormatVersion: "2010-09-09"
Description: >-
  VirtualSutra AI: the read-only role every member account of an AWS Organization gets, so one
  hub role can discover and scan the whole Organization. Deploy it as a service-managed
  CloudFormation StackSet with automatic deployment on, so accounts added later get it too.
  It holds SecurityAudit and the few reads discovery and scanning need, and nothing that writes.

Parameters:
  HubAccountId:
    Type: String
    Description: The 12-digit id of the account that holds the hub role (the management account, or the delegated administrator).
    AllowedPattern: '^[0-9]{12}$'
    ConstraintDescription: Twelve digits.
  HubRoleName:
    Type: String
    Description: The name of the hub role, exactly as in the connection's Role ARN. Only this role may assume the member role.
    AllowedPattern: '^[A-Za-z0-9+=,.@_-]{1,64}$'
    ConstraintDescription: An IAM role name, without a path.
  ExternalId:
    Type: String
    Description: The ExternalId of the connection. The member role is assumed only with this value.
    MinLength: 2
    MaxLength: 1224
    AllowedPattern: '^[A-Za-z0-9+=,.@:/_-]*$'
    ConstraintDescription: 'Letters, digits and + = , . @ : / _ -'
  RoleName:
    Type: String
    Description: The member role's name. Leave it as it is unless the connection's Member role name says otherwise.
    Default: VirtualSutraReadOnly
    AllowedPattern: '^[A-Za-z0-9+=,.@_-]{1,64}$'
    ConstraintDescription: An IAM role name, without a path. Not an administrator role.

Resources:
  ReadOnlyRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref RoleName
      Description: Read-only access for VirtualSutra AI discovery and scanning, assumed from the hub role.
      MaxSessionDuration: 3600
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            # The hub ROLE, not the hub account's root: no other principal of that account may assume it.
            Principal:
              AWS: !Sub "arn:${AWS::Partition}:iam::${HubAccountId}:role/${HubRoleName}"
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: !Ref ExternalId
      ManagedPolicyArns:
        - !Sub "arn:${AWS::Partition}:iam::aws:policy/SecurityAudit"
      Policies:
        - PolicyName: VirtualSutraDiscoveryAndScan
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Sid: DiscoveryReads
                Effect: Allow
                Action:
                  - ec2:DescribeRegions
                  - eks:ListClusters
                  - eks:DescribeCluster
                  - ecr:DescribeRepositories
                  - ecr:DescribeImages
                Resource: "*"
              - Sid: PullAnImageToScanIt
                Effect: Allow
                Action:
                  - ecr:GetAuthorizationToken
                  - ecr:BatchGetImage
                  - ecr:GetDownloadUrlForLayer
                Resource: "*"

Outputs:
  RoleArn:
    Description: The member role in this account.
    Value: !GetAtt ReadOnlyRole.Arn
