Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(s3): use Bucket Policy for Server Access Logging grant (under feature flag) #23386

Merged
merged 3 commits into from
Dec 28, 2022

Conversation

laurelmay
Copy link
Contributor

@laurelmay laurelmay commented Dec 18, 2022

Using ACLs to grant access to buckets is no longer recommended. In fact,
it doesn't work if Object Ownership is set to be enforced for the
bucket. According to the service documentation for enabling server
access logging
, it is now preferred to use a bucket policy to grant
permission to deliver logs to a bucket.

Changing the default would result in changes to deployed resources, so
the new behavior is added behind a feature flag.

An alternative here may be to use the Bucket Policy either when the feature
flag is enabled or when ownership is set to BUCKET_OWNER_ENFORCED since
the latter doesn't work with the current implementation anyway.

Closes: #22183


All Submissions:

Adding new Construct Runtime Dependencies:

  • This PR adds new construct runtime dependencies following the process described here

New Features

  • Have you added the new feature to an integration test?
    • Did you use yarn integ to deploy the infrastructure and generate the snapshot (i.e. yarn integ without --dry-run)?

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

…ature flag)

Using ACLs to grant access to buckets is no longer recommended. In fact,
it doesn't work if Object Ownership is set to be enforced for the
bucket. According to the service documentation for [enabling server
access logging][1], it is now preferred to use a bucket policy to grant
permission to deliver logs to a bucket.

Changing the default would result in changes to deployed resources, so
the new behavior is added behind a feature flag.

[1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html
@gitpod-io
Copy link

gitpod-io bot commented Dec 18, 2022

@github-actions github-actions bot added p2 admired-contributor [Pilot] contributed between 13-24 PRs to the CDK labels Dec 18, 2022
@aws-cdk-automation aws-cdk-automation requested a review from a team December 18, 2022 18:58
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

@laurelmay
Copy link
Contributor Author

Features must contain a change to an integration test file and the resulting snapshot.

I assume that like in #22740 this is just covered by the existing integration test. If there's a way to actually test both sides of the feature flag, I'd be happy to write an additional test but it seems like integ-runner uses the NEW_PROJECT_FLAGS.

Copy link
Contributor

@corymhall corymhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kylelaker we had a previous PR that was going to do this, but we ended up closing it because some services still require the ACL #20898

@laurelmay
Copy link
Contributor Author

@kylelaker we had a previous PR that was going to do this, but we ended up closing it because some services still require the ACL #20898

Oh I missed that. I guess in searching I only looked at open PRs. Sorry for the duplicate.

For what it's worth, the idea of a single shared logs bucket is a bit broken with that CloudFront example. The ACL grant is done by CloudFormation itself when specifying the Logging property (putting the ACL in the template isn't required like it is for S3). This results in conflicting ACLs being written (CloudFront requires FULL_CONTROL and S3 uses the canned ACL for read/write). So when combined, depending on ordering, CloudFront is unable to write logs anyway.

This PR also does not enforce BUCKET_OWNER_ENFORCED but purely adopts a bucket policy. That might even fix the CloudFront use case because there wouldn't be competing ACLs for the Log Delivery (but that certainly wasn't intentional as I was writing this).

Here is the stack I used for testing this:

import * as cdk from 'aws-cdk-lib';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import { Construct } from 'constructs';

export class TestS3Stack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const logsBucket = new s3.Bucket(this, 'LogsBucket');
    const content = new s3.Bucket(this, 'Content');
    const deployment = new s3deploy.BucketDeployment(this, 'ContentDeployment', {
      sources: [s3deploy.Source.asset('website')],
      destinationBucket: content,
    });
    const origin = new origins.S3Origin(content);

    const distribution = new cloudfront.Distribution(this, 'Distribution', {
      // CloudFormation handles the ACL grant for CloudFront to this bucket. It
      // will grant FULL_CONTROL to c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0
      // as well as to the current account
      logBucket: logsBucket,
      logFilePrefix: "distribution",
      defaultBehavior: { origin },
    });
  }

