# pages A micro static-site host at `pages.elijah.run`, running entirely on Cloudflare (Workers + R2 + D1) with the Worker written in Rust compiled to WebAssembly. ## What it does - Browse all live pages at `pages.elijah.run`. - Log in with GitHub, upload a single `.html` file or a `.zip` of static assets (drag & drop), pick a name, and the content is served at `pages.elijah.run//`. - Update a page in place: **Update** on any page you own re-uploads its content under the same name (the URL never changes, and files the new upload doesn't include are removed). - Admins approve which users may upload, and can delete or update any page. Hosted pages are intended to be **client-side-only single-page apps**. They are served with a sandboxing Content-Security-Policy (opaque origin): no cookies, no localStorage — see `docs/plans/2026-07-12-pages-design.md` §2.1. An admin can mark a specific page, or all of a user's pages, as **trusted** to opt them out of that sandbox (e.g. for local-first apps that need `localStorage`) — see the "Trust escape hatch" addendum in §2.1 for the exact semantics and the security trade-off that comes with it. ## How it works One Cloudflare Worker routes everything: - `/` — embedded management UI (list, login, upload, admin) - `/auth/*` — GitHub OAuth + session cookies (sessions in D1, hashed) - `/api/*` — JSON API (list/upload/update/delete pages, manage users) - `//*` — page content served from R2 with strict security headers Uploads are validated hard: strict slug grammar + reserved names, zip path-traversal rejection, decompression limits (10 MiB compressed, 25 MiB uncompressed, 300 files). See the design doc for the full security analysis. ## Run locally ```sh # from pages/ cp .dev.vars.example .dev.vars # fill in a GitHub OAuth app's id/secret wrangler d1 execute pages --local --file migrations/schema.sql wrangler dev # builds via worker-build and serves locally ``` ## Test ```sh # from pages/ cargo fmt cargo check --target wasm32-unknown-unknown cargo clippy --all-targets -- -D warnings cargo test ``` ## Deploy Infrastructure (R2 bucket, D1 database, DNS, rate limits) is OpenTofu in `infra/`; the Worker itself deploys with `wrangler deploy` (see `infra/README.md`). Secrets via `wrangler secret put GITHUB_CLIENT_SECRET`. ## License Dual-licensed under [Apache-2.0](../LICENSE-APACHE) and [MIT](../LICENSE-MIT), like the rest of this repository. ## Disclaimer This software was written with Claude Code. Design, review and orchestration by Claude Fable 5 (`claude-fable-5`); implementation by Claude Sonnet agents with Claude Opus review agents.