Summary
Give the guardian edge an HTTPS story and a CORS allowlist so remote clients (the hosted PWA at the official URL, and any phone) can connect. This is Phase 6.5 of docs/technical/ui-runtime-modes-plan.md and a hard prerequisite for the mobile half of #511.
Why this is unavoidable (platform rules, not our code)
- Secure context: a PWA installs only over HTTPS or from
localhost. Plain HTTP on a LAN IP is never installable.
- Mixed content: an HTTPS origin (the hosted client) cannot
fetch() a plain-HTTP guardian. So every phone → guardian connection needs TLS, regardless of where the client was installed from.
- The desktop/localhost install path needs none of this — a
http://127.0.0.1 origin is a secure context and may call plain-HTTP LAN guardians (loopback is the most-trusted Private Network Access tier). That's why it's the zero-setup default and this issue only gates the remote/phone story.
Today there is no TLS anywhere in the stack (verified: no caddy/tls references in packages/skeleton/system/stack/ or containers/) and guardian sends no CORS headers.
Simplicity guardrail (from the ratified plan, §8 rule 11)
TLS is never a manual user task on default paths. Explicit non-goal: asking non-technical users to install a private CA on iOS/Android (mkcert-style). The chosen flows must be guided.
Scope
Non-goals
- No change to the loopback-default posture: guardian stays LAN-dark unless explicitly exposed (
OP_BIND_ADDRESS policy unchanged)
- No public-internet exposure guidance beyond the Tailscale/Caddy paths
Related
Summary
Give the guardian edge an HTTPS story and a CORS allowlist so remote clients (the hosted PWA at the official URL, and any phone) can connect. This is Phase 6.5 of
docs/technical/ui-runtime-modes-plan.mdand a hard prerequisite for the mobile half of #511.Why this is unavoidable (platform rules, not our code)
localhost. Plain HTTP on a LAN IP is never installable.fetch()a plain-HTTP guardian. So every phone → guardian connection needs TLS, regardless of where the client was installed from.http://127.0.0.1origin is a secure context and may call plain-HTTP LAN guardians (loopback is the most-trusted Private Network Access tier). That's why it's the zero-setup default and this issue only gates the remote/phone story.Today there is no TLS anywhere in the stack (verified: no caddy/tls references in
packages/skeleton/system/stack/orcontainers/) and guardian sends no CORS headers.Simplicity guardrail (from the ratified plan, §8 rule 11)
TLS is never a manual user task on default paths. Explicit non-goal: asking non-technical users to install a private CA on iOS/Android (mkcert-style). The chosen flows must be guided.
Scope
ts.netname with a real Let's Encrypt cert — no cert management for the userapp.openpalm.dev) baked in, additional origins configurable; enforced testsrequiresHttpsForRemoteConnectionsenforced client-side too: the hosted client refuses plain-HTTP non-loopback targets with an actionable message deep-linking to the TLS guideNon-goals
OP_BIND_ADDRESSpolicy unchanged)Related
docs/technical/ui-runtime-modes-plan.md— Phase 6.5, §6.10docs/technical/ui-client-split-assessment.md— evidence §4 (secure context, mixed content, PNA)