If any bucket starts logging to logsBucket after the initial creation of this stack, log delivery from CloudFront will start to fail because the FULL_CONTROL access to that Canonical User ID is no longer present. If the buckets stopped needing ACLs for log delivery and instead used the bucket policy, CloudFront would still work after adding a bucket that logs to logsBucket.

This feels like it's actually a CloudFormation bug (ideally, the Distribution wouldn't be so magical about ACLs or it'd be even more magical and figure out when the Bucket's ACL changed and update accordingly).

But because this PR doesn't start requiring BUCKET_OWNER_ENFORCED, the only thing that it would do is allow users to start adopting the policy format instead and elect to use BUCKET_OWNER_ENFORCED if that works for them. Instead of being behind a feature flag, this could just be done automatically if BUCKET_OWNER_ENFORCED is set because that would break any services that require ACLs anyway.

Overall, this whole situation is a bit of a mess. Hopefully all services can start working with Bucket Policy soon.

@corymhall
Copy link
Contributor

But because this PR doesn't start requiring BUCKET_OWNER_ENFORCED, the only thing that it would do is allow users to start adopting the policy format instead and elect to use BUCKET_OWNER_ENFORCED if that works for them. Instead of being behind a feature flag, this could just be done automatically if BUCKET_OWNER_ENFORCED is set because that would break any services that require ACLs anyway.

Overall, this whole situation is a bit of a mess. Hopefully all services can start working with Bucket Policy soon.

@kylelaker thanks for the detailed explanation! I think I'm good with your solution. Can update the S3 readme to have a new entry that shows our recommended configuration?

@corymhall corymhall added the pr-linter/exempt-integ-test The PR linter will not require integ test changes label Dec 27, 2022
@corymhall corymhall self-assigned this Dec 27, 2022
@aws-cdk-automation aws-cdk-automation dismissed their stale review December 27, 2022 13:15

✅ Updated pull request passes all PRLinter validations. Dissmissing previous PRLinter review.

@mergify mergify bot dismissed corymhall’s stale review December 28, 2022 00:15

Pull request has been modified.

@mergify
Copy link
Contributor

mergify bot commented Dec 28, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: cdcb49a
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit 6975a7e into aws:main Dec 28, 2022
@mergify
Copy link
Contributor

mergify bot commented Dec 28, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@laurelmay laurelmay deleted the s3-bucket-logging-policy-no-acl branch December 28, 2022 21:02
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Jan 20, 2023
…ature flag) (aws#23386)

Using ACLs to grant access to buckets is no longer recommended. In fact,
it doesn't work if Object Ownership is set to be enforced for the
bucket. According to the service documentation for [enabling server
access logging][1], it is now preferred to use a bucket policy to grant
permission to deliver logs to a bucket.

Changing the default would result in changes to deployed resources, so
the new behavior is added behind a feature flag.

An alternative here may be to use the Bucket Policy either when the feature
flag is enabled or when ownership is set to `BUCKET_OWNER_ENFORCED` since
the latter doesn't work with the current implementation anyway.

Closes: aws#22183 

[1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html


----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [X] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Feb 22, 2023
…ature flag) (aws#23386)

Using ACLs to grant access to buckets is no longer recommended. In fact,
it doesn't work if Object Ownership is set to be enforced for the
bucket. According to the service documentation for [enabling server
access logging][1], it is now preferred to use a bucket policy to grant
permission to deliver logs to a bucket.

Changing the default would result in changes to deployed resources, so
the new behavior is added behind a feature flag.

An alternative here may be to use the Bucket Policy either when the feature
flag is enabled or when ownership is set to `BUCKET_OWNER_ENFORCED` since
the latter doesn't work with the current implementation anyway.

Closes: aws#22183 

[1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html


----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [X] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
admired-contributor [Pilot] contributed between 13-24 PRs to the CDK p2 pr-linter/exempt-integ-test The PR linter will not require integ test changes
Projects
None yet
3 participants