The Magic Sauce: Cloudfront IAM Policies for Use with W3 Total Cache

If you want to improve the performance of your WordPress installation, W3 Total Cache is one of the best options out there for optimizing page delivery and script minification. But if you want to take your performance web-scale, you’ll need to consider a commercial-grade Content Delivery Network (CDN). Fortunately, W3 Total Cache offer multiple options, and (in my humble opinion) Amazon Web Services Cloudfront running on top of an S3 bucket is the best CDN option available. While the W3 Total Cache FAQ has a decent overview of how to configure a basic CloudFront/S3 CDN, AWS architectures that implement the higher level of security offered by assigning specific IAM accounts to Cloudfront distributions and S3 buckets can present a problem.

Even though Frederick Townes deserves a Nobel Prize for creating W3 Total Cache, he didn’t quite nail it when comes to parsing messages generated by the AWS API when the plugin tries to connect to Cloudfront.

Here is the most common error messages I ran into when trying to configure W3 Total Cache to work with Cloudfront within a PCI 3 compliant AWS architecture:

Error: Unable to list buckets (S3::listBuckets(): [AccessDenied] Access Denied).

W3 Total cache tries to create a dropdown list of S3 Buckets to which the IMA account has access. While listBucket is a valid IAM policy to list the contents of an S3 bucketS3, listBuckets isn’t valid. The correct policy reference is ListAllMyBuckets.

The correct IAM policy should look like this:

{
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::cdn.mydomain.com",
"arn:aws:s3:::cdn.mydomain.com/*"
]
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
}
]
}

But this only covers the policy to list the S3 Buckets. If you’re using W3 Total Cache with Cloudfront, you also need to be able to list the Cloudfront distributions:

{
"Version": "2014-10-31",
"Statement":[{
"Effect":"Allow",
"Action":["cloudfront:ListDistributions"],
"Resource":"*"
}
]
}

From a security perspective, it’s not ideal that the IAM policy has to be able to list the distributions and buckets. A better solution would be to provide a field in which to manually enter the bucket or distribution name.

Leave a Reply