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.
Scanned 2/12/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: "cloudflare-r2-bucket-management-and-access"
description: "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."
---
# Cloudflare 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:
```toml
[[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:
```ts
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:
```ts
if (!c.get("user")) return c.json({ auth: false }, 401);
```
---
## Public Access Mode
Enable public read with bucket policy:
```bash
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)
```ts
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:
```json
{
"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:
```ts
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 (`v1/avatars`) for migrations
---
## Listing + Search
```ts
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:
```bash
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 |
|---|---|
| `hono-r2-integration` | This skill expands it with policy, access control, public/private modes |
| `cloudflare-worker-deployment` | Ensures R2 bindings are correctly mapped across envs |
| `cloudflare-d1-migrations-and-production-seeding` | Not DB schema — but both require env-controlled versioning |
| `hono-authentication` | User-based folder ownership, signed URL verification |
No comments yet. Be the first to comment!