# theta-agent on Windows — design Status: **planning / design draft**. Companion to `DESIGN.md`, which describes the Linux-first agent. This document covers bringing the agent to Windows as a first-class platform, optimized for **air-gapped** deployment: everything the host needs ships in one installer, and nothing on the target machine requires internet access. ## 1. Goals 1. **Parity, not a port.** Every capability Linux has, Windows has too: telemetry, remote operations (reboot/shutdown, service control, desktop control, arbitrary commands, logs, IAM, self-update), LDAP-backed directory logins, secrets, and a WireGuard mesh client. The capability matrix and Ed25519 signature model from `DESIGN.md` apply unchanged; only the executors change. 2. **One installer, fully offline.** A single Inno Setup `.exe` installs everything the Windows host needs — agent service, tray, credential provider, WireGuard client, runtime dependencies. No downloads at install time and no internet calls at runtime. 3. **Single outbound connection preserved.** The agent still dials one persistent WSS connection to the SSO. No inbound ports, no firewall rules. 4. **The SSO holds all resources.** The Windows installer, loose binaries, and the self-update feed are served from the SSO, mirroring the existing `/resources/theta-agent/...` tree. ## 2. Current Windows compatibility status The agent already compiles, runs, and enrolls on Windows. Validated against a live SSO (`sso.suite.vm42.us`): - `go build` for `windows/amd64` succeeds; the agent enrolls via join key, persists its issued token + the SSO's Ed25519 public key to `agent.yml`, and streams discovery / telemetry over WSS. - Unix-domain sockets work on Windows (Go ≥ 1.18, needs Win10 1803+); the LDAP byte-pump and tray IPC both bind and accept connections under the per-user temp dir. - Two unit tests assert POSIX `0600` modes that Windows does not implement; they are the only failures and are not runtime defects (`go test` gate must be made Windows-aware). ### Changes already merged - **Tray IPC socket paths are platform-aware.** Linux keeps `/run/theta/tray.sock` + `/tmp/theta-tray.sock`; Windows uses a Unix socket under the per-user temp dir (`tray_ipc.go`). The tray companion dials the same path. - **The tray no longer exits on Windows.** The `DISPLAY`/`WAYLAND_DISPLAY` graphical session guard is now non-Windows only (`cmd/theta-agent-tray/main.go`). ## 3. Process & services layout | Component | Runs as | Purpose | | :--- | :--- | :--- | | `theta-agent` | Windows service (SYSTEM, auto-start) | WSS to SSO, command dispatch, telemetry, LDAP byte-pump, loopback `/bind`, IAM, WG control | | `theta-agent-tray` | Per-user, logon autostart | Status icon, enrollment dialog, VPN control, auto-VPN | | `theta-agent-helper` (new) | Per-interactive-session, spawned by the service | Desktop controls that cannot run from session 0 | | OpenCredential CP DLL | Loaded by `LogonUI.exe` (Winlogon) | LDAP-backed Windows logon | | `WireGuardTunnel$` | Service installed by WireGuard client | Mesh tunnel | The service is the lynchpin: it is up before any user session, which is what lets the credential provider validate logins at Ctrl+Alt+Del. ## 4. Remote operations (full parity) Command dispatch, capability gating, and Ed25519 verification in `websocket.go` are platform-neutral. A `executor_windows.go` (plus a small `executor_linux.go` containing today's Linux mapping) selects the underlying implementation. | Command | Linux (today) | Windows | | :--- | :--- | :--- | | `reboot` | `reboot` | `shutdown.exe /r /t 0` | | `shutdown` | `shutdown -h now` / `poweroff` | `shutdown.exe /s /t 0` | | `service_restart` | `systemctl restart ` | `sc.exe stop/start ` (allowed-list unchanged) | | `systemd_action` | `systemctl ` | `sc.exe `; `status` → `sc.exe query` | | `arbitrary_bash` | `bash -c