You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3091c99
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/WEB.md
+14-9Lines changed: 14 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -189,7 +189,8 @@ write), the tab's secrets ride through that one navigation in sessionStorage and
189
189
and removed, when the editor starts again. The tab comes back to the address it left: a folder or
190
190
workspace opened from the computer is opened again, not the scratch workspace.
191
191
192
-
-**`?signin=1`** (the account site's "Open LevelCode" link) makes step 1 happen by itself, once:
192
+
-**`?signin=1`** (the account site's "Open LevelCode" link, and where a sign-in on the account site
193
+
lands while the web edition is on) makes step 1 happen by itself, once:
193
194
`main.js` removes the parameter, then delivers `levelcode://…/launch`, which focuses the chat and
194
195
starts the sign-in only when there is no session.
195
196
-**A result is delivered only if it is fresh** (written in the last two minutes — the one-time
@@ -329,17 +330,21 @@ Three settings on the Rails app (all default **off**; with none set nothing chan
329
330
| Variable | Meaning |
330
331
| --- | --- |
331
332
|`LEVELCODE_WEB_EDITOR_ORIGINS`| Comma list of origins the editor is served from, exactly (`https://editor.example.com`). A sign-in code is only ever sent to `<origin>/callback.html` with the right parameters. Also the CORS list. |
332
-
|`LEVELCODE_WEB_EDITOR_URL`| Where the account site's "Open LevelCode" goes: one of those origins and, optionally, a path. |
333
+
|`LEVELCODE_WEB_EDITOR_URL`| Where the account site's "Open LevelCode" goes, and where a sign-in on the account site lands (with `?signin=1`; a `next` page the visitor asked for wins): one of those origins and, optionally, a path. |
333
334
|`LEVELCODE_WEB_EXTENSION_HOST_ORIGINS`| Comma list (one wildcard each) of origins the extension host runs on, when isolated. CORS only — never a callback. |
334
335
335
336
`GET /api/levelcode/v1/web_editor` answers `{ enabled, url }`; the account SPA shows its entry
336
337
points only when it is on.
337
338
338
-
**Do not host the editor on a subdomain of the account host.** The account session cookie is
339
-
`SameSite=Lax`, which is a site boundary, not an origin one: it is sent on a request from a sibling
340
-
subdomain, and the API takes that cookie when there is no bearer token. A page that runs other
341
-
people's extensions there could cause credentialed requests (CORS stops it *reading* the answer, not
342
-
causing the effect). Use another registrable domain.
339
+
**On a subdomain of the account host — `app.levelcode.ai` — and why that is safe now.** The account
340
+
session cookie is `SameSite=Lax`, which is a site boundary, not an origin one: it is sent on a request
341
+
from a sibling subdomain. The API takes it only from the account site's own pages (`Sec-Fetch-Site:
342
+
same-origin`, systemu-net/thin.ly#454), and the `/ai/*` writes carry Rails' CSRF token, so the
343
+
editor's page cannot spend the account's session; it uses its own bearer token, as the desktop does.
344
+
**Deploy that backend before** setting the variables above for a subdomain. What a subdomain can
345
+
still do that another domain cannot: set a cookie for the parent domain (a `__Host-` session cookie
346
+
would refuse it — not done), and run whatever the page runs — LevelCode's own code only. Before the
347
+
page runs anyone else's, put the extension host on another registrable domain.
343
348
344
349
## Security model
345
350
@@ -520,8 +525,8 @@ Say these out loud rather than discover them in production:
520
525
521
526
## Decisions that are the owner's
522
527
523
-
1.**The editor's domain.**Not a subdomain of the account host (see Deploying). Which registrable
524
-
domain, and who holds it.
528
+
1.**The editor's domain.***Decided 2026-10-17:*`app.levelcode.ai`, and a sign-in at levelcode.ai
529
+
lands there (systemu-net/thin.ly#454). Open: the `__Host-` session cookie (see Deploying).
525
530
2.**The webview origin.** Keep Code-OSS's CDN (no setup; a dependency on Microsoft's hosting of the
526
531
published page for this build's commit) or self-host a wildcard origin.
527
532
3.**Isolating the extension host.** Worth it before any third-party extension is ever allowed; not
0 commit comments