Skip to content

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:

  1. Automated Visual Regression & Demo Recordings: Hosting dual-viewport headless screencasts (walkthrough.mp4) and high-resolution route screenshots (<route>.webp) produced by scripts/capture-demo.ts and .github/workflows/demo-capture.yml.
  2. 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:

  1. 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).
  2. Key Hierarchy:
    • Demo Walkthroughs:
      demos/<app-slug>/<environment>/<commit-sha>/<viewport>/<filename>
      Example: demos/bakery/staging/bab68a1/desktop/walkthrough.mp4 Example: demos/bakery/staging/bab68a1/mobile/menu.webp
    • Shared Media:
      media/<tenant-slug>/<collection>/<sha256-hash>.<ext>
      Example: media/bakery/pastries/a1b2c3d4e5f6.webp

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 a 400 MalformedXML API error). Consequently, all active local development ports (3000 for Node/Next, 4321 for Astro, 5173 for Vite, and 8787/8788 for 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:

Terminal window
# Set CORS configuration from JSON file
npx wrangler r2 bucket cors set siteswarm-demos --file /path/to/cors.json -y
npx wrangler r2 bucket cors set siteswarm-media --file /path/to/cors.json -y
# Verify active CORS rules
npx wrangler r2 bucket cors list siteswarm-demos
npx wrangler r2 bucket cors list siteswarm-media

4. 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.com

4.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_ID
  • CLOUDFLARE_API_TOKEN
  • R2_ACCESS_KEY_ID
  • R2_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:

  1. Dual-Viewport Screencast Capture:
    • desktop: 1920x1080 @ 1x scale factor.
    • mobile: 390x844 @ 2x Retina scale factor (iPhone 14 profile).
  2. Screencast Encoding:
    • CDP Page.startScreencast frames are piped into ffmpeg producing walkthrough.mp4 (yuv420p, +faststart).
    • High-resolution keyframes per route are encoded to WebP (<route-slug>.webp).
  3. Artifact Upload:
    • Uploads directly to siteswarm-demos bucket using either AWS S3 SigV4 PUT or Cloudflare REST API PUT.
  4. Zero-Dependency Presigned SigV4 URLs:
    • Uses Node’s native node:crypto (createHmac, createHash) to generate 7-day AWS SigV4 GetObject presigned 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.
scripts/capture-demo.ts
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

Terminal window
# 1. List provisioned buckets on the corporate account
pnpm 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 configuration
pnpm exec wrangler r2 bucket cors list siteswarm-demos
pnpm 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 Probe
echo "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 Probe
pnpm 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:

  1. 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.
  2. 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.
  3. 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.
  4. Client-Specific Storage Quota Telemetry: Per-tenant storage usage tracking via Cloudflare Analytics Engine will be implemented alongside tenant billing dashboards.