You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vibed/pages/docs/ARCHITECTURE.md

2.2 KiB

pages — Architecture

Full design + security analysis: plans/2026-07-12-pages-design.md.

Components

                     ┌─────────────────────────────────────────┐
 browser ──────────▶ │  Cloudflare Worker (Rust → wasm, axum)  │
                     │                                         │
  GET  /             │  routes/mod.rs   router construction    │
  GET  /auth/*       │  routes/auth.rs  GitHub OAuth, sessions │──▶ github.com (token exchange)
  *    /api/*        │  routes/api.rs   pages + users JSON API │──▶ D1 `DB` (users/sessions/pages)
  GET  /<slug>/*     │  routes/serve.rs page content serving   │──▶ R2 `PAGES` (<slug>/<path>)
                     │                                         │
                     │  core/  pure policy logic (native-      │
                     │         tested): slug, mime, upload     │
                     │         validation, security headers    │
                     └─────────────────────────────────────────┘

Component interactions

  • core/ has no Cloudflare dependencies; it compiles natively and holds every security-relevant decision (slug grammar, reserved names, zip limits, MIME allowlist, CSP header values). Unit tests live here.
  • db.rs (wasm-only) wraps D1 queries; routes/ (wasm-only) are thin axum handlers that call core + db + R2.
  • auth.rs builds OAuth URLs and cookie/session token logic (pure parts native-tested); the GitHub HTTP calls are wasm-only.
  • static/index.html is the whole management UI, embedded at compile time with include_str! and served at /.

Trust boundaries

  1. Uploaded content is untrusted: validated in core/upload.rs, stored in R2, and always served with a sandboxing CSP (opaque origin) so it can never make credentialed calls to /api.
  2. Browser → API: session cookie (__Host-, HttpOnly, SameSite=Lax, hashed in D1) + Origin check on mutating routes.
  3. Worker → GitHub: client secret only ever used server-side.