AWSTemplateFormatVersion: "2010-09-09" Description: This AWS CloudFormation Template creates the necessary resources that a security admin can leverage for appropriate role assignments to specific job functions that are needed for creating and maanging a certificate authority and issuing private certificates using ACM Private CA # This IAM user will be used for all login and development Resources: # We will use admin privileges for now and make it least privilege as we learn CaAdminRole: Type : AWS::IAM::Role Properties: RoleName: 'CaAdminRole' AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: !Sub "${AWS::AccountId}" Action: - "sts:AssumeRole" Policies: - PolicyName: "CaAdminRolePolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Resource: "*" Action: - acm-pca:ImportCertificateAuthorityCertificate - acm-pca:TagCertificateAuthority - acm-pca:ListTags - acm-pca:GetCertificate - acm-pca:UntagCertificateAuthority - acm-pca:GetCertificateAuthorityCsr - acm-pca:GetCertificateAuthorityCertificate - acm-pca:RevokeCertificate - acm-pca:UpdateCertificateAuthority - acm-pca:ListCertificateAuthorities - acm-pca:DescribeCertificateAuthorityAuditReport - acm-pca:CreateCertificateAuthorityAuditReport - acm-pca:RestoreCertificateAuthority - acm-pca:IssueCertificate - acm-pca:CreateCertificateAuthority - acm-pca:DeletePermission - acm-pca:DescribeCertificateAuthority - acm-pca:CreatePermission - acm-pca:ListPermissions - acm-pca:DeleteCertificateAuthority - acm:DescribeCertificate - acm:ListCertificates - acm:AddTagsToCertificate - acm:ListTagsForCertificate - PolicyName: "LambdaSetupPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Resource: "*" Action: - lambda:CreateFunction - lambda:GetFunctionConfiguration - lambda:GetFunction - lambda:InvokeFunction - iam:GetPolicy - iam:GetPolicyVersion - iam:ListRolePolicies - iam:ListAttachedRolePolicies - iam:GetRole - iam:GetRolePolicy - iam:PassRole - iam:SimulatePrincipalPolicy - iam:CreateRole - iam:CreatePolicy - iam:PutRolePolicy - PolicyName: "CleanupPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Resource: "*" Action: - lambda:DeleteFunction - iam:DeleteRole - iam:DeleteRolePolicy ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSCertificateManagerPrivateCAPrivilegedUser - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - arn:aws:iam::aws:policy/IAMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess # We will use admin privileges for now and make it least privilege as we learn AppDevRole: Type : AWS::IAM::Role Properties: RoleName: 'AppDevRole' AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: !Sub "${AWS::AccountId}" Action: - "sts:AssumeRole" Policies: - PolicyName: "AppDevACMPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - acm:ListCertificates - acm:ListTagsForCertificate - acm:DescribeCertificate - acm:RequestCertificate - acm:DeleteCertificate - acm:AddTagsToCertificate - acm-pca:IssueCertificate - acm-pca:ListTags - acm-pca:GetCertificate - acm-pca:GetCertificateAuthorityCertificate - acm-pca:RevokeCertificate - acm-pca:ListCertificateAuthorities - acm-pca:CreatePermission - acm-pca:ListPermissions - acm-pca:GetCertificateAuthorityCsr - acm-pca:DescribeCertificateAuthority Resource: "*" ManagedPolicyArns: - arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess - arn:aws:iam::aws:policy/AWSLambdaFullAccess - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - arn:aws:iam::aws:policy/AmazonEC2FullAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - arn:aws:iam::aws:policy/AWSCloud9User - arn:aws:iam::aws:policy/IAMFullAccess - arn:aws:iam::aws:policy/AmazonSSMFullAccess # We will use admin privileges for now and make it least privilege as we learn IOTDevRole: Type : AWS::IAM::Role Properties: RoleName: 'IOTDevRole' AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: !Sub "${AWS::AccountId}" Action: - "sts:AssumeRole" Policies: - PolicyName: "IOTDevPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - acm:ListCertificates - acm:ListTagsForCertificate - acm:DescribeCertificate - acm:RequestCertificate - acm:DeleteCertificate - acm:AddTagsToCertificate - acm-pca:IssueCertificate - acm-pca:ListTags - acm-pca:GetCertificate - acm-pca:GetCertificateAuthorityCertificate - acm-pca:RevokeCertificate - acm-pca:ListCertificateAuthorities - acm-pca:CreatePermission - acm-pca:ListPermissions - acm-pca:GetCertificateAuthorityCsr - acm-pca:DescribeCertificateAuthority Resource: "*" ManagedPolicyArns: - arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess - arn:aws:iam::aws:policy/AWSLambdaFullAccess - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess - arn:aws:iam::aws:policy/AmazonEC2FullAccess - arn:aws:iam::aws:policy/AmazonS3FullAccess - arn:aws:iam::aws:policy/AWSCloud9User - arn:aws:iam::aws:policy/IAMFullAccess - arn:aws:iam::aws:policy/AmazonSSMFullAccess - arn:aws:iam::aws:policy/AdministratorAccess CreationLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: ca_cert_creation RetentionInDays: 60 RevLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: cert_revocation RetentionInDays: 60 RevEventRule: Type: AWS::Events::Rule Properties: Description: "Certificate revoked" EventPattern: source: - "aws.acm-pca" detail-type: - "AWS API Call via CloudTrail" detail: eventSource: - "acm-pca.amazonaws.com" eventName: - "RevokeCertificate" State: "ENABLED" Targets: - Arn: Fn::GetAtt: - RevLogGroup - Arn Id: cert-revocation-log - Arn: Fn::GetAtt: - LambdaCARevocation - Arn Id: rev-cert-lambda DependsOn: - RevLogGroup CreationEventRule: Type: AWS::Events::Rule Properties: Description: "CA Certificate created" EventPattern: source: - "aws.acm-pca" detail-type: - "AWS API Call via CloudTrail" detail: eventSource: - "acm-pca.amazonaws.com" eventName: - "ImportCertificateAuthorityCertificate" State: "ENABLED" Targets: - Arn: Fn::GetAtt: - CreationLogGroup - Arn Id: ca-cert-creation-log - Arn: Fn::GetAtt: - LambdaCACreation - Arn Id: ca-cert-creation-lambda DependsOn: - CreationLogGroup S3Bucket: DeletionPolicy: Retain Type: 'AWS::S3::Bucket' Properties: {} BucketPolicy: Type: 'AWS::S3::BucketPolicy' Properties: Bucket: Ref: S3Bucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: AWSCloudTrailAclCheck Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: 's3:GetBucketAcl' Resource: !Sub 'arn:aws:s3:::${S3Bucket}' - Sid: AWSCloudTrailWrite Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: 's3:PutObject' Resource: !Sub 'arn:aws:s3:::${S3Bucket}/AWSLogs/${AWS::AccountId}/*' Condition: StringEquals: 's3:x-amz-acl': bucket-owner-full-control LambdaCACreationPermission: Type: "AWS::Lambda::Permission" Properties: Action: 'lambda:InvokeFunction' FunctionName: Ref: LambdaCACreation Principal: 'events.amazonaws.com' SourceArn: Fn::GetAtt: - CreationEventRule - Arn LambdaCARevocationPermission: Type: "AWS::Lambda::Permission" Properties: Action: 'lambda:InvokeFunction' FunctionName: Ref: LambdaCARevocation Principal: 'events.amazonaws.com' SourceArn: Fn::GetAtt: - RevEventRule - Arn LambdaCACreation: Type: 'AWS::Lambda::Function' Properties: FunctionName: CertAuthCreation Handler: index.lambda_handler Runtime: python3.7 Timeout: 60 Role: !GetAtt LambdaRole.Arn Tags: - Key: workshop Value: acm-private-ca Code: ZipFile: | import json import boto3 import datetime def lambda_handler(event, context): secHubClient = boto3.client('securityhub') accountNum = boto3.client('sts').get_caller_identity()['Account'] my_session = boto3.session.Session() region = my_session.region_name caCertARN = event['detail']['requestParameters']['certificateAuthorityArn'] date = datetime.datetime.now().isoformat() + "Z" print(date) response = secHubClient.batch_import_findings( Findings=[ { "SchemaVersion": "2018-10-08", "Id": region + "/" + accountNum + "/" + caCertARN, "ProductArn": "arn:aws:securityhub:" + region + ":" + accountNum + ":product/" + accountNum + "/default", "GeneratorId": caCertARN, "AwsAccountId": accountNum, "Types": [ "Unusual Behaviors/Process" ], "CreatedAt": date, "UpdatedAt": date, "Severity": { "Normalized": 60 }, "Criticality": 80, "Title": "Certificate Authority Creation", "Description": "A Private CA certificate was issued in AWS Certificate Manager Private CA", "Remediation": { "Recommendation": { "Text": "Verify this CA certificate creation was taken by a privileged user", "Url": "https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaAuthAccess.html" } }, "ProductFields": { "aws/securityhub/FindingId": "arn:aws:securityhub:" + region + ":" + accountNum + ":product/" + accountNum + "/default/" + region + "/" + accountNum + "/caCertARN", "aws/securityhub/SeverityLabel": "MEDIUM", "aws/securityhub/ProductName": "ACM PCA", "aws/securityhub/CompanyName": "AWS" }, "Resources": [ { "Type": "Other", "Id": caCertARN, "Region": region } ], "WorkflowState": "NEW", "RecordState": "ACTIVE" }, ] ) print(response) return 200 LambdaCARevocation: Type: 'AWS::Lambda::Function' Properties: FunctionName: CertificateRevocation Handler: index.lambda_handler Runtime: python3.7 Timeout: 60 Role: !GetAtt LambdaRole.Arn Tags: - Key: workshop Value: acm-private-ca Code: ZipFile: | import json import boto3 import datetime def lambda_handler(event, context): secHubClient = boto3.client('securityhub') accountNum = boto3.client('sts').get_caller_identity()['Account'] my_session = boto3.session.Session() region = my_session.region_name certARN = event['detail']['requestParameters']['certificateSerial'] date = datetime.datetime.now().isoformat() + "Z" print(date) response = secHubClient.batch_import_findings( Findings=[ { "SchemaVersion": "2018-10-08", "Id": region + "/" + accountNum + "/" + certARN, "ProductArn": "arn:aws:securityhub:" + region + ":" + accountNum + ":product/" + accountNum + "/default", "GeneratorId": certARN, "AwsAccountId": accountNum, "Types": [ "Unusual Behaviors/Process" ], "CreatedAt": date, "UpdatedAt": date, "Severity": { "Normalized": 60 }, "Criticality": 80, "Title": "Certificate Revocation", "Description": "A private certificate was revoked in AWS Certificate Manager Private CA", "Remediation": { "Recommendation": { "Text": "Verify this certificate revocation was taken by a privileged user", "Url": "https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaAuthAccess.html" } }, "ProductFields": { "aws/securityhub/FindingId": "arn:aws:securityhub:" + region + ":" + accountNum + ":product/" + accountNum + "/default/" + region + "/" + accountNum + "/certARN", "aws/securityhub/SeverityLabel": "MEDIUM", "aws/securityhub/ProductName": "ACM PCA", "aws/securityhub/CompanyName": "AWS" }, "Resources": [ { "Type": "Other", "Id": certARN, "Region": region } ], "WorkflowState": "NEW", "RecordState": "ACTIVE" }, ] ) print(response) return 200 LambdaRole: Type: 'AWS::IAM::Role' Properties: RoleName: LambdaSecHubRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AWSSecurityHubFullAccess' - 'arn:aws:iam::aws:policy/CloudWatchFullAccess' SecHub: Type: "AWS::SecurityHub::Hub" myTrail: DependsOn: - BucketPolicy Type: 'AWS::CloudTrail::Trail' Properties: S3BucketName: !Ref S3Bucket IsLogging: true IsMultiRegionTrail: false