skip to Main Content

I want to deploy a static site with CDK, I know that setting s3 bucket to public access is restricted since april 2023, So I decided to go with the OriginAccessIdentity route, but getting 403 when trying to access the domain name that is tied to the distribution and thisone to the s3 bucket.

this is my code so far:

const oai = new OriginAccessIdentity(this, siteDomain);
const siteBucket = new s3.Bucket(this, "SiteBucket", {
      bucketName: siteDomain,
      autoDeleteObjects: true,
      publicReadAccess: false,
      removalPolicy: RemovalPolicy.DESTROY, // not for production
      websiteIndexDocument: "index.html",
      websiteErrorDocument: "error.html",
    });

    new CfnOutput(this, "Bucket", { value: siteBucket.bucketName });

    siteBucket.grantRead(oai);

    const distribution = new Distribution(this, "Distribution", {
      certificate: certificate,
      defaultRootObject: "index.html",
      domainNames: [siteDomain, domainName],
      minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2021,
      errorResponses: [
        {
          httpStatus: 404,
          responseHttpStatus: 404,
          responsePagePath: "/error.html",
        },
      ],
      defaultBehavior: {
        allowedMethods: AllowedMethods.ALLOW_ALL,
        cachePolicy: CachePolicy.CACHING_DISABLED, // only for development
        compress: true,
        origin: new S3Origin(siteBucket, { originAccessIdentity: oai }),
        originRequestPolicy: new OriginRequestPolicy(
          this,
          "OriginRequestPolicy",
          {
            headerBehavior: OriginRequestHeaderBehavior.all(),
            queryStringBehavior: OriginRequestQueryStringBehavior.all(),
            cookieBehavior: OriginRequestCookieBehavior.all(),
          }
        ),
        viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
    });

the error I get is:

Code: AccessDenied
Message: Access Denied

any advice will be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    The solution involves two main components:

    1. Setting up the S3 Bucket: This includes configuring the bucket to block public access, which is crucial for security. The bucket is also set up to automatically delete objects and to serve a website.
    const siteBucket = new s3.Bucket(this, "SiteBucket", {
      bucketName: siteDomain,
      autoDeleteObjects: true,
      removalPolicy: RemovalPolicy.DESTROY, // not for production
      websiteIndexDocument: "index.html",
      websiteErrorDocument: "error.html",
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS, // super important
    });
    
    1. Creating a Policy that Allows Public Read Access: This policy allows any user to read all objects in the bucket. It's important to note that this policy should be used carefully, as it allows public access to the bucket's contents.
    const bucketPolicy = new PolicyStatement({
      sid: "allow-public-access",
      principals: [new AnyPrincipal()],
      effect: Effect.ALLOW,
      actions: ["s3:GetObject"],
      resources: [siteBucket.bucketArn + "/*"],
    });
    
    siteBucket.addToResourcePolicy(bucketPolicy);
    

    In this code, siteBucket.addToResourcePolicy(bucketPolicy); adds the policy to the bucket, effectively applying the permissions defined in the policy.

    found the inspiration on this video https://www.youtube.com/watch?v=X9cdkqBgLbs


  2. You can’t use OAI on a S3 bucket configured as a website endpoint.
    You should configure the bucket as a custom origin and restrict access to served files with custom headers.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search