clone

a self-hosted sync node for lofi apps: jazz sync over iroh, ticket-gated, with no static ip or cloud needed

docs: state ticket custody as the app actually ships it

Dami committed 7286978
hosting-lofi-apps described the pasted ticket as passkey-encrypted in
localStorage — the intended contract stated as fact. The shipped
behavior: sync tickets persist as a sealed record under a device-bound
key; provision tickets split through the scope-down exchange, with the
provision original passkey-sealed or memory-only and the password
manager holding the durable copy.

Part of FelineStateMachine/lofi#123 (D §4).
commit
728697890b3df904b2e89493900b18c84706aefa
parent
24706fa75783c06501f68cc8500a1c8b794b67b7
author
Dami <dami.etoile@gmail.com>
1 file changed, +9 -4
Mdocs/hosting-lofi-apps.md13+++++++++----
M docs/hosting-lofi-apps.md +9 -4
@@ -36,9 +36,12 @@ lofi-node ticket list --dir ./data
3636 lofi-node ticket revoke <id> --dir ./data # live sockets close with 40013737 ```3838 39-The user pastes the ticket into their lofi app; the app stores it passkey-encrypted in localStorage40-and uses the ticket's URL as its sync server. Format and app-side flow:41-[app-ticket.md](app-ticket.md).39+The user pastes the ticket into their lofi app (tell them to let their password manager save it —40+the secret is shown once and the node keeps only a hash). The app never stores a ticket in41+cleartext: a sync ticket persists as a sealed record under a device-bound key and its URL becomes42+the sync server; a provision ticket is split first through the scope-down exchange — the app stores43+a derived sync ticket and keeps the provision original passkey-sealed or memory-only. Format and44+app-side flow: [app-ticket.md](app-ticket.md).4245 4346 ## 2. Get the app's schema into the store4447
@@ -46,7 +49,9 @@ A store with no deployed schema is unusable — client writes hang (preflight wi
4649 `GET <ticket.url>/store-status`, see [app-ticket.md](app-ticket.md)). Two paths publish a schema:4750 4851 **Primary — runtime provisioning via a provision ticket** (the lofi#109 opt-in flow): issue49-`lofi-node ticket issue --provision --label app-setup` and hand it to the app. The app (or any52+`lofi-node ticket issue --provision --label app-setup` and hand it to the app. On enrollment the app53+splits it through the scope-down exchange (everyday transport rides a derived sync ticket; admin54+capability unlocks through a passkey ceremony when provisioning actually runs). The app (or any5055 jazz-tools `deploy` caller) uses the ticket URL as `serverUrl` with a placeholder admin secret — the5156 gate strips inbound admin headers and injects the node's own for provision-scoped requests, so the5257 real secret never leaves the node. Slice-by-slice merge deploys (`createTables` migrations, union