quickS3.com
Cloudflare R2 file manager for teams: API token, CORS, and setup

Cloudflare R2 file manager for teams: API token, CORS, and setup

Give your team a web file manager for Cloudflare R2 without dashboard access. Create a scoped R2 API token, fix CORS errors, and share expiring links.

•8 min read

The Cloudflare dashboard is a fine place to create an R2 bucket, and a poor place to hand files to a team. Anyone who browses R2 there needs a seat on your Cloudflare account, nobody can be limited to one folder, and dashboard uploads stop at 300 MB per file. Putting an R2 API token in a desktop client gets around the size limit, but then everyone shares one credential.

This guide connects R2 to quickS3 instead. Your team signs in to quickS3 and gets a web file manager for the buckets and folders their role allows. The R2 token stays in one place, and files move straight between the browser and Cloudflare.

What you’ll set up

  • An R2 API token limited to the buckets your team needs
  • A quickS3 connection built from your Cloudflare account ID
  • CORS on the bucket, so uploads work in the browser (quickS3 does this for you)
  • Roles that give each person the right buckets and folders

Ways to give your team access to R2

Cloudflare dashboard Desktop client (Cyberduck, rclone) quickS3
Each person needs A seat on your Cloudflare account A copy of an R2 API token A quickS3 login
Access to one folder only No No, tokens are scoped per bucket Yes, set per role
Removing one person Remove them from the account Roll the token for everyone Remove them from the role
Largest upload 300 MB per file Large files, in parts Large files, in parts
AI agents (Claude, Codex) No No Yes, over MCP, with the same roles

Step 1: Create an R2 bucket

  1. Log in to the Cloudflare dashboard.
  2. Go to R2 Object Storage and click Create bucket.
  3. Pick a name (lowercase, no spaces is safest). Leave the location on Automatic unless you need your data kept in the EU or in a FedRAMP environment.

While you’re on the R2 overview page, copy your Account ID. quickS3 builds the endpoint from it.

Step 2: Create an R2 API token

R2 uses R2 API tokens as S3 credentials.

  1. In R2 Object Storage, click Manage API tokens.

  2. Create an Account API token or a User API token. An account token keeps working if the person who created it leaves your Cloudflare account, which makes it the better choice for a shared tool like quickS3.

  3. Under Permissions, pick the smallest one that works:

    • Object Read & Write (recommended): read, write, and list objects in the buckets you choose.
    • Object Read only: read and list objects in the buckets you choose.
    • Admin Read only: list buckets and read objects across the account.
    • Admin Read & Write: full control of every bucket. Only use it if you really need it.

    With an Object permission, the token can’t list buckets, so quickS3 can’t find them for you. You’ll type the bucket names into quickS3’s Bucket scopes field instead.

  4. If you chose an Object permission, pick the bucket or buckets it applies to.

  5. Leave Client IP Address Filtering empty. quickS3’s requests don’t come from one fixed IP, so a filter will block them.

  6. Create the token and copy the Access Key ID and Secret Access Key from the S3 section of the page. Cloudflare shows the secret only once.

Cloudflare also shows a Token value on that page. That’s a Cloudflare API token, not an S3 key, and quickS3 doesn’t need it.

Step 3: Connect R2 to quickS3

  1. In quickS3, go to Storage Providers and click Add Provider.
  2. Choose Cloudflare R2.
  3. Fill in the form:
    • Account ID: from Step 1.
    • Jurisdiction: Standard (No Jurisdiction) for most buckets. Choose European Union (EU) or FedRAMP only if you created the bucket with that jurisdiction. quickS3 shows the endpoint it will use.
    • Bucket scopes (optional): leave blank to let quickS3 list every bucket the token can reach. With an Object token, enter the bucket names, comma-separated.
    • Access key ID and Secret access key: from Step 2.
  4. Leave Allow quickS3 to update bucket CORS settings (recommended) on. When you save or test the connection, quickS3 adds its origin to the bucket’s CORS policy.
  5. Leave Allow uploads through quickS3 off. Uploads go straight from the browser to R2, and file data never passes through quickS3.
  6. Save. quickS3 tests the connection before storing it.

Step 4: Give your team access

A quickS3 role is a list of rules. Each rule names a connection, a bucket, and optionally a prefix (a folder), and says whether it allows reading or writing. Deny rules always win over allow rules.

For example, a Marketing role might allow writing to campaigns/ in your assets bucket, while a Freelancer role allows reading briefs/ and writing deliveries/ and nothing else. Create the roles under Permissions, then invite people and assign them. Nobody needs a Cloudflare login, and changing someone’s access never means rolling a token.

