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/.beans/pages-shqc--per-page-and-pe...

40 lines
2.2 KiB
Markdown

---
# pages-shqc
title: 'Per-page and per-user trust: opt out of CSP sandbox'
status: completed
type: feature
priority: normal
created_at: 2026-07-13T23:44:29Z
updated_at: 2026-07-13T23:58:27Z
---
Allow admin-designated trusted pages/users whose content is served WITHOUT the CSP sandbox (design §2.1), so local-first apps can use localStorage. Effective trust = pages.trusted OR users.trusted (owner), computed at serve time via D1 join.
Scope:
- migrations: add users.trusted + pages.trusted (INTEGER NOT NULL DEFAULT 0); base schema.sql updated for fresh installs + incremental 0002 migration for live DB
- db.rs: trusted fields on User/PageRow, get_page joins owner trust, set_page_trusted, set_user_trusted
- api.rs: PATCH /api/pages/{slug} {trusted} (admin+Origin), PATCH /api/users/{id} accepts {can_upload?, trusted?}
- serve.rs: D1 lookup first (404 for unknown slug before R2), conditional sandbox header
- core: pure helper for conditional header set + tests
- UI: admin trust toggles (users panel + per-page), trusted badge
- docs: design §2.1 addendum — trusted content can act as any visitor incl. admins; trust only content you authored
- [x] schema + migration
- [x] db.rs trust support
- [x] api endpoints
- [x] serve-time conditional sandbox
- [x] core helper + tests
- [x] UI toggles/badge
- [x] docs updated
- [x] full validation suite green
## Summary of Changes
Per-page + per-user trust escape hatch by a Sonnet agent; Opus production-rigor review: APPROVE, no blockers.
- Effective trust = pages.trusted OR owner users.trusted, computed via live join at serve time; only the 200 content path can drop the sandbox — 301/404/500 and all error branches stay sandboxed (fail-safe verified).
- Trust settable only by admins (Origin-checked PATCH /api/pages/{slug} + extended PATCH /api/users/{id}); login upsert can never touch it.
- migrations/0002-trust.sql for the live DB (must run BEFORE deploy — old columns missing → 500s, review-confirmed fail-safe but an outage).
- UI: trusted badges + admin toggles; docs §2.1 addendum with the explicit trusted-content warning.
- Review hygiene fix: tfplan* gitignored and removed from the tree.
148 unit tests + 18 doctests green; both targets clippy-clean.