R2 Storage Baseline
Cloudflare R2 Storage Baseline, Provisioning & Operational Runbook
1. Executive Summary & Purpose
This operational runbook governs the architecture, provisioning, CORS security configuration, credential management, and programmatic integration of Cloudflare R2 object storage for the SiteSwarm edge platform on the corporate account (JP Technology Solutions / Account ID: 7fba1ed07b005a3c31a890fe6c20cda2).
Cloudflare R2 provides zero-egress fee S3-compatible object storage. Within SiteSwarm, R2 is the foundational tier for:
- Automated Visual Regression & Demo Recordings: Hosting dual-viewport headless screencasts (
walkthrough.mp4) and high-resolution route screenshots (<route>.webp) produced byscripts/capture-demo.tsand.github/workflows/demo-capture.yml. - Client Media & Asset Ingestion: Storing tenant-uploaded imagery, static branding assets, and dynamic CMS media decoupled from application bundles.
flowchart TD subgraph CorporateAccount ["Cloudflare Corporate Account (7fba1ed07b005a3c31a890fe6c20cda2)"] subgraph Buckets ["R2 Storage Buckets"] DemoBucket[("siteswarm-demos\n(Private Storage)")] MediaBucket[("siteswarm-media\n(Private / CORS Restricted)")] end
subgraph Security ["Perimeter Security & CORS"] CORS["Bucket CORS Policy\n• https://*.jpsoftwareassociates.com\n• https://jpsoftwareassociates.com\n• http://localhost:[3000, 4321, 5173, 8787]"] SigV4["AWS SigV4 Presigner (scripts/capture-demo.ts)\n• Zero-dependency node:crypto HMAC-SHA256\n• 7-Day Expiration Ceiling (604,800s)"] end end
subgraph CI ["Continuous Integration (GitHub Actions)"] DemoCapture["demo-capture.yml\n(CDP Screencast Engine)"] Secrets["Repository Secrets\n• R2_ACCESS_KEY_ID\n• R2_SECRET_ACCESS_KEY\n• CLOUDFLARE_API_TOKEN\n• CLOUDFLARE_ACCOUNT_ID"] end
subgraph Consumers ["Consumers & Edge Services"] PRComment["GitHub PR Execution Evidence\n(Presigned 7-Day Video/Screenshot Links)"] ClientApps["Client Applications & Astro Edge\n(Shared Media & Demo Assets)"] end
Secrets --> DemoCapture DemoCapture -->|"S3 SigV4 Upload / REST PUT"| DemoBucket DemoCapture --> SigV4 SigV4 --> PRComment Buckets --- CORS CORS --> ClientApps[!IMPORTANT] Architectural Invariant (Domain Separation): Technical runbooks govern storage bucket configurations, credential access matrices, CORS rules, and programmatic SDK/CLI bindings. Retail subscription prices, billing tiers, and monthly commercial retainers are strictly out of scope per repository governance.
2. Bucket Inventory & Naming Conventions
2.1 Provisioned Buckets
| Bucket Name | Account ID | Default Storage Class | Purpose | Access Perimeter |
|---|---|---|---|---|
siteswarm-demos |
7fba1ed07b005a3c31a890fe6c20cda2 |
Standard | Playwright CDP screencasts, walkthrough videos, and route screenshots | Private; presigned SigV4 URLs only |
siteswarm-media |
7fba1ed07b005a3c31a890fe6c20cda2 |
Standard | Shared client assets, CMS uploads, and visual branding assets | Restricted; CORS allowed origins |
2.2 Naming Conventions & Object Key Taxonomy
SiteSwarm enforces deterministic, kebab-case naming for all R2 buckets and structured prefix partitioning for stored objects:
- Bucket Naming Standard:
- Platform Buckets:
siteswarm-<purpose>(e.g.,siteswarm-demos,siteswarm-media). - Tenant-Specific Buckets:
client-<slug>-media(when tenant isolation requires dedicated storage).
- Platform Buckets:
- Key Hierarchy:
- Demo Walkthroughs:
Example:demos/<app-slug>/<environment>/<commit-sha>/<viewport>/<filename>
demos/bakery/staging/bab68a1/desktop/walkthrough.mp4Example:demos/bakery/staging/bab68a1/mobile/menu.webp - Shared Media:
Example:media/<tenant-slug>/<collection>/<sha256-hash>.<ext>
media/bakery/pastries/a1b2c3d4e5f6.webp
- Demo Walkthroughs:
3. Bucket CORS Policies & Security Perimeter
3.1 CORS Policy Specification
Both siteswarm-demos and siteswarm-media enforce a CORS policy permitting client-side HTTP GET and HEAD requests from corporate platform domains and authenticated local development origins.
{ "rules": [ { "allowed": { "origins": [ "https://*.jpsoftwareassociates.com", "https://jpsoftwareassociates.com", "http://localhost", "http://localhost:3000", "http://localhost:4321", "http://localhost:5173", "http://localhost:8787", "http://localhost:8788", "http://127.0.0.1:3000", "http://127.0.0.1:4321", "http://127.0.0.1:5173", "http://127.0.0.1:8787" ], "methods": [ "GET", "HEAD" ], "headers": [ "*" ] }, "exposeHeaders": [ "ETag", "Content-Type", "Content-Length" ], "maxAgeSeconds": 86400 } ]}[!NOTE] R2 Wildcard Port Constraint: Cloudflare R2 supports wildcards in subdomains (
https://*.jpsoftwareassociates.com), but does not allow wildcards in port numbers (e.g.,http://localhost:*triggers a400 MalformedXMLAPI error). Consequently, all active local development ports (3000for Node/Next,4321for Astro,5173for Vite, and8787/8788for Wrangler) are explicitly enumerated in the origin matrix.
3.2 Applying and Inspecting CORS via Wrangler
To apply the canonical CORS policy to a bucket:
# Set CORS configuration from JSON filenpx wrangler r2 bucket cors set siteswarm-demos --file /path/to/cors.json -ynpx wrangler r2 bucket cors set siteswarm-media --file /path/to/cors.json -y
# Verify active CORS rulesnpx wrangler r2 bucket cors list siteswarm-demosnpx wrangler r2 bucket cors list siteswarm-media4. Access Credential Architecture & Security Matrix
SiteSwarm adheres to a Dual-Tier Access Credential Matrix separating Cloudflare Account API Tokens from S3-compatible R2 credentials.
4.1 Credential Topology & Scopes
| Credential Type | Environment Variable | Target System | Scope / Permissions |
|---|---|---|---|
| Cloudflare Account API Token | CLOUDFLARE_API_TOKEN |
Wrangler CLI & REST API | Account-level: Workers R2 Storage:Edit, Workers Scripts:Edit |
| Cloudflare Account ID | CLOUDFLARE_ACCOUNT_ID |
Wrangler & AWS SDK | Target: 7fba1ed07b005a3c31a890fe6c20cda2 |
| R2 S3 Access Key ID | R2_ACCESS_KEY_ID |
scripts/capture-demo.ts, AWS SDK |
S3 API endpoint access; bucket-scoped read/write |
| R2 S3 Secret Access Key | R2_SECRET_ACCESS_KEY |
scripts/capture-demo.ts, AWS SDK |
HMAC signing secret for SigV4 authorization & presigning |
4.2 S3-Compatible API Endpoint
Cloudflare R2 provides an S3-compatible REST API endpoint mapped per account:
https://7fba1ed07b005a3c31a890fe6c20cda2.r2.cloudflarestorage.com4.3 GitHub Actions CI/CD Secrets
For automated demo capture workflows (.github/workflows/demo-capture.yml), configure the following repository secrets under Settings > Secrets and variables > Actions:
CLOUDFLARE_ACCOUNT_IDCLOUDFLARE_API_TOKENR2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEY
5. Programmatic Demo Capture & Media Integration
5.1 Demo Capture Engine Architecture (scripts/capture-demo.ts)
SiteSwarm’s demo capture engine integrates directly with Cloudflare R2 and Cloudflare Browser Rendering over CDP:
- Dual-Viewport Screencast Capture:
desktop: 1920x1080 @ 1x scale factor.mobile: 390x844 @ 2x Retina scale factor (iPhone 14 profile).
- Screencast Encoding:
- CDP
Page.startScreencastframes are piped intoffmpegproducingwalkthrough.mp4(yuv420p,+faststart). - High-resolution keyframes per route are encoded to WebP (
<route-slug>.webp).
- CDP
- Artifact Upload:
- Uploads directly to
siteswarm-demosbucket using either AWS S3 SigV4 PUT or Cloudflare REST API PUT.
- Uploads directly to
- Zero-Dependency Presigned SigV4 URLs:
- Uses Node’s native
node:crypto(createHmac,createHash) to generate 7-day AWS SigV4GetObjectpresigned URLs without heavy external AWS SDK dependencies. - URLs are embedded into the standard 7-Column Execution Evidence Table and the
### 🎬 Presigned Video & Screenshot Evidence (7-Day R2 Links)PR comment.
- Uses Node’s native
export const DEFAULT_DEMOS_BUCKET = 'siteswarm-demos';export const DEFAULT_PRESIGN_TTL_SECONDS = 604_800; // 7 days (maximum AWS SigV4 TTL)6. Tier 2 Behavioral Runtime Verification & Operational Commands
All bucket operations can be verified live using the Wrangler CLI and curl probes.
6.1 Verification Command Reference
# 1. List provisioned buckets on the corporate accountpnpm exec wrangler r2 bucket list# Expected output:# name: siteswarm-demos# creation_date: 2026-11-11T...# name: siteswarm-media# creation_date: 2026-11-11T...
# 2. Inspect active CORS configurationpnpm exec wrangler r2 bucket cors list siteswarm-demospnpm exec wrangler r2 bucket cors list siteswarm-media# Expected output:# allowed_origins: https://*.jpsoftwareassociates.com, https://jpsoftwareassociates.com, http://localhost, ...# allowed_methods: GET, HEAD
# 3. Remote Object Upload Probeecho "ok" | pnpm exec wrangler r2 object put siteswarm-demos/health.txt --pipe --remote# Expected output:# Resource location: remote# Creating object "health.txt" in bucket "siteswarm-demos".# Upload complete.
# 4. Remote Object Download Probepnpm exec wrangler r2 object get siteswarm-demos/health.txt --remote --pipe# Expected output:# ok
# 5. Anti-Mocking Failure-Mode Probe (Nonexistent key)pnpm exec wrangler r2 object get siteswarm-demos/nonexistent-key.txt --remote# Expected exit code: 1# Expected output:# ✘ [ERROR] The specified key does not exist.7. Decisions Intentionally Deferred
To uphold the Minimal Viable Abstraction (MVA) principle, the following capabilities are intentionally deferred to future platform iterations:
- Custom Public Domain Mapping (
cdn.jpsoftwareassociates.com): Public asset delivery currently relies on presigned S3 SigV4 URLs and direct edge proxy bindings. Custom public domain mapping with Cloudflare Managed Transforms will be evaluated during client asset CDN optimization. - Automated Object Lifecycle & Expiration Rules: Demo recordings currently utilize 7-day presigned URLs. Automatic R2 bucket lifecycle rules (e.g., pruning demo video objects older than 30 days) will be established in a subsequent operational hygiene milestone.
- Cross-Region Bucket Replication: R2 buckets currently operate with standard multi-region automatic edge replication; explicit cross-region replication rules are deferred until regulatory data residency requirements emerge.
- Client-Specific Storage Quota Telemetry: Per-tenant storage usage tracking via Cloudflare Analytics Engine will be implemented alongside tenant billing dashboards.