src/constructs/iam/policies/s3-get-object.ts (43 lines of code) (raw):

import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam"; import type { GuPrivateS3ConfigurationProps } from "../../../utils/ec2"; import { GuAppAwareConstruct } from "../../../utils/mixin/app-aware-construct"; import { GuDistributionBucketParameter } from "../../core"; import type { AppIdentity, GuStack } from "../../core"; import { GuAllowPolicy } from "./base-policy"; import type { GuNoStatementsPolicyProps } from "./base-policy"; export interface GuGetS3ObjectPolicyProps extends GuNoStatementsPolicyProps { bucketName: string; paths?: string[]; } export class GuGetS3ObjectsPolicy extends GuAllowPolicy { constructor(scope: GuStack, id: string, props: GuGetS3ObjectPolicyProps) { const paths: string[] = props.paths ?? ["*"]; const s3Resources: string[] = paths.map((path) => `arn:aws:s3:::${props.bucketName}/${path}`); super(scope, id, { ...props, actions: ["s3:GetObject"], resources: s3Resources }); } } /** * Creates an `AWS::IAM::Policy` to grant `s3:GetObject` permission to the account's distribution bucket. * The permission is tightly scoped to the path to the app (`bucket/stack/stage/app/*`) and will look something like: * * ```yaml * GetDistributablePolicyTestingF9D43A3E: * Type: AWS::IAM::Policy * Properties: * PolicyDocument: * Version: "2012-10-17" * Statement: * - Action: s3:GetObject * Effect: Allow * Resource: * Fn::Join: * - "" * - - 'arn:aws:s3:::' * - Ref: DistributionBucketName * - /STACK/ * - Ref: Stage * - /APP/* * PolicyName: GetDistributablePolicyTestingF9D43A3E * ``` * * If necessary, an `AWS::SSM::Parameter<String>` parameter will be added to the template, * with a default value of `/account/services/artifact.bucket` which is the recommended Parameter Store location. * * @see GuDistributionBucketParameter */ export class GuGetDistributablePolicy extends GuAppAwareConstruct(GuGetS3ObjectsPolicy) { constructor(scope: GuStack, props: AppIdentity) { const path = [scope.stack, scope.stage, props.app, "*"].join("/"); super(scope, "GetDistributablePolicy", { ...props, bucketName: GuDistributionBucketParameter.getInstance(scope).valueAsString, paths: [path], }); } } export class GuGetDistributablePolicyStatement extends PolicyStatement { constructor(scope: GuStack, props: AppIdentity) { const path = [scope.stack, scope.stage, props.app, "*"].join("/"); super({ effect: Effect.ALLOW, actions: ["s3:GetObject"], resources: [`arn:aws:s3:::${GuDistributionBucketParameter.getInstance(scope).valueAsString}/${path}`], }); } } export class GuGetPrivateConfigPolicy extends GuGetS3ObjectsPolicy { constructor(scope: GuStack, id: string, props: GuPrivateS3ConfigurationProps) { super(scope, id, { bucketName: props.bucket.valueAsString, paths: props.files }); } }