docs(13): operator decision — web-search setting derives the AIUI CSP
The toggle must change what is POSSIBLE, not ask the frame to behave. Records the verified mechanics: CSP is nginx-emitted (static add_header), the setting lives only in browser localStorage today, and the node's nginx self-heal reverts hand edits — so the setting moves node-side and the CSP derives from it, allowlisted rather than wildcard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c3277a8323
commit
31f78bdced
+35
-1
@@ -35,7 +35,41 @@ inside the embed:
|
||||
- **Content enrichment does not work.** Poster/cover art and web-search lookups are outbound
|
||||
calls to third parties from the frame.
|
||||
|
||||
Two directions, and they are a real decision, not a detail:
|
||||
### OPERATOR DECISION (2026-08-06): the "web search" setting governs this
|
||||
|
||||
The existing AIUI **web search** toggle is the switch. On → outbound (relays, enrichment,
|
||||
search) is permitted. Off → local-only. And per the operator: *"we must make sure settings are
|
||||
valid"* — the toggle must **change what is possible**, not merely ask the frame to behave.
|
||||
|
||||
That makes the CSP **setting-derived** rather than a static choice between (a) and (b) below.
|
||||
Mechanics, verified on archi-dev-box:
|
||||
|
||||
- The CSP is emitted by **nginx**, not the binary —
|
||||
`/etc/nginx/sites-enabled/archipelago` `location /aiui/`, one static `add_header
|
||||
Content-Security-Policy … connect-src $scheme://$host:*/aiui/ blob: data: …`.
|
||||
- The setting currently lives **only in the browser**: `localStorage['aiui-web-search']`
|
||||
(`aiui/packages/app/src/stores/chat.ts:131`). A browser-side flag cannot drive a
|
||||
server-emitted header, and the iframe must not be able to widen its own sandbox.
|
||||
|
||||
So the work is:
|
||||
|
||||
1. **Move the setting node-side** (same shape as `grants.json`: persisted, default-closed,
|
||||
owner-owned) with an RPC to read/set it. AIUI reads it rather than owning it.
|
||||
2. **Derive the CSP from it** — nginx `map`/`include` of a node-written snippet, or serve the
|
||||
`/aiui/` document from the binary. Note the node's nginx self-heal reverts hand edits to
|
||||
`/etc/nginx`, so this must be node-managed, not an operator edit.
|
||||
3. **Allowlist, not wildcard**, when enabled: the node's configured relays (`wss://…`) plus the
|
||||
named enrichment hosts — never `connect-src *`, or the setting stops meaning anything.
|
||||
4. Keep the node-brokered paths screened by the existing egress guard; a widened CSP covers the
|
||||
frame's *direct* calls only.
|
||||
|
||||
Security note to carry into the plan: with the toggle on, the frame can talk to allowlisted
|
||||
third parties directly, so peer-influenced content reaching those calls is a new exfiltration
|
||||
sink (cf. 13-12's untrusted-content boundary). Default stays OFF and the owner turns it on
|
||||
knowingly — which is exactly what makes it a valid setting rather than decoration.
|
||||
|
||||
The two directions below are retained as the implementation shapes this decision picks between
|
||||
for the *brokered* half (enrichment/search), not as a live question about relays:
|
||||
|
||||
- **(a) Broker it node-side.** The frame keeps its tight CSP; the node gains explicit,
|
||||
permissioned endpoints (a relay bridge; an enrichment proxy) that AIUI calls at same-origin.
|
||||
|
||||
Reference in New Issue
Block a user