Skip to content

Commit 3091c99

Browse files
authored
Merge pull request #110 from levelcodeai/docs/web-editor-on-app-subdomain
docs(web): the editor goes on app.levelcode.ai, and a sign-in at levelcode.ai lands in it
2 parents d1abd38 + 542cdc5 commit 3091c99

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

‎docs/WEB.md‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ write), the tab's secrets ride through that one navigation in sessionStorage and
189189
and removed, when the editor starts again. The tab comes back to the address it left: a folder or
190190
workspace opened from the computer is opened again, not the scratch workspace.
191191

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:
193194
`main.js` removes the parameter, then delivers `levelcode://…/launch`, which focuses the chat and
194195
starts the sign-in only when there is no session.
195196
- **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
329330
| Variable | Meaning |
330331
| --- | --- |
331332
| `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. |
333334
| `LEVELCODE_WEB_EXTENSION_HOST_ORIGINS` | Comma list (one wildcard each) of origins the extension host runs on, when isolated. CORS only — never a callback. |
334335

335336
`GET /api/levelcode/v1/web_editor` answers `{ enabled, url }`; the account SPA shows its entry
336337
points only when it is on.
337338

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.
343348

344349
## Security model
345350

@@ -520,8 +525,8 @@ Say these out loud rather than discover them in production:
520525

521526
## Decisions that are the owner's
522527

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).
525530
2. **The webview origin.** Keep Code-OSS's CDN (no setup; a dependency on Microsoft's hosting of the
526531
published page for this build's commit) or self-host a wildcard origin.
527532
3. **Isolating the extension host.** Worth it before any third-party extension is ever allowed; not

0 commit comments

Comments
 (0)