Skip to content

Commit

Permalink
Merge pull request #238 from gammarer/feature/add-origin-access-controle
Browse files Browse the repository at this point in the history
feat: add origin access control
  • Loading branch information
yicr committed Apr 5, 2024
2 parents d7ff17b + 0f556e1 commit 181b82b
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 56 deletions.
109 changes: 98 additions & 11 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

[![View on Construct Hub](https://constructs.dev/badge?package=@gammarer/aws-secure-cloudfront-origin-bucket)](https://constructs.dev/packages/@gammarer/aws-secure-cloudfront-origin-bucket)

An AWS CDK construct library to create secure S3 buckets for CloudFront origin.
An AWS CDK construct library to create secure S3 buckets for CloudFront origin.

## Install

Expand All @@ -20,6 +20,10 @@ An AWS CDK construct library to create secure S3 buckets for CloudFront origin.
npm install @gammarer/aws-secure-cloudfront-origin-bucket
# or
yarn add @gammarer/aws-secure-cloudfront-origin-bucket
# or
pnpm add @gammarer/aws-secure-cloudfront-origin-bucket
# or
bun add @gammarer/aws-secure-cloudfront-origin-bucket
```

### Python
Expand Down Expand Up @@ -47,18 +51,34 @@ Add the following to pom.xml:

## Example

### for OAI(Origin Access Identity)

```typescript
import { SecureCloudFrontOriginBucket } from '@gammarer/aws-secure-cloudfront-origin-bucket';
import { SecureCloudFrontOriginBucket, SecureCloudFrontOriginType } from '@gammarer/aws-secure-cloudfront-origin-bucket';

const oai = new cloudfront.OriginAccessIdentity(stack, 'OriginAccessIdentity');

new SecureCloudFrontOriginBucket(stack, 'SecureCloudFrontOriginBucket', {
bucketName: 'example-origin-bucket',
cloudFrontOriginType: SecureCloudFrontOriginType.ORIGIN_ACCESS_IDENTITY,
cloudFrontOriginAccessIdentityS3CanonicalUserId: oai.cloudFrontOriginAccessIdentityS3CanonicalUserId,
});
```

### for OAC(Origin Access Control)

```typescript
import { SecureCloudFrontOriginBucket, SecureCloudFrontOriginType } from '@gammarer/aws-secure-cloudfront-origin-bucket';

declare const s3Bucket: cloudfront.Distribution;

new SecureCloudFrontOriginBucket(stack, 'SecureCloudFrontOriginBucket', {
bucketName: 'example-origin-bucket',
cloudFrontOriginType: SecureCloudFrontOriginType.ORIGIN_ACCESS_CONTROL,
cloudFrontArn: 'arn:aws:cloudfront::123456789:distribution/DISTRIBUTIONID',
});
```

## License

This project is licensed under the Apache-2.0 License.
This project is licensed under the Apache-2.0 License.
73 changes: 60 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,78 @@
import { SecureBucket, SecureBucketEncryption } from '@gammarer/aws-secure-bucket';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export interface SecureCloudFrontOriginBucketProps {
export enum SecureCloudFrontOriginType {
/**
* OriginAccessIdentity
*/
ORIGIN_ACCESS_IDENTITY,

/**
* OriginAccessControl
*/
ORIGIN_ACCESS_CONTROL,
}

interface BaseSecureCloudFrontOriginBucketProps {
readonly bucketName?: string;
}

export interface SecureCloudFrontOriginAccessControlBucketProps extends BaseSecureCloudFrontOriginBucketProps {
readonly cloudFrontOriginType: SecureCloudFrontOriginType.ORIGIN_ACCESS_CONTROL;
readonly cloudFrontArn: string;
}

export interface SecureCloudFrontOriginAccessIdentityBucketProps extends BaseSecureCloudFrontOriginBucketProps {
readonly cloudFrontOriginType: SecureCloudFrontOriginType.ORIGIN_ACCESS_IDENTITY;
readonly cloudFrontOriginAccessIdentityS3CanonicalUserId: string;
}

export class SecureCloudFrontOriginBucket extends SecureBucket {

constructor(scope: Construct, id: string, props: SecureCloudFrontOriginBucketProps) {
constructor(scope: Construct, id: string, props: SecureCloudFrontOriginAccessControlBucketProps | SecureCloudFrontOriginAccessIdentityBucketProps) {
super(scope, id, {
bucketName: props.bucketName,
encryption: SecureBucketEncryption.S3_MANAGED, // Notice)Only S3 Managed
versioned: false,
});

// 👇Allow CloudFront access
this.addToResourcePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [
new iam.CanonicalUserPrincipal(
props.cloudFrontOriginAccessIdentityS3CanonicalUserId,
),
],
resources: [`${this.bucketArn}/*`],
}));
// 👇 add BucketPolicy
const bucketPolicy = new s3.BucketPolicy(scope, 'BucketPolicy', {
bucket: this,
});

switch (props.cloudFrontOriginType) {
case SecureCloudFrontOriginType.ORIGIN_ACCESS_CONTROL:
// 👇 add bucket policy statement for cloud front origin access identity
bucketPolicy.document.addStatements(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [
new iam.ServicePrincipal('cloudfront.amazonaws.com'),
],
resources: [`${this.bucketArn}/*`],
conditions: {
StringEquals: {
'AWS:SourceArn': props.cloudFrontArn,
},
},
}));
break;
case SecureCloudFrontOriginType.ORIGIN_ACCESS_IDENTITY:
// 👇 add bucket policy statement for cloud front origin access identity
bucketPolicy.document.addStatements(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [
new iam.CanonicalUserPrincipal(
props.cloudFrontOriginAccessIdentityS3CanonicalUserId,
),
],
resources: [`${this.bucketArn}/*`],
}));
break;
}
}
}
Loading

0 comments on commit 181b82b

Please sign in to comment.