Mastodon

CORS Rules

Your bucket's CORS rules say which websites may use it from a browser,
with which methods and headers. A valid key is still required either way.

When you need them

Your setup CORS rules
A web app, wiki or uploader on your own domain calling the S3 API with a key Yes.
Tools that send no website: the AWS CLI, rclone, a backup job, a server No. A request with no Origin header is never refused by a rule.
A static site served from the bucket, visited directly No. The page and its files share one origin.
That site's files embedded on another domain (a font, a video, a JSON file) Yes. The same rules apply on the web endpoint.

The default

A bucket with no rules answers *: any website may use it, with a valid
key. Nothing is stored. The Files tab in this dashboard is a website too,
and it works on every bucket because of this default.

Add a rule and only the websites you name get through.

Set rules in the dashboard

Open the bucket, Manage, then Advanced Options. The editor loads the
live rules from the bucket, never a cached copy, so what you see is what
get-bucket-cors would return.

Each rule has:

Field Meaning
Allowed origins One website per line, scheme included: https://app.example.ca. * means any.
Allowed methods GET, PUT, POST, DELETE, HEAD, or Any.
Allowed headers Request headers the browser may send. * for any. Uploads from a page need Authorization, Content-Type and the x-amz-* headers an SDK sets.
Expose headers Response headers the page's JavaScript may read. ETag for multipart uploads.
Max age Seconds a browser may reuse its preflight answer. Blank leaves it to the browser.
Rule name Optional, for you.

Raw JSON shows the same rules in the put-bucket-cors shape and edits
both ways: type valid JSON and the form follows, edit the form and the JSON
follows.

The Raw JSON pane open beside the form, showing the same rule as JSON

Saving a rule that restricts asks you to confirm and lists the websites
that will still get through. If someone changed the rules since you loaded
them (another tab, a put-bucket-cors), the save is refused and the editor
reloads onto the live rules instead of overwriting them.

The restrict confirm, naming the one website that will still get through and reminding that a key is still required

Set rules over S3

A rule you write here appears in the editor unchanged, and the other way
round.

{
  "CORSRules": [
    {
      "ID": "app",
      "AllowedOrigins": ["https://app.example.ca"],
      "AllowedMethods": ["GET", "PUT"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag"],
      "MaxAgeSeconds": 3600
    }
  ]
}
aws s3api put-bucket-cors --bucket your-bucket-name --cors-configuration file://cors.json \
  --endpoint-url https://alpha.buckets.stormdevelopments.ca --profile stormdevelopments

aws s3api get-bucket-cors --bucket your-bucket-name \
  --endpoint-url https://alpha.buckets.stormdevelopments.ca --profile stormdevelopments

The key needs owner permission on the bucket: the bucket's admin key, or an
account key. Profile setup is in
Connecting S3 Tooling.

How Storm enforces them

AWS refuses at the preflight. Storm cannot: every bucket is reached through
its key, so the unauthenticated preflight cannot tell which bucket it is
for. The preflight answers * and the browser sends the real request. Storm
reads the rules on that request, the one carrying your key, the bucket and
the Origin, and refuses it when no rule matches: HTTP 403 with the S3
error code cors_origin_refused. The outcome for the bucket is the same as
a refused preflight.

Rules are stored the moment you save. Whether your endpoint refuses on them
yet is on the badge beside the editor: Enforced, or Stored, not
enforced yet
. Until an endpoint enforces, it answers * for every
website. A change on an enforcing endpoint takes effect within 30 seconds.

A refused request in the Files tab, or from your own page, is covered in
Troubleshooting.