Amazon S3
Before you begin
An AWS account with permission to create IAM users/policies and S3 buckets.
Steps
-
Bucket — S3 console → Buckets → create or choose one; note the name and region. Object Ownership is usually “Bucket owner enforced” (ACLs disabled) — this plugin never sets object ACLs.
-
IAM user — IAM console → Users → Create user → programmatic access only (no console password needed).
-
Policy — attach an inline policy scoped to your bucket:
{"Version": "2012-10-17","Statement": [{ "Sid": "ListBucket", "Effect": "Allow","Action": ["s3:ListBucket", "s3:GetBucketLocation"],"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME" },{ "Sid": "ObjectReadWrite", "Effect": "Allow","Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject","s3:AbortMultipartUpload", "s3:ListMultipartUploadParts"],"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*" }]}To scope to a key prefix instead, add a
Conditionwiths3:prefixon theListBucketstatement and change the object-actionsResourcetobucket/PREFIX/*— then set the same prefix in Universal Storage → Storage. The Universal Storage → Health screen generates this policy pre-filled for your current bucket/prefix. -
Access key — IAM → your user → Security credentials → Create access key (“Application running outside AWS”). The secret is shown once — store it now.
-
In Universal Storage → Settings, choose provider Amazon S3, enter the bucket, region, and the access key/secret, then Test connection. When Amazon S3 is selected, custom endpoint and path-style settings from previous S3-compatible configurations are ignored so the connection test targets AWS S3 directly.
Public delivery
The plugin never sets public-read ACLs. For public delivery, use a CDN (CloudFront with
Origin Access Control is the standard pattern) or a bucket policy allowing
s3:GetObject, and set that hostname as the CDN/Base URL in Universal Storage →
Storage.
Verify it worked
Test connection on the Storage screen passes all steps (client, bucket, upload, HEAD, delete). If your bucket has no public read path configured, the test also warns you about that explicitly rather than letting it fail silently at delivery time.
Troubleshooting
AccessDenied/403 — the IAM policy is missing, attached to the wrong user, or scoped to
the wrong bucket/prefix. Confirm under IAM → Users → your plugin’s user → Permissions. Run
wp universal-storage test for a CLI-side check independent of the admin button.