Documentation

Custom IAM Policy for Amazon S3

When creating an IAM User to use with Amazon S3 and WP Offload Media for the first time, we strongly recommend using the AmazonS3FullAccess policy to avoid any issues.

If you’re familiar with AWS IAM policies and later wish to restrict the Amazon S3 access for the AWS User who’s Access Keys are being used by WP Offload Media, here are the basic actions required for WP Offload Media to work properly.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ObjectLevel",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::*/*"
    },
    {
      "Sid": "BucketLevel",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketPublicAccessBlock",
        "s3:PutBucketPublicAccessBlock",
        "s3:GetBucketOwnershipControls",
        "s3:PutBucketOwnershipControls",
        "s3:CreateBucket",
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::*"
    },
    {
      "Sid": "AccountLevel",
      "Effect": "Allow",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "*"
    }
  ]
}

This policy allows the user to create buckets, delete files (not buckets), upload files, download files, and list files and buckets. It also allows for getting and changing the Block All Public Access and Object Ownership Enforced status for a bucket, and changing the ACL of objects. This is the basic level of permissions the plugin requires for all functionality to work without issues.

However, if some functionality is not needed, read on for how each section of the policy can be altered to further restrict access.

Object Level Restrictions

The PutObject, GetObject and DeleteObject actions are absolutely required and fundamental to WP Offload Media’s use. However, if the bucket being used with WP Offload Media has Block All Public Access enabled, or Object Ownership enforced, then the PutObjectAcl action is redundant and can be removed.

If the policy is to only be used with a single bucket, the Resource can be restricted to apply only to that bucket’s objects.

Therefore the bare minimum ObjectLevel section is as follows (change “mybucket” as appropriate)…

    {
      "Sid": "ObjectLevel",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::mybucket/*"
    },

Bucket Level Restrictions

The GetBucketLocation, ListBucket, GetBucketPublicAccessBlock and GetBucketOwnershipControls actions are absolutely required, allowing WP Offload Media to determine which region the bucket is in, list objects, check the Block All Public Access to Bucket status, and check whether Object Ownership is enforced respectively.

If you do not wish to allow WP Offload Media to enable or disable Block All Public Access for the Bucket, then the PutBucketPublicAccessBlock action can be removed. Errors will be shown if anyone tries to use that functionality.

Similarly, if you do not wish to allow WP Offload Media to control whether Object Ownership is enforced for the Bucket, then the PutBucketOwnershipControls action can be removed. Errors will be shown if anyone tries to use that functionality.

If you do not wish to allow WP Offload Media to create a bucket to offload to, then the CreateBucket action can be removed. Errors will be shown if anyone tries to use that functionality.

If the policy is to only be used with a single bucket, the Resource can be restricted to apply only to that bucket.

Therefore the bare minimum BucketLevel section is as follows (change “mybucket” as appropriate)…

    {
      "Sid": "BucketLevel",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketPublicAccessBlock",
        "s3:GetBucketOwnershipControls",
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::mybucket"
    },

Account Level Restrictions

This policy can be further tightened to restrict user access to a specific bucket and not see other buckets. Simply remove the AccountLevel section of the example policy so that buckets can not be listed.

It’s important to note that if you do restrict access like this, the plugin will give you an Access Denied error when trying to select a bucket. The user does not have permission to list all the buckets in your account. Fortunately you can simply type in the bucket name.

Minimum IAM User Policy

With the above taken into account, restricting access to a single “mybucket” bucket which has Block All Public Access enabled, and Object Ownership enforced, the following minimum IAM User policy should work with WP Offload Media.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ObjectLevel",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::mybucket/*"
    },
    {
      "Sid": "BucketLevel",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketPublicAccessBlock",
        "s3:GetBucketOwnershipControls",
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::mybucket"
    }
  ]
}

The above policy allows WP Offload Media to offload and manage the Media Library in a specific Amazon S3 bucket without any errors in general usage.

If however a WordPress admin user tries to use WP Offload Media to disable Block All Public Access on the bucket, turn off Object Ownership enforcement in the bucket, list buckets, create a bucket, or otherwise configure use with another bucket, those actions will fail.

Further Resources

You can read more about IAM policies here and AWS can generate one for you here.