* feat(desktop): add Electron shell lifecycle Signed-off-by: QCYTSN <2558348385@qq.com> * docs(desktop): document shell security boundary Signed-off-by: QCYTSN <2558348385@qq.com> * fix(desktop): address shell lifecycle review Signed-off-by: QCYTSN <2558348385@qq.com> * fix(desktop): constrain backend executable resolution Signed-off-by: QCYTSN <2558348385@qq.com> --------- Signed-off-by: QCYTSN <2558348385@qq.com>
6.1 KiB
6.1 KiB
Desktop Process-Boundary Threat Model
Scope
This document covers the Electron main process, its sandboxed renderer, and the single Vibe-Trading Python process started by the shell. Packaging, credential storage, auto-update, optional messaging adapters, broker configuration, and code signing are outside this change.
Assets
- The per-launch API authentication secret.
- Local Vibe-Trading sessions, reports, configuration, and research data.
- Any credentials already present in the environment inherited by the Python process.
- The integrity of the executable selected as the backend.
- The ability to invoke authenticated local API routes.
Trust boundaries
Electron main process
|-- owns random API secret
|-- selects backend executable and starts watchdog
|-- injects Authorization on one loopback origin
|
+--> sandboxed renderer
| no Node.js, isolated context, deny-by-default permissions
| can use the authenticated local API through normal page requests
|
+--> backend parent-death watchdog
|-- inherits the launch secret only to pass it to Python
|-- exits without spawning Python if the parent is already gone
|-- monitors Electron IPC disconnect and parent PID liveness
+--> Python backend
binds 127.0.0.1:<random-port>
receives API_AUTH_KEY through its child environment
The renderer is trusted to perform the same application actions as the web UI, but it is not given the raw authentication secret. A renderer compromise can still call authenticated API routes through the Electron session and is therefore security-significant.
Controls
Loopback and authentication
- The backend is launched with
--host 127.0.0.1. - A free ephemeral port is selected for every backend start.
- The secret is 32 cryptographically random bytes encoded with Base64URL.
- The secret exists only in Electron main-process memory and the owned watchdog/Python child environments. It is not written to logs, configuration, or renderer storage.
- Electron adds
Authorization: Bearer <secret>only when the request origin exactly matches the active backend origin. - Health and shutdown requests are authenticated.
- A new desktop process receives a new secret, so any stale value is invalid after exit.
Renderer
nodeIntegrationis disabled.contextIsolationand Chromium sandboxing are enabled.- The preload exposes only status, error, retry, log-folder, and backend-restart operations.
- Browser permission checks and requests are denied by default.
- New windows are denied; safe HTTP(S) links are opened in the system browser.
- In-window navigation is restricted to the active local backend origin.
- Developer tools are unavailable when Electron reports a packaged build.
- Renderer traffic uses an isolated persistent Electron partition rather than the default browser session.
Backend executable resolution
VIBE_TRADING_EXECUTABLE, when it names an existing file, is an explicit operator override and takes precedence.- Packaged-runtime discovery checks only exact paths anchored to Electron's
application and resources directories, including fixed
appandresourcessubtrees. It does not walk their ancestors. - Source-mode discovery is disabled for packaged applications. During source
development, an ancestor is accepted only when its
pyproject.tomlcontains[project].name = "vibe-trading-ai"; only that marked root's.venv\Scripts\vibe-trading.exeis eligible. - The final fallback checks non-empty
PATHentries forvibe-trading.exe. - No generic executable candidate is evaluated while walking ancestors, and the filesystem drive root is never treated as a source-project root.
Process lifecycle
- Only one desktop application instance is allowed.
- Standard output and standard error are appended to a per-user Electron log.
- Startup waits for authenticated health success and reports early process exit with a bounded log tail.
- Electron starts a small watchdog before the Python backend. The watchdog verifies that the Electron main PID is alive before spawning Python.
- The watchdog retains an IPC channel to Electron and also polls the exact
parent PID. An IPC disconnect or dead parent PID triggers Windows
taskkill /T /Fagainst the Python process tree without relying on an Electron JavaScript shutdown callback. - Normal shutdown first calls the authenticated backend shutdown route. If the backend remains alive, Electron asks the watchdog to terminate it and finally retains process-tree termination as a bounded fallback.
- The automated parent-death smoke test terminates only the Electron main PID, then independently verifies that both the Python PID and loopback listener are gone.
Residual risks
- Renderer script injection can exercise the authenticated API even though it cannot read the raw secret.
- A local administrator, debugger, or process with equivalent user privileges may inspect the Electron, watchdog, or Python process and its environment.
- Port discovery closes the probe socket before Python binds it. Another local process can win that race, causing startup failure; it does not receive the authentication secret.
- The development override
VIBE_TRADING_EXECUTABLEtrusts the explicitly selected executable. Users must not point it at untrusted code. - The
PATHfallback trusts the desktop process environment and normal Windows executable-path integrity. A process able to alter that environment can select the backend that receives the launch secret. - The child inherits the desktop process environment. Secure credential isolation is deferred to the packaging/credential-storage review.
- Forceful tree termination can interrupt in-progress local work after the graceful shutdown timeout.
- This source-only change does not provide code signing, installer reputation, update authenticity, or an official HKUDS release channel.
Non-goals
- Protecting against a fully compromised Windows account or administrator.
- Enabling remote API access.
- Managing broker, exchange, IM, or model-provider credentials.
- Installing or updating the application.