Repository navigation
Description
Problem
After afx ide install && afx ide start on a local machine, the natural next step is to open http://localhost:4100/ide/?folder=<path> in a browser. Tower answers 401. Trying the server directly at http://127.0.0.1:8200/ide/ answers 403. The only working entries today are the Codev Cloud URL (needs an owner session and a tunnel round trip) or a hand-built http://127.0.0.1:8200/ide/?tkn=<token>&folder=…, which is not a user path.
Measured 2026-10-29 on macOS with codev 3.3.6 and @cluesmith/codev-ide 1.0.0:
GET http://127.0.0.1:4100/ide/ -> 401 (bare browser navigation)
GET http://127.0.0.1:8200/ide/ -> 403 (server wants its connection token)
GET http://127.0.0.1:4100/ide/?folder=… + codev-tower-key header -> 200 text/html
Root cause
Tower's HTTP choke point (isRequestAllowed, server-utils.ts) accepts the local key only as a request header (codev-tower-key, legacy codev-web-key). The dashboard works because GET / is a public route whose HTML gets the key injected as window.__CODEV_TOWER_KEY__, and every dashboard fetch then adds the header. A top-level browser navigation to /ide/ cannot carry a header, so it never reaches the forward. The cloud path works only because the tunnel proxy stamps the header server-side on every request.
The IDE connection token is not the gap: ide-forward.ts already injects the vscode-tkn cookie on every forwarded request, cloud or local. The gap is that a local browser has no header-free way to present the Tower key, and this applies not just to the first navigation but to every workbench asset request and every ?reconnectionToken= WebSocket the workbench opens against 4100/ide/….
Proposed rule
Give a local browser a header-free credential for the /ide/ prefix that carries the same trust as the key header, without weakening either secret:
- An authenticated dashboard action (fetch with the key header) mints a session credential for the forward, delivered as an
HttpOnly; SameSite=Strict; Path=/idecookie (or sets the key itself in such a cookie). Only the Host-guarded loopback origin can obtain it, and only by already holding the key. isForwardAuthorized(the one authorization seam for the forward, HTTP and WebSocket upgrade alike) accepts that cookie as an alternative to the header.isRequestAllowedlets/ide/*through to that seam when the cookie is present. Nothing else in Tower accepts the cookie.- Add an Open IDE link per workspace on the local dashboard that performs the mint and then opens
/ide/?folder=<workspace path>in a new tab. This is the local counterpart of the cloud dashboard's Open IDE entry.
Non-goals: do not drop the server's connection token (upstream VS Code requires it on localhost for good reason); do not open /ide/ to bare loopback requests that hold neither the header nor the minted cookie; the cloud path is unchanged.
Acceptance
- On a machine with Tower and the IDE server running, the local dashboard shows an Open IDE link per workspace that opens the workbench with the Codev sidebar in a new tab, with no cloud session and no hand-built URL. The workbench's assets and its WebSocket connections all succeed through
4100/ide/. - A bare
curl http://127.0.0.1:4100/ide/still returns 401. A request with a rebound Host still fails the Host guard. - The cloud URL still works unchanged.
codev/resources/commands/agent-farm.md(and the skeleton twin) describe the Open IDE link and the local URL as the user path.
Reported by the codev-ide workspace architect from the owner's first local use of 3.3.6 + codev-ide 1.0.0. Related: #1668 (IDE prefix forward), #1789 (Tower-managed server), #1589 (per-session remote credential, the planned swap point in isForwardAuthorized).
Activity
amrmelsayed commentedon Nov 3, 2026
On it! Working on this with the PIR protocol (plan + dev-approval gates before PR).
[PIR #1869] Plan draft
[PIR #1869] Plan revised: cross-port cookie risk
[PIR #1869] Plan revised: security review M1-M4
[PIR #1869] Plan revised: security review S1-S4
[PIR #1869] Plan revised: multi-user trust wording
[PIR #1869] Forward seam accepts the /ide session cookie behind a cro…
[PIR #1869] Strip the /ide session cookie before forwarding to the ID…
[PIR #1869] Mint endpoint POST /api/ide/session, log-safe refusals, C…
[PIR #1869] Open IDE link per workspace on the Tower dashboard
[PIR #1869] Document the Open IDE path and the /ide session cookie tr…
[PIR #1869] Rotate the IDE connection token on every IDE server spawn
[PIR #1869] Route the local workbench through Tower and keep the IDE …
[PIR #1869] Log the pathname only for refused /ide requests
[PIR #1869] Plan amendment 1 and docs: workbench routing, token handl…
[PIR #1869] Thread: amendment 1 implemented
[PIR #1869] Show the IDE row first on each workspace card
[PIR #1869] Review + retrospective
[PIR #1869] Address consultation: no ACAC relay, mint waits for a liv…
[PIR #1869] Review: consultation findings and dispositions
[PIR #1869] Thread: review and consultation
[PIR #1869] Review iteration 1 rebuttals
Merge pull request #1872 from cluesmith/builder/pir-1869
amrmelsayed commentedon Nov 3, 2026
Shipped in PR #1872 (merged 2026-11-03, merge commit 20a2e8c). Local browsers reach the IDE through Tower via the Open IDE row on each workspace card; the forward accepts an origin-guarded /ide session cookie, the workbench is routed through Tower with its token injected into the page, and the IDE connection token rotates on every spawn. Security review by the security architect: APPROVE; integration review: Claude and Codex APPROVE. Follow-ups are tracked separately by the architect.
release notes: Open IDE from the local dashboard (#1869, PR #1872)
[Spec 1658] Merge main (v3.3.7, #1869 Open IDE, #1877 pid-reuse row d…
[Spec 1658] Windows tests after the main merge: #1877 start-time help…
[Spec 1658][Phase: review] fix(M7): Open IDE sends the workspace as a…