From eb5ba11f672977b7368c67204beddb232eb4a745 Mon Sep 17 00:00:00 2001 From: Nicole Rappe Date: Sun, 11 Jan 2026 22:33:49 -0700 Subject: [PATCH] Tunnel-Related Codex Docs Removed --- .../src/Devices/ReverseTunnel/Powershell.jsx | 54 +++++- Docs/Codex/REVERSE_TUNNEL_PROMPT.md | 97 ---------- Docs/Codex/Remote_Shell_UI_Changes.md | 41 +++++ Docs/Codex/Reverse_VPN_Tunnel_Deployment.md | 165 ------------------ 4 files changed, 91 insertions(+), 266 deletions(-) delete mode 100644 Docs/Codex/REVERSE_TUNNEL_PROMPT.md create mode 100644 Docs/Codex/Remote_Shell_UI_Changes.md delete mode 100644 Docs/Codex/Reverse_VPN_Tunnel_Deployment.md diff --git a/Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx b/Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx index 3c6d33a0..b311ce55 100644 --- a/Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx +++ b/Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx @@ -133,6 +133,32 @@ export default function ReverseTunnelPowershell({ device }) { return socket; }, []); + const notifyAgentOnboarding = useCallback(async () => { + try { + await fetch("/api/notifications/notify", { + method: "POST", + headers: { "Content-Type": "application/json" }, + credentials: "include", + body: JSON.stringify({ + title: "Agent Onboarding Underway", + message: + "Please wait for the agent to finish onboarding into Borealis. It takes about 1 minute to finish the process.", + icon: "info", + variant: "info", + }), + }); + } catch { + /* ignore notification transport errors */ + } + }, []); + + const handleAgentOnboarding = useCallback(async () => { + await notifyAgentOnboarding(); + setStatusMessage("Agent Onboarding Underway."); + setSessionState("idle"); + setShellState("idle"); + }, [notifyAgentOnboarding]); + const appendOutput = useCallback((text) => { if (!text) return; setOutput((prev) => { @@ -234,9 +260,22 @@ export default function ReverseTunnelPowershell({ device }) { } setLoading(true); setStatusMessage(""); - setSessionState("connecting"); - setShellState("opening"); try { + try { + const readinessResp = await fetch( + `/api/tunnel/status?agent_id=${encodeURIComponent(agentId)}` + ); + const readinessData = await readinessResp.json().catch(() => ({})); + if (readinessResp.ok && readinessData?.agent_socket === false) { + await handleAgentOnboarding(); + return; + } + } catch { + // best-effort readiness check + } + + setSessionState("connecting"); + setShellState("opening"); const resp = await fetch("/api/tunnel/connect", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -284,6 +323,10 @@ export default function ReverseTunnelPowershell({ device }) { if (!openResp?.error) { return openResp; } + if (openResp.error === "agent_socket_missing") { + await handleAgentOnboarding(); + return null; + } lastError = openResp.error; setStatusMessage(`Waiting for PowerShell shell (${attempt})...`); await sleep(2000); @@ -291,7 +334,10 @@ export default function ReverseTunnelPowershell({ device }) { throw new Error(lastError || "shell_connect_failed"); }; - await openShellWithRetry(); + const opened = await openShellWithRetry(); + if (!opened) { + return; + } setStatusMessage(""); setSessionState("connected"); setShellState("connected"); @@ -302,7 +348,7 @@ export default function ReverseTunnelPowershell({ device }) { } finally { setLoading(false); } - }, [agentId, ensureSocket]); + }, [agentId, ensureSocket, handleAgentOnboarding]); const handleSend = useCallback( async (text) => { diff --git a/Docs/Codex/REVERSE_TUNNEL_PROMPT.md b/Docs/Codex/REVERSE_TUNNEL_PROMPT.md deleted file mode 100644 index 7a245151..00000000 --- a/Docs/Codex/REVERSE_TUNNEL_PROMPT.md +++ /dev/null @@ -1,97 +0,0 @@ -# Borealis Reverse VPN Tunnel Work — Handoff Prompt - -You are resuming work on Borealis' WireGuard-based reverse VPN tunnel migration in -`d:\Github\Borealis`. You should assume no prior context. Start by reading `AGENTS.md` -and these docs (order matters): - -- `Docs/Codex/BOREALIS_AGENT.md` -- `Docs/Codex/BOREALIS_ENGINE.md` -- `Docs/Codex/SHARED.md` -- `Docs/Codex/USER_INTERFACE.md` -- `Docs/Codex/Reverse_VPN_Tunnel_Deployment.md` - -Do not implement Linux yet. - -## Current Status (What Is Working) - -- WireGuard tunnel comes up and the PowerShell VPN shell connects successfully. -- Agent log confirms: start request received, client config rendered, session started, - and a shell connection accepted from `10.255.0.2`. -- Engine log shows WireGuard listener installed, firewall rules applied, device - activity started. - -## Key Fixes Already Applied - -1) Port conflict fix - - Default VPN shell port changed from `47001` to `47002`. - - Updated in: - - `Data/Engine/config.py` - - `Data/Agent/Roles/role_VpnShell.py` - - `Data/Engine/web-interface/src/Devices/Device_Details.jsx` - - `Docs/Codex/REVERSE_TUNNELS.md` - -2) Agent role load/import failures resolved - - WireGuard role was failing to load due to `signature_utils` import path and a - dataclass crash. - - Added `sys.path` insertions in role manager to make helpers importable: - - `Data/Agent/role_manager.py` - - `Agent/Borealis/role_manager.py` - - Added fallback import in WireGuard role: - - `Data/Agent/Roles/role_WireGuardTunnel.py` - - `Agent/Borealis/Roles/role_WireGuardTunnel.py` - - Replaced `@dataclass SessionConfig` with a plain class in both roles to avoid - `AttributeError: 'NoneType' object has no attribute '__dict__'`. - -3) VPN shell read-loop noise suppressed - - The engine threw `TimeoutError` on idle shell reads; now handled cleanly. - - Updated in `Data/Engine/services/WebSocket/vpn_shell.py`: - - `tcp.settimeout(15)` - - Catch `socket.timeout` and `TimeoutError` and exit loop cleanly. - -## Logs to Know - -- Agent: `Agent/Logs/VPN_Tunnel/tunnel.log` (tunnel lifecycle) and `Agent/Logs/VPN_Tunnel/remote_shell.log` (shell I/O). -- Engine: `Engine/Logs/VPN_Tunnel/tunnel.log`, `Engine/Logs/VPN_Tunnel/remote_shell.log`, `Engine/Logs/engine.log`. - -## What Likely Remains - -- Ensure Section 7 (End-to-End Validation) in - `Docs/Codex/Reverse_VPN_Tunnel_Deployment.md` has accurate `[x]` checkboxes for - completed tests. -- Confirm UI/PowerShell web terminal behaves as expected (live output, disconnect - cleanup, idle timeout). -- Validate no legacy tunnel references remain (if any cleanup missing). -- Update docs/checklists if any step is now complete or needs clarification. - -## Important File Paths Touched - -- `Data/Engine/config.py` -- `Data/Agent/Roles/role_VpnShell.py` -- `Data/Agent/Roles/role_WireGuardTunnel.py` -- `Agent/Borealis/Roles/role_WireGuardTunnel.py` -- `Data/Agent/role_manager.py` -- `Agent/Borealis/role_manager.py` -- `Data/Engine/web-interface/src/Devices/Device_Details.jsx` -- `Docs/Codex/REVERSE_TUNNELS.md` -- `Data/Engine/services/WebSocket/vpn_shell.py` - -## Environment Notes - -- Shell: PowerShell -- `approval_policy=never` (do not request escalations) -- `sandbox_mode=danger-full-access` - -## Suggested Verification Steps - -- Re-run UI PowerShell connect and confirm live terminal works. -- Check agent log for: - - `WireGuard start request received` - - `WireGuard client session started` - - `Accepted shell connection from 10.255.0.2` -- Check engine log for: - - `WireGuard listener installed` - - No `Failed to connect vpn shell` warnings - - No `TimeoutError` stack trace after the read-loop fix. - -When you continue, keep `Data/Agent` and `Agent/Borealis` copies in sync where -appropriate. diff --git a/Docs/Codex/Remote_Shell_UI_Changes.md b/Docs/Codex/Remote_Shell_UI_Changes.md new file mode 100644 index 00000000..f0ae2648 --- /dev/null +++ b/Docs/Codex/Remote_Shell_UI_Changes.md @@ -0,0 +1,41 @@ +# Remote Shell UI Changes Handoff + +You are a new ChatGPT Codex agent working in `d:\Github\Borealis`. Start by reading +`AGENTS.md`, then follow the doc chain it specifies. Also read +`Docs/Codex/TOAST_NOTIFICATIONS.md` to implement toast notifications correctly. + +## Current Situation +- The WireGuard tunnel and Remote Shell work once the agent SYSTEM socket is online. +- If the operator clicks **Connect** too early, the UI shows `agent_socket_missing` + and no toast appears. +- Goal: prevent the Remote Shell connect attempt until the agent is actually ready, + and show a toast notification if the operator clicks too early. + +## Required Behavior +- When the agent SYSTEM socket is not registered, the UI must block the connection + attempt, show a toast via `/api/notifications/notify`, and keep the UI idle + (no tunnel/session attempt). +- Toast title: `Agent Onboarding Underway` +- Toast message: + `Please wait for the agent to finish onboarding into Borealis. It takes about 1 minute to finish the process.` + +## Important References +- `Docs/Codex/TOAST_NOTIFICATIONS.md` (toast API path, payload schema, auth, Socket.IO event) +- `AGENTS.md` (instructions and precedence) +- UI file: `Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx` +- API status endpoint: `/api/tunnel/status` returns `agent_socket` when available +- Socket error path: `agent_socket_missing` + +## Troubleshooting Context +- Engine logs show `vpn_shell_open_failed ... reason=agent_socket_missing` when the + SYSTEM socket is not connected. +- Toasts do not appear; likely causes: WebUI build is reused (`Existing WebUI build found`) + or the UI error path doesn't trigger the toast. +- Ensure the toast is sent via `/api/notifications/notify` with `credentials: "include"` + and the payload schema from `TOAST_NOTIFICATIONS.md`. + +## Deliverables +- Update UI logic to call the notification API and block the connection attempt until + readiness is confirmed. +- Cover both preflight status checks and the `agent_socket_missing` shell open response. +- Provide explicit rebuild/restart steps if the WebUI build must be refreshed. diff --git a/Docs/Codex/Reverse_VPN_Tunnel_Deployment.md b/Docs/Codex/Reverse_VPN_Tunnel_Deployment.md deleted file mode 100644 index d7537fd4..00000000 --- a/Docs/Codex/Reverse_VPN_Tunnel_Deployment.md +++ /dev/null @@ -1,165 +0,0 @@ -# Reverse VPN Tunnel Deployment Plan (WireGuard/UDP) – Windows First - -Use this checklist to rebuild Borealis reverse tunnels as a WireGuard-based, host-only, single-tunnel-per-agent system. This is written for a Codex agent who will implement the migration; the operator expects milestone checkpoints and commits. Read `AGENTS.md` and `Docs/Codex/REVERSE_TUNNELS.md` first to understand the current stack you are replacing. **Implement Windows first. Do not implement Linux yet; see the separate Linux section for later execution.** - -## Context: Why this change -- Current tunnels: WebSocket/TLS framing, domain lanes (2/1/2), per-protocol handlers, custom leases, idle/grace timers. -- Desired state: one outbound WireGuard/UDP tunnel per agent, host-only reachability, multiplex any protocol (RDP, WinRM/PS, SSH, VNC/WebRTC, etc.) over a single VPN session. No legacy domains/limits, no fallback to WebSocket tunnels. -- Constraints: UDP is available (operators can open firewall). Use UDP port **30000** for the VPN server (not 443). Outbound-only from agents, idle timeout 15 minutes, no grace period, immediate teardown on operator exit/stop. Client-to-client disallowed; only engine↔agent virtual /32. -- Packaging: Admin rights available. Standardize on WireGuard with the official Windows driver/client. The adapter installs at agent bootstrap and persists; sessions are ephemeral and started on demand. -- Keys/Certs: Prefer reusing existing Engine/Agent certificate infrastructure for orchestration token signing/validation. WireGuard still needs its own keypairs; if reuse paths are impossible, store VPN server keys under `Engine/Certificates/VPN_Server` and client keys under `Agent/Borealis/Certificates/VPN_Client`. - -## High-Level Outcomes (Windows first) -- Engine runs a WireGuard listener on UDP port 30000 (dedicated). -- One live VPN tunnel per agent enforced server-side; multiple operators piggyback on the same tunnel. -- Engine issues short-lived session material (token + client config + ephemeral or pre-provisioned keys) per connect request; server rejects clients without a fresh orchestration token. -- Host-only routing: assign per-agent /32; AllowedIPs limited to the agent /32; no LAN routes. Engine firewall/ACL blocks client-to-client and can restrict engine→agent ports per device defaults and operator overrides. -- APIs: `/api/tunnel/connect`, `/api/tunnel/status`, `/api/tunnel/disconnect`. Agent receives start/stop signals analogous to current `reverse_tunnel_start/stop`. -- Logging and audit stay in place (use `Engine/Logs/VPN_Tunnel/tunnel.log` and `Agent/Logs/VPN_Tunnel/tunnel.log` consistently for tunnel lifecycle). -- UI: `Data/Engine/web-interface/src/Devices/Device_Details.jsx` gets an “Advanced Config” tab for per-agent allowed ports; `Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx` is reused for a live PowerShell MVP wired to the new APIs. - -## Milestone Checkpoints (commit names, Windows first) -- Milestone: Dependencies & Bootstrap (Windows) -- Milestone: Engine VPN Server & ACLs (Windows) -- Milestone: Agent VPN Client & Lifecycle (Windows) -- Milestone: API & Service Orchestration (Windows) -- Milestone: UI Advanced Config & Operator Flow (Windows, PowerShell MVP) -- Milestone: Legacy Tunnel Removal & Cleanup (Windows) -- Milestone: End-to-End Validation (Windows) - -At each milestone: pause, run the listed checks, talk to the operator, and commit with the milestone name. - -## Detailed Steps — Windows Implementation - -### 1) Dependencies & Bootstrap — Milestone: Dependencies & Bootstrap (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- WireGuard packaging: - - [x] Bundle official WireGuard for Windows (driver + client). - - [x] Download installers into `Dependencies/VPN_Tunnel_Adapter/` and keep them there (no deletion) for ad-hoc reinstalls. -- Update `Borealis.ps1`: - - [x] Install/verify WireGuard driver/client idempotently with admin rights. - - [x] Log to `Agent/Logs/install.log`. - - [x] Do not start any tunnel yet. -- Linux: do nothing yet (see later section). -- Checkpoint tests: - - [x] WireGuard binaries available in agent runtime. - - [x] WireGuard driver installed and visible. - -### 2) Engine VPN Server & ACLs — Milestone: Engine VPN Server & ACLs (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- Configure WireGuard listener on UDP port 30000; bind only on engine host. [x] -- Server config: - - [x] Assign per-agent virtual IP (/32). Use AllowedIPs to restrict each peer to its /32. - - [x] Disable client-to-client by not including other peers’ networks in AllowedIPs. - - [x] Do not push DNS or LAN routes; host-only reachability engine IP ↔ agent virtual /32. -- ACL layer: - - [x] Default allowlist per agent derived from OS (Windows: RDP 3389, WinRM 5985/5986, PS remoting ports; include VNC/WebRTC defaults as desired). - - [x] Allow operator overrides per agent; enforce at engine firewall layer. -- Keys/Certs: - - [x] Prefer reusing existing Engine cert infrastructure for signing orchestration tokens. Generate WireGuard server key and store it; if reuse paths are impossible, place under `Engine/Certificates/VPN_Server`. - - [x] Session token binding: require fresh orchestration token (tunnel_id/agent_id/expiry) validated before accepting a peer (e.g., via pre-shared keys or control-plane validation before adding peer). -- Logging: server logs to `Engine/Logs/VPN_Tunnel/tunnel.log` (or renamed consistently); shell I/O to `Engine/Logs/VPN_Tunnel/remote_shell.log`. [x] -- Checkpoint tests: - - [x] Engine starts WireGuard listener locally on 30000. - - [x] Only engine IP reachable; client-to-client blocked. - - [x] Peers without valid token/key are rejected. - -### 3) Agent VPN Client & Lifecycle — Milestone: Agent VPN Client & Lifecycle (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- Agent config template: - - [x] Outbound UDP to engine:30000. - - [x] No DNS/routing changes beyond the /32 to engine. - - [x] Adapter persists; sessions start/stop on demand. -- Lifecycle in agent role (replace legacy reverse tunnel role): - - [x] Receive connect request, fetch session token + WG peer config (keys, endpoint, allowed IPs), start WireGuard. - - [x] Enforce single session per agent; reject/dismiss concurrent starts. - - [x] Idle timeout: 15 minutes of no operator activity triggers disconnect. No grace period; operator disconnect triggers immediate stop. - - [x] Stop path: remove peer/bring interface down cleanly; adapter remains installed. -- Keys/Certs: - - [x] Prefer reusing existing Agent cert infrastructure for token validation; generate WG client key per agent. If reuse paths are impossible, store under `Agent/Borealis/Certificates/VPN_Client`. -- Logging: `Agent/Logs/VPN_Tunnel/tunnel.log` captures connect/disconnect/errors/idle timeouts; shell I/O to `Agent/Logs/VPN_Tunnel/remote_shell.log`. [x] -- Checkpoint tests: - - [x] Manual connect/disconnect against engine test server. - - [x] Idle timeout fires at ~15 minutes of inactivity. - -### 4) API & Service Orchestration — Milestone: API & Service Orchestration (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- [x] Replace legacy tunnel APIs with: - - [x] `POST /api/tunnel/connect` → tunnel_id, token, WG client config (keys, endpoint, allowed IPs), virtual IP, idle_seconds (900). - - [x] `GET /api/tunnel/status` → up/down, virtual IP, connected operators. - - [x] `DELETE /api/tunnel/disconnect` → immediate teardown and lease release. -- [x] Engine orchestrator: - - [x] Manages single tunnel per agent; tracks tunnel_id, virtual IP, token expiry. - - [x] Emits start/stop signals to agent (rename events as needed). - - [x] Cleans peer/routing state on stop. -- [x] Token issuance: short-lived, binds agent_id/tunnel_id/port/expiry; validated before adding peer. -- [x] Remove domain limits; remove channel/protocol handler registry for tunnels. -- Checkpoint tests: - - [x] API happy path: connect → status → disconnect. - - [x] Second connect reuses the active tunnel (no duplicate sessions). - -### 5) UI Advanced Config & Operator Flow (PowerShell MVP) — Milestone: UI Advanced Config & Operator Flow (Windows, PowerShell MVP) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- [x] In `Data/Engine/web-interface/src/Devices/Device_Details.jsx`, add “Advanced Config” tab: - - [x] “Reverse VPN Tunnel - Allowed Ports” with toggles per protocol. - - [x] Defaults by OS (Windows: RDP/WinRM/PS; All: VNC/WebRTC; allow operator overrides). -- [x] PowerShell MVP: - - [x] Reuse `Data/Engine/web-interface/src/Devices/ReverseTunnel/Powershell.jsx` as the base UI. - - [x] Rewire to new APIs and virtual IP flow. - - [x] Keep live web terminal behavior (WebSocket or equivalent) so operator input streams to remote PowerShell and outputs stream back in real time over the VPN tunnel. - - [x] Ensure tunnel is up via `/api/tunnel/connect/status` before opening the terminal; call `/api/tunnel/disconnect` on exit/tab close. -- Later protocols (RDP/SSH/etc.) can follow once MVP is proven, but do not block on them for this milestone. -- Checkpoint tests: - - [x] UI can start a tunnel, launch PowerShell terminal, send commands, receive live output, and tear down. - - [x] Toggles change ACL behavior (engine→agent reachability) as expected. - -### 6) Legacy Tunnel Removal & Cleanup — Milestone: Legacy Tunnel Removal & Cleanup (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- [x] Remove/retire: - - [x] Engine `reverse_tunnel_orchestrator` and domain handlers under `Data/Engine/services/WebSocket/Agent/Reverse_Tunnels/`. - - [x] Agent `role_ReverseTunnel.py` and protocol handlers. - - [x] WebUI components tied to the old Socket.IO tunnel namespace. -- [x] Update docs and references to point to the new WireGuard VPN flow; keep change log entries. -- [x] Ensure no lingering domain limits/config knobs remain. -- Checkpoint tests: - - [x] Codebase builds/starts without references to legacy tunnel modules. - - [x] UI no longer calls old APIs or Socket.IO tunnel namespace. - -### 7) End-to-End Validation — Milestone: End-to-End Validation (Windows) -- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise). -- Functional: - - [x] Windows agent: WireGuard connect on port 30000; PowerShell MVP fully live in the web terminal; RDP/WinRM reachable over tunnel as configured. - - [x] Idle timeout at 15 minutes of inactivity. - - [x] Operator disconnect stops tunnel immediately. -- Security: - - [x] Client-to-client blocked. - - [x] Only engine IP reachable; per-agent ACL enforces allowed ports. - - [x] Token enforcement blocks stale/unauthorized sessions. -- Resilience: - - [x] Restart engine: WireGuard server starts; no orphaned routes. - - [x] Restart agent: adapter persists; tunnel stays down until requested. -- Logging/audit: - - [x] Connect/disconnect/idle/stop reasons recorded in `VPN_Tunnel/tunnel.log` (Engine/Agent) and Device Activity; shell I/O recorded in `VPN_Tunnel/remote_shell.log`. -- Checkpoint tests: - - [x] Run the above matrix; gather logs for operator review before final commit. - -## Linux (Deferred) — Do Not Implement Yet -- When greenlit, mirror the structure above for Linux: - - WireGuard (kernel module preferred) on UDP 30000; userspace fallback if needed. - - Per-agent keys; reuse cert infrastructure for token signing/validation if possible; otherwise dedicated `Engine/Certificates/VPN_Server` and `Agent/Borealis/Certificates/VPN_Client`. - - Same APIs/UI, same idle/teardown semantics. - - Validate SSH/Bash over tunnel for Linux devices. -- Add new milestones for Linux when the operator approves. - -## Cautions and Gotchas -- Use UDP 30000 for WireGuard; do not use 443. -- Ensure WireGuard driver install is robust and idempotent; keep installers in `Dependencies/VPN_Tunnel_Adapter/`. -- Idle enforcement must be tied to operator activity, not just socket liveness—ensure operator-side clients signal activity. -- Keep adapters installed but sessions ephemeral; stop path must tear down the tunnel without removing the driver. -- Preserve logging paths and headers per domain docs. -- Do not leave any legacy domain-limit logic or protocol-channel framing in the new stack. -- Be explicit about token validation before adding peers to the WireGuard interface. - -## Operator Check-Ins -- After each milestone, present: what changed, tests run/results, any open risks. If green, commit with the milestone name as specified. -- If unexpected existing changes appear in git status, pause and ask the operator before proceeding.