AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > ETH2 Validator BLS Key Generator Globals: Function: Timeout: 120 Parameters: SigningProfileVersionArnParameter: Type: String Description: Lambda Code Signing Profile ARN Default: "" Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.200.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: "secure-keygen-vpc" Metadata: cfn_nag: rules_to_suppress: - id: W60 reason: "Only Lambda is deployed on this VPC. No need for flow log" PrivateSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [ 1, !GetAZs '' ] CidrBlock: 10.200.0.0/24 MapPublicIpOnLaunch: false PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PrivateSubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnet LambdaSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Validator Lambda Security Group VpcId: !Ref VPC SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 Description: Allow to all destinations Metadata: cfn_nag: rules_to_suppress: - id: W5 reason: "Lambda function need to interact with other AWS services" EndpointSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: VPC Endpoint Security Group VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !GetAtt VPC.CidrBlock Description: Allow from VPC SecurityGroupEgress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: !GetAtt VPC.CidrBlock Description: Allow to VPC KMSEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub 'com.amazonaws.${AWS::Region}.kms' PrivateDnsEnabled: true VpcId: !Ref VPC SubnetIds: - !Ref PrivateSubnet SecurityGroupIds: - !Ref EndpointSecurityGroup S3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: '*' Action: - 's3:*' Resource: - '*' RouteTableIds: - !Ref PrivateRouteTable ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcId: !Ref VPC DynamoDBEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: '*' Action: - 'dynamodb:BatchWriteItem' - 'dynamodb:DeleteItem' - 'dynamodb:DescribeTable' - 'dynamodb:PutItem' - 'dynamodb:UpdateItem' Resource: - '*' RouteTableIds: - !Ref PrivateRouteTable ServiceName: !Sub 'com.amazonaws.${AWS::Region}.dynamodb' VpcId: !Ref VPC ValidatorKeyGenFunction: Type: AWS::Serverless::Function Properties: PackageType: Zip CodeUri: secure_keygen/ Handler: app.lambda_handler Runtime: python3.9 MemorySize: 1024 CodeSigningConfigArn: !Ref SignedFunctionCodeSigningConfig ReservedConcurrentExecutions: 1 VpcConfig: SecurityGroupIds: - !Ref LambdaSecurityGroup SubnetIds: - !Ref PrivateSubnet Environment: Variables: KMS_KEY_ARN: Fn::GetAtt: - Key - Arn DDB_TABLE_NAME: Ref: ValidatorKeysTable LOG_LEVEL: "DEBUG" Architectures: - x86_64 Policies: - Version: "2012-10-17" Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Effect: Allow Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*' - Action: - kms:Encrypt - kms:GenerateDataKey* - kms:ReEncrypt* Effect: Allow Resource: Fn::GetAtt: - Key - Arn - Action: - dynamodb:BatchWriteItem - dynamodb:DeleteItem - dynamodb:DescribeTable - dynamodb:PutItem - dynamodb:UpdateItem Effect: Allow Resource: - Fn::GetAtt: - ValidatorKeysTable - Arn Metadata: cfn_nag: rules_to_suppress: - id: W89 reason: "False positive - https://github.com/stelligent/cfn_nag/issues/601" # CodeSigningConfig drift detection not supported: # https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/954 SignedFunctionCodeSigningConfig: Type: AWS::Lambda::CodeSigningConfig Properties: Description: "Code Signing for ValidatorKeyGenFunction" AllowedPublishers: SigningProfileVersionArns: - !Ref SigningProfileVersionArnParameter CodeSigningPolicies: UntrustedArtifactOnDeployment: "Enforce" ValidatorKeysTable: Type: AWS::DynamoDB::Table Properties: KeySchema: - AttributeName: web3signer_uuid KeyType: HASH - AttributeName: pubkey KeyType: RANGE AttributeDefinitions: - AttributeName: web3signer_uuid AttributeType: S - AttributeName: pubkey AttributeType: S PointInTimeRecoverySpecification: PointInTimeRecoveryEnabled: true ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 5 SSESpecification: SSEEnabled: true BillingMode: PROVISIONED UpdateReplacePolicy: Delete DeletionPolicy: Delete Key: Type: AWS::KMS::Key Properties: KeyPolicy: Statement: - Action: - "kms:Create*" - "kms:Describe*" - "kms:Enable*" - "kms:Encrypt" - "kms:List*" - "kms:Put*" - "kms:Update*" - "kms:Revoke*" - "kms:Disable*" - "kms:Get*" - "kms:Delete*" - "kms:ScheduleKeyDeletion" - "kms:CancelKeyDeletion" - "kms:GenerateDataKey*" - "kms:TagResource" - "kms:UntagResource" # - "kms:Decrypt" # Uncomment to debug Effect: Allow Principal: AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root' Resource: "*" Version: "2012-10-17" EnableKeyRotation: true UpdateReplacePolicy: Delete DeletionPolicy: Delete Outputs: ValidatorKeyGenFunction: Description: "Lambda Function ARN" Value: !GetAtt ValidatorKeyGenFunction.Arn ValidatorKeyGenFunctionIamRole: Description: "Implicit IAM Role created for function" Value: !GetAtt ValidatorKeyGenFunctionRole.Arn ValidatorKeysTable: Description: "DynamoDB Table Arn" Value: !GetAtt ValidatorKeysTable.Arn Key: Description: "KMS Key" Value: !GetAtt Key.Arn