Claude-skill-registry cloudflare-r2-bucket-management-and-access
Use this skill to configure Cloudflare R2 buckets, access control, lifecycle policies, public/private assets, and integration with Hono Workers using read/write/delete/list operations and signed-access patterns.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cloudflare-r2-bucket-management-and-access" ~/.claude/skills/majiayu000-claude-skill-registry-cloudflare-r2-bucket-management-and-access && rm -rf "$T"
skills/data/cloudflare-r2-bucket-management-and-access/SKILL.mdCloudflare R2 Bucket Management & Access Skill
Purpose
You are the assistant responsible for managing R2 storage in production including:
- Bucket provisioning & environment separation
- Public/private access strategy
- Upload/download/stream patterns
- Lifecycle rules & retention policies
- Signed URL access patterns
- Asset optimization + access performance
Use this skill when handling Cloudflare R2 + Hono Worker integration beyond basic uploads.
Do not use this skill for:
- D1 schema or migrations →
cloudflare-d1-migrations-and-production-seeding - Core Hono routing →
hono-app-scaffold - Auth logic →
hono-authentication
Environment-Aware Bucket Setup
This skill knows how to structure R2 per environment:
[[r2_buckets]] binding = "BUCKET" bucket_name = "my-bucket-dev" preview_bucket_name = "my-bucket-dev" [env.staging] [[env.staging.r2_buckets]] binding = "BUCKET" bucket_name = "my-bucket-staging" [env.production] [[env.production.r2_buckets]] binding = "BUCKET" bucket_name = "my-bucket-prod"
Claude should:
- Default to separate buckets per environment
- Suggest mirroring structure between staging & prod
- Prevent mixing prod bucket during dev
R2 Access Permission Strategy
R2 can be accessed in multiple ways — this skill helps choose between:
| Mode | Use Case |
|---|---|
| Private (default) | User uploads, internal assets |
| Public Read | Images, static assets, public files |
| Signed-access URLs | Limited-time external file sharing |
| Proxy download route via Hono | Controlled rule-based access |
This skill selects approach based on context.
Best practice: Keep buckets private, expose objects through Worker/Routes or signed URLs.
Private Access (Recommended Default)
Use Cloudflare Worker as controlled access:
app.get("/file/:key", async (c) => { const key = decodeURIComponent(c.req.param("key")); const obj = await c.env.BUCKET.get(key); if (!obj) return c.notFound(); return new Response(obj.body, { headers: { "Content-Type": obj.httpMetadata?.contentType ?? "application/octet-stream" } }); });
This enables auth-check:
if (!c.get("user")) return c.json({ auth: false }, 401);
Public Access Mode
Enable public read with bucket policy:
wrangler r2 bucket policy put BUCKET << 'EOF' { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "r2:GetObject", "Resource": "BUCKET/*" } ] } EOF
Use only for assets intended to be publicly hosted (CDN optimized).
Upload Handling (secure)
const file = await c.req.formData().then(f => f.get("file") as File); const key = `users/${c.get("user")?.id}/${Date.now()}-${file.name}`; await c.env.BUCKET.put(key, await file.arrayBuffer(), { httpMetadata: { contentType: file.type } }); return c.json({ key, url: `/file/${encodeURIComponent(key)}` });
The skill ensures safe naming conventions:
- No raw user-supplied keys
- Timestamp or UUID prefix
- Supports multi-tenant structures
R2 Lifecycle Policies
Claude may apply retention or expiration policy suggestions:
| Policy | Benefit |
|---|---|
| Auto-delete after X days | Temporary file cleanup |
| Move to cold storage after X | Cost reduction |
| Prevent overwrite unless flagged | Audit safety |
Example JSON policy reference:
{ "Rules": [ { "ID": "auto-expire-temp", "Filter": { "Prefix": "temp/" }, "Expiration": { "Days": 30 } } ] }
Signed URL Access (download/share)
Cloudflare does not sign natively — we generate JWT-contained key + expiry:
import { SignJWT, jwtVerify } from "jose"; export async function createSignedURL(key: string, expSec: number, secret: string) { const token = await new SignJWT({ key }) .setProtectedHeader({ alg: "HS256" }) .setExpirationTime(Math.floor(Date.now()/1000) + expSec) .sign(new TextEncoder().encode(secret)); return `/download/${token}`; } app.get("/download/:token", async (c) => { const secret = c.env.JWT_SECRET; const { payload } = await jwtVerify(c.req.param("token"), new TextEncoder().encode(secret)); const obj = await c.env.BUCKET.get(payload.key); if(!obj) return c.notFound(); return new Response(obj.body); });
This simulates presigned URLs safely.
Directory-like Prefixing
Claude may suggest folder-style structure for organization:
/public/assets/* /users/[id]/uploads/* /tenants/[id]/invoices/* /tmp/uploads/*
Naming rules enforced by this skill:
- Avoid exposing tenant IDs publicly unless hashed
- PascalCase or kebab-case predictable
- Versionable storage layout (
) for migrationsv1/avatars
Listing + Search
const result = await c.env.BUCKET.list({ prefix: `users/${id}/` }); return c.json(result.objects.map(o => ({ key: o.key, size: o.size, date: o.uploaded })));
Skill advises pagination if results exceed limits.
CI/CD Hooks For R2 Deployments
This skill suggests combining with future CI/CD workflow:
wrangler deploy --env production
Then apply bucket policy or migration tasks post-deploy.
For automation:
- cache invalidation
- namespace provisioning
- retention checks
Example Prompts That Activate This Skill
- “Store files in R2 with security rules.”
- “Make public CDN bucket for static assets.”
- “Generate signed URLs for temporary downloads.”
- “Organize tenant bucket structure cleanly.”
- “Set expiration policy for old file uploads.”
Interactions With Other Skills
| Skill | How it connects |
|---|---|
| This skill expands it with policy, access control, public/private modes |
| Ensures R2 bindings are correctly mapped across envs |
| Not DB schema — but both require env-controlled versioning |
| User-based folder ownership, signed URL verification |