From 77bd2864821ab00ec6cdee9764091062b51fbce8 Mon Sep 17 00:00:00 2001 From: Stephen Kuenzli Date: Tue, 25 Jun 2024 22:37:58 -0700 Subject: [PATCH] Test CloudFront OAC support by creating a Key and Bucket. It works! https://d2p2e6v3qepvh3.cloudfront.net/great-news-everyone.jpg Created CloudFront distribution manually because there's a dependency issue. CloudFront distributions rely on S3 Buckets (origin). But the S3 Bucket and KMS Key policy relies on the CloudFront distribution id. So a circular dependency, though it looks like there may be a workaround: https://github.com/aws/aws-cdk/issues/21771 --- bin/k9-cdk.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/bin/k9-cdk.ts b/bin/k9-cdk.ts index 443c31a..35aba0b 100644 --- a/bin/k9-cdk.ts +++ b/bin/k9-cdk.ts @@ -2,6 +2,8 @@ import * as cdk from "aws-cdk-lib"; import {RemovalPolicy, Tags} from "aws-cdk-lib"; +// import * as cloudfront from "aws-cdk-lib/aws-cloudfront"; +// import * as cforigins from "aws-cdk-lib/aws-cloudfront-origins"; import * as kms from "aws-cdk-lib/aws-kms"; import * as s3 from "aws-cdk-lib/aws-s3"; import {BlockPublicAccess, BucketEncryption} from "aws-cdk-lib/aws-s3"; @@ -26,6 +28,7 @@ const readConfigArns = administerResourceArns.concat( const readWriteDataArns = [ "arn:aws:iam::123456789012:role/app-backend", "arn:aws:iam::139710491120:role/k9-dev-appeng", + "arn:aws:sts::139710491120:assumed-role/k9-dev-appeng/console" ]; const readDataArns = [ @@ -132,6 +135,60 @@ const key = new kms.Key(stack, 'KMSKey', { policy: keyPolicy, }); -for(let construct of [bucket, websiteBucket, autoDeleteBucket, key]){ +// Created test distribution manually because I haven't fully sorted through +// https://github.com/aws/aws-cdk/issues/21771 +// +// let cloudfrontDistribution = new cloudfront.Distribution(stack, 'oac-bucket-dist', { +// comment: 'k9-cdk integration test distribution for CloudFront OAC', +// defaultBehavior: { +// origin: new cforigins.S3Origin(cloudfrontOACBucket, { +// +// }), +// }, +// }); +let cloudfrontDistributionId = 'E1OHGXOERP1X0D' +let cloudfrontDistributionArn = `arn:aws:cloudfront::${stack.account}:distribution/${cloudfrontDistributionId}` +// let cloudfrontDistributionArn = `arn:aws:cloudfront::${stack.account}:distribution/${cloudfrontDistribution.distributionId}` + +const cloudfrontOACk9KeyPolicyProps: k9.kms.K9KeyPolicyProps = { + k9DesiredAccess: k9BucketPolicyProps.k9DesiredAccess, + trustAccountIdentities: false, + awsServiceAccessGenerators: new Array( + new k9.kms.CloudFrontOACReadAccessGenerator(cloudfrontDistributionArn), + ) +}; +const cloudfrontOACKeyPolicy = k9.kms.makeKeyPolicy(cloudfrontOACk9KeyPolicyProps); + +const cloudfrontOACKey = new kms.Key(stack, 'CloudFrontOACKMSKey', { + alias: 'k9-cdk-v2-cloudfront-oac-test', + policy: cloudfrontOACKeyPolicy, +}); + +const cloudfrontOACBucket = new s3.Bucket(stack, 'CloudFrontOACBucket', { + bucketName: 'k9-cdk-v2-cloudfront-oac-test', + removalPolicy: RemovalPolicy.DESTROY, + encryption: BucketEncryption.KMS, + encryptionKey: cloudfrontOACKey +}); + +const cloudfrontOACBucketPolicyProps: k9.s3.K9BucketPolicyProps = { + bucket: cloudfrontOACBucket, + k9DesiredAccess: k9BucketPolicyProps.k9DesiredAccess.concat([]), + encryption: BucketEncryption.KMS_MANAGED, + awsServiceAccessGenerators: new Array( + new k9.s3.CloudFrontOACReadAccessGenerator(cloudfrontOACBucket, cloudfrontDistributionArn), + ) +}; + +k9.s3.grantAccessViaResourcePolicy(stack, "CloudFrontOACBucket", cloudfrontOACBucketPolicyProps); + +for (let construct of [bucket, + websiteBucket, + autoDeleteBucket, + key, + // cloudfrontDistribution, + cloudfrontOACBucket, + cloudfrontOACKey, +]) { Tags.of(construct).add('k9security:analysis', 'include'); }