# Cloudflare R2 — storage your AI actually controls (Kit 4)

Kit 3 set up Cloudflare as your foundation. This one turns on the storage piece — a place for
your files that your AI can fully operate, in the same one control center as everything else.

Quick framing so you don't misread this: it is NOT about quitting Google Drive. Keep your Drive.
It's great for what it's for — everyday documents, organizing, sharing, and tools like NotebookLM
and Google's AI. R2 is a different tool for a different job. Drive is built for a person clicking
around in a browser; R2 is built for code, which means it's built for Claude. Drive is for you;
R2 is for your agent. You'll use both.

Cloudflare R2 is object storage (your own cloud drive) that lives in the same Cloudflare account
you set up in Kit 3. It speaks S3 — the standard language every storage tool already knows — and
you can give it ONE key that doesn't expire. Hand that key to your AI and it can list, upload,
download, and organize your files on its own, quietly, with no login screen in the way. No egress
fees, and it doubles as your CDN.

One note for your wallet before you sign up for anything: "object storage" is the category, and
R2 is S3-compatible, meaning it works like the storage standard everyone already knows. If you
already have object storage somewhere that speaks S3 (an Amazon S3 bucket, Backblaze B2,
DigitalOcean Spaces, and the like), you can point Claude at that instead. No need to double up.
R2 is the one to pick starting fresh, because it lives in the same Cloudflare account as
everything else and never charges you to pull your files back out.

The one thing to get right from the start is access: what's private, what's public, and how you
hand out the in-between safely. That's most of this kit.

## Prerequisite
- The Cloudflare account from Kit 3 (the API token you scoped there already covers R2).
- That's it. Claude can install anything else it needs (like rclone).

## How to use it (any OS)
Two ways — both end with Claude doing the setup:

- **Quick:** hit Copy, open Claude Code, paste this in, and say the line below.
- **Most reliable** (let Claude read the whole file): hit Download, then tell Claude:
  *"read ~/Downloads/r2-storage-setup.md and set it up with me."*

Either way, say:

> "Set up Cloudflare R2 as my AI-controlled storage. Make TWO buckets to start: one PRIVATE (for
> my data, backups, anything not meant for the public) and one PUBLIC (for images/files I want to
> serve on the web). Create an S3 API token scoped to my buckets, set to NEVER expire, and store
> the Access Key ID + Secret safely. Configure rclone so I can use the private bucket like a drive.
> For the public bucket, connect a cdn subdomain and turn OFF the default r2.dev URL so everything
> serves through my domain. Show me how to hand out a single private file with a time-limited
> presigned URL. Ask me for what you need as you go."

## The mental model: three ways in
Every bucket starts PRIVATE — nothing is reachable until you deliberately open it. There are
exactly three ways to grant access, and picking the right one per file is the whole game.

1. **Your AI and your tools → the S3 key.** A permanent Access Key ID + Secret. Full read/write,
   never touches the public internet. This is how Claude runs your storage.
2. **The public → a custom domain (your CDN).** For files meant for everyone (site images, public
   downloads), put them in a PUBLIC bucket and connect a `cdn.yourdomain.com` domain. Now they
   serve fast off Cloudflare's edge. Turn OFF the default `r2.dev` URL so all traffic goes through
   your proxied domain (caching + control). Heads up: a custom domain makes the WHOLE bucket
   readable to anyone who knows an object's path — so only genuinely-public things go in here.
3. **The in-between → a signature.** For a private file you want to hand to one person for a short
   time (a paid download, a client's file), you do NOT make the bucket public. You generate a
   presigned URL — a signed, time-limited link to that one object that expires on its own (say, in
   an hour). It's the S3 "signature": temporary public access to one private file, nothing else.

For anything gated at scale — per-customer downloads, paywalled files — put a small Worker in
front of the private bucket that checks a token (or logs you in) before it serves the file. That's
the production version of a signature: your code decides who gets in, the bucket stays private.

## What it sets up

**1. A private bucket + a public bucket.** Keep them separate on purpose. Private data must never
land in the bucket that has a public domain on it — that's the one mistake that turns "storage"
into "leak."

**2. One S3 key that doesn't expire.** R2 → Manage R2 API Tokens → Create API Token. You get an
Access Key ID and a Secret, and you can set expiration to "never." THIS is the difference from
Google Drive: a permanent, standard credential your AI holds indefinitely — no OAuth dance, no
re-consent. Scope it to your buckets with read + write.

**3. rclone on the private bucket — treat it like a drive.** `rclone sync ~/important
r2:private/important` backs your data up, and your AI runs the same commands. Copy, sync, mount.

**4. The public bucket wired as your CDN.** Custom domain connected, r2.dev off. Assets in this
bucket serve at cdn.yourdomain.com — the image on a sales page and last night's public export in
one fast place.

**5. Presigned URLs for private hand-offs.** Claude can generate one on demand: a link to a single
private object that works for a set number of minutes, then dies. No bucket exposure.

**6. The pricing, so you know exactly what you're signing up for.**
- First 10 GB every month: free.
- After that: about 1.5 cents per GB per month (100 GB is roughly $1.50).
- Egress — pulling your data back out — is zero. Always. No bandwidth bill, no download caps.

Honest note: for a giant cheap locker of terabytes, a consumer plan can be cheaper per terabyte.
R2's win isn't "cheapest locker" — it's your data becoming infrastructure your AI controls, with a
key that doesn't expire and no toll to read your own files back.

## Security — the part not to skip
- **Private by default.** A bucket is closed until you add a custom domain or enable r2.dev. Don't
  open one unless you mean to.
- **Separate private and public buckets.** A custom domain exposes every object in that bucket by
  its key (no listing, but guessable/leakable paths are public). Never mix private data in.
- **Reach for the weakest access that works:** S3 key for you/your AI, presigned URL for a
  one-off private hand-off, a Worker-guard for anything gated at scale. Public bucket only for
  things that are truly public.
- **Guard the Secret.** Env var or secret store, never hardcoded, never committed. Scope the token
  to specific buckets and read/write only. "Never expires" is safe *because* you can revoke or
  rotate it in one click — it lasts until you decide it shouldn't.
- **Audit what's public.** Periodically check which buckets have a custom domain or r2.dev on, and
  confirm nothing private is sitting in them.

## If Claude needs the exact specs
R2 is S3-compatible. Endpoint `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`, region `auto`.
Credentials = Access Key ID + Secret from an R2 API token. rclone: provider `Cloudflare`, the
keys + endpoint, add `no_check_bucket = true` for object-scoped tokens; AWS CLI works with
`--endpoint-url`. Public bucket: Settings → connect a custom domain, then disable the r2.dev
managed URL. Presigned URL: S3 `presign` (aws-cli `aws s3 presign s3://bucket/key --expires-in
3600 --endpoint-url ...`, or the SDK) — time-limited GET/PUT. Gated serving: a Worker with an R2
bucket binding that validates a token/session before returning the object.

## Make it stick
Key in your secret store, handed to your agent, with an `rclone sync` for the folders you want
backed up on a schedule. From then on your data lives somewhere your AI owns — not somewhere it
has to keep logging into.

You're done when: your AI can list, upload, and download your PRIVATE bucket on its own with a key
that doesn't expire; your PUBLIC bucket serves at cdn.yourdomain.com; and you can hand someone a
single private file with a link that expires on its own.

That's Kit 4. Your data now belongs to your setup, not to a login screen — and you decide, file by
file, who gets in.

-- Cliff (connectwithcliff.com)
