AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  DuoCredentialsSecretArn:
    Type: String
    Description: >-
      ARN of a Secrets Manager secret containing Duo credentials as JSON
      with keys: DUO_API_HOSTNAME, DUO_INTEGRATION_KEY, DUO_SECRET_KEY.
  DuoCredentialsKmsKeyArn:
    Type: String
    Description: >-
      ARN of the customer-managed KMS key used to encrypt the Duo credentials
      secret. Leave empty if using the default AWS-managed key (aws/secretsmanager).
    Default: ''
  S3Bucket:
    Type: String
    Description: S3 bucket containing the Lambda function code and layer zip files.
  LambdaKey:
    Type: String
    Description: S3 object key for the Lambda function code zip.
  LambdaVersion:
    Type: String
    Description: S3 object version ID for the Lambda function code zip. Leave empty if not using versioning.
    Default: ''
  LayerKey:
    Type: String
    Description: S3 object key for the Lambda layer zip.
  LayerVersion:
    Type: String
    Description: S3 object version ID for the Lambda layer zip. Leave empty if not using versioning.
    Default: ''
  LogRetentionInDays:
    Type: Number
    Description: Number of days to retain CloudWatch log events.
    Default: 14
  CreateCloudWatchLogGroup:
    Type: String
    Description: Whether to create the CloudWatch log group and logging policy.
    Default: 'true'
    AllowedValues:
      - 'true'
      - 'false'

Conditions:
  EnableCloudWatchLogging: !Equals [!Ref CreateCloudWatchLogGroup, 'true']
  HasKmsKey: !Not [!Equals [!Ref DuoCredentialsKmsKeyArn, '']]
  HasLambdaVersion: !Not [!Equals [!Ref LambdaVersion, '']]
  HasLayerVersion: !Not [!Equals [!Ref LayerVersion, '']]

Resources:
  DuoClientLayer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      LayerName: DuoClientLayer
      Description: Duo Client layer sourced directly from an S3 bucket
      Content:
        S3Bucket: !Ref S3Bucket
        S3Key: !Ref LayerKey
        S3ObjectVersion: !If [HasLayerVersion, !Ref LayerVersion, !Ref 'AWS::NoValue']
      CompatibleRuntimes:
        - python3.13

  AgentCoreGatewayInterceptorRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AgentCoreGatewayInterceptorLambdaRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: SecretsManagerAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: !Ref DuoCredentialsSecretArn
        - !If
          - HasKmsKey
          - PolicyName: KmsDecrypt
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action:
                    - kms:Decrypt
                  Resource: !Ref DuoCredentialsKmsKeyArn
          - !Ref AWS::NoValue

  AgentCoreGatewayInterceptorLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: DuoAgentCoreGatewayInterceptorLambdaFunction
      Handler: handler.lambda_handler
      Runtime: python3.13
      Role: !GetAtt AgentCoreGatewayInterceptorRole.Arn
      Code:
        S3Bucket: !Ref S3Bucket
        S3Key: !Ref LambdaKey
        S3ObjectVersion: !If [HasLambdaVersion, !Ref LambdaVersion, !Ref 'AWS::NoValue']
      Layers:
        - !Ref DuoClientLayer
      LoggingConfig: !If
        - EnableCloudWatchLogging
        - LogGroup: !Ref AgentCoreGatewayInterceptorLogGroup
          LogFormat: JSON
        - !Ref AWS::NoValue
      Environment:
        Variables:
          DUO_CREDENTIALS_SECRET_ARN: !Ref DuoCredentialsSecretArn

  AgentCoreGatewayInterceptorLogGroup:
    Type: AWS::Logs::LogGroup
    Condition: EnableCloudWatchLogging
    Properties:
      LogGroupName: /aws/lambda/DuoAgentCoreGatewayInterceptorLambdaFunction
      RetentionInDays: !Ref LogRetentionInDays

Outputs:
  LambdaFunctionArn:
    Description: ARN of the Lambda function
    Value: !GetAtt AgentCoreGatewayInterceptorLambdaFunction.Arn
  LambdaRoleArn:
    Description: ARN of the Lambda execution role
    Value: !GetAtt AgentCoreGatewayInterceptorRole.Arn
  LayerVersionArn:
    Description: ARN of the Lambda layer version
    Value: !Ref DuoClientLayer