To send a file to someone outside your team, open it in quickS3 and create a share link that expires after 1 hour, 6 hours, 1 day, 7 days, or 30 days.

CORS for Cloudflare R2

Browsers block requests from one site to another unless the second site allows it. When you upload in quickS3, your browser sends the file from https://quicks3.com straight to https://<ACCOUNT_ID>.r2.cloudflarestorage.com, so the bucket must allow that origin. With CORS updates switched on, quickS3 sets this up when you save the connection. You only need the steps below if you turned that off.

In the Cloudflare dashboard:

  1. Open R2 Object Storage and select your bucket.
  2. Go to Settings.
  3. Under CORS Policy, click Add CORS policy.
  4. In the JSON tab, paste a policy like this:
[
  {
    "AllowedOrigins": ["https://quicks3.com"],
    "AllowedMethods": ["GET", "PUT", "HEAD", "DELETE"],
    "AllowedHeaders": ["*"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]

Or with Wrangler:

  1. Log in:
npx wrangler login
  1. Save the policy as cors.json:
{
  "rules": [
    {
      "allowed": {
        "origins": ["https://quicks3.com"],
        "methods": ["GET", "PUT", "HEAD", "DELETE"]
      }
    }
  ]
}
  1. Apply it to your bucket:
npx wrangler r2 bucket cors set <BUCKET_NAME> --file cors.json
  1. Check what’s set:
npx wrangler r2 bucket cors list <BUCKET_NAME>

Common R2 CORS errors

  • “No ‘Access-Control-Allow-Origin’ header is present”: the origin in the policy doesn’t match the page exactly. Use https://quicks3.com, with no path and no trailing slash.
  • The preflight (OPTIONS) request fails: the upload sends a header the policy doesn’t allow. "AllowedHeaders": ["*"] is the easy fix.
  • It works in production but not on localhost: add http://localhost:<port> as a second origin, port included.
  • You just changed the policy and nothing happened: R2 can take up to about 30 seconds to apply CORS changes. Wait, then reload.

R2 endpoints and jurisdictions

R2’s S3 endpoint is built from your account ID:

  • Standard: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
  • EU: https://<ACCOUNT_ID>.eu.r2.cloudflarestorage.com
  • FedRAMP: https://<ACCOUNT_ID>.fedramp.r2.cloudflarestorage.com

A bucket created with a jurisdiction only answers on that jurisdiction’s endpoint. If you have buckets in both, create one quickS3 connection for each. The S3 region for R2 is always auto, and quickS3 sets it for you.

Troubleshooting

InvalidAccessKeyId or SignatureDoesNotMatch

  • You pasted the Token value instead of the Access Key ID and Secret Access Key.
  • The secret was pasted with a missing character or a trailing space. Create a new token if you can’t be sure.
  • The jurisdiction on the connection doesn’t match the bucket’s.

AccessDenied when quickS3 lists buckets

  • The token has an Object permission, which can’t list buckets. Enter the bucket names in Bucket scopes.

AccessDenied on one bucket

  • The token is scoped to other buckets. Edit the token in Manage API tokens and add the bucket.
  • Client IP Address Filtering is set on the token. Remove it.

“blocked by CORS policy”

  • Turn Allow quickS3 to update bucket CORS settings on and click Test connection again, or see the CORS errors above.

Let Claude or Codex use your R2 bucket

quickS3 is also a remote MCP server, at https://quicks3.com/mcp. Once R2 is connected, Claude, Claude Code, Codex, or another MCP client that supports OAuth can list folders, fetch files, and upload results. The agent doesn’t get an R2 token. It only gets the quickS3 roles you pick when you approve it, it has no delete tool, and file data goes straight between the agent and R2 through short-lived links. See Connect Claude Code to S3 or Connect Codex to S3.

What R2 costs

As of September 2026, R2 Standard storage is $0.015 per GB per month, with no egress fees. Writes and lists cost $4.50 per million requests, and reads $0.36 per million. The free tier covers 10 GB of storage, 1 million writes, and 10 million reads each month. Check Cloudflare’s R2 pricing page for current rates.


Using another provider too? quickS3 also works with Backblaze B2, DigitalOcean Spaces, Wasabi, and AWS S3. Ready to try it? Sign up for quickS3 and connect your R2 bucket.

For maintained setup steps and current limits, use the Cloudflare R2 documentation.

Read next