diff --git a/CLAUDE.md b/CLAUDE.md index ffc090e..8527625 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -315,6 +315,17 @@ a Service cannot address the one pod holding a console listener. Agents report CPU/memory/swap/partitions/kernel — metrics every 30s, full static snapshot every 15 min. They also check for pending OS package updates hourly and can apply them on command (`ApplyUpdatesCmd`). +Windows update checking and applying go through the Windows Update COM API +(`Microsoft.Update.Session`) rather than the PSWindowsUpdate module, which would +need a PowerShell Gallery install on every host and fails on an air-gapped +fleet. `CurrentVersion` is empty on Windows and `NewVersion` carries the KB +article ID: a Windows update is not a version bump of a named package. + +**The agent never reboots a host.** `ApplyUpdatesCmd` installs and stops there; +`inventory.reboot_required` reports that one is owed, set on the static snapshot +every 15 minutes. Linux fills it too, from `/var/run/reboot-required` or +`dnf needs-restarting -r`. + ### Package inventory and CVE findings Agents report their installed packages hourly; the control plane matches them @@ -364,10 +375,22 @@ scheduler off entirely. A **workload** is one Docker container or one systemd unit — one word for the page, the collection and the commands, rather than saying "container or -service" in every identifier. Linux only, and **not gated by licence**: this -reads as core fleet management, so v1 ships everywhere with no `HasFeature` -check. If that changes the check belongs at `ReportWorkloads`, gating collection -rather than display, exactly as sub-project A does. +service" in every identifier. + +On Windows a workload is a Docker container or a Windows **service**, reported +under the same `unit` kind and the same `systemd_ok` / `systemd_error` fields — +one wire shape, worded per platform in the UI, which is the only layer that +knows the host's OS. The platform split lives entirely in the agent, as build +tags (`systemd_linux.go` / `services_windows.go` and the matching `control_` +and `logs_` pairs); the control plane is OS-blind and needed no changes. +Windows collection runs PowerShell through `agent/internal/winexec`, and every +script emits JSON that a build-tag-free parser reads, so the parsers are tested +on Linux — the agent module has no Windows CI. + +**Not gated by licence**: this reads as core fleet management, so v1 ships +everywhere with no `HasFeature` check. If that changes the check belongs at +`ReportWorkloads`, gating collection rather than display, exactly as sub-project +A does. Agents collect on a 60-second ticker and report through `ReportWorkloads` with the **offer-then-send** handshake the package report already uses. The offer is @@ -391,8 +414,9 @@ reads get `WorkloadLogsResult`. `CommandStream` republishes **every** no-op, so this costs nothing and avoids a second result path. **The protected set is computed agent-side and enforced agent-side.** -`vantage-agent.service`, plus the container ID read from `/proc/self/cgroup` -should the agent ever run in a container. As with the console relay hardcoding +`vantage-agent.service` on Linux, `VantageAgent` on Windows, plus the container +ID read from `/proc/self/cgroup` should the agent ever run in a container. As +with the console relay hardcoding `127.0.0.1`, the control plane may name a target but the agent decides what it will do to itself; a server-side denylist alone would be bypassed by the next dispatch path someone adds, and the failure is unrecoverable from the UI. The @@ -1144,7 +1168,12 @@ git push origin main # server + web deploy - **guacd for console** — protocol handling is Guacamole's problem, not ours; we proxy the WebSocket and manage credentials. - **`org_id` on every document** — isolation enforced at the query layer, not by separate databases. - **root only** — manages `/root/.ssh/authorized_keys`; no per-user key management. -- **Windows agents are second-class by design** — register, heartbeat, run steps, report inventory; no `authorized_keys` management. +- **Windows agents cover the fleet-management path** — register, heartbeat, run + steps, report inventory, OS updates through the Windows Update COM API, and + workloads (services plus containers, with control and logs). They still do no + `authorized_keys` management, and no package inventory or CVE matching: the + vulnerability feeds this project uses carry no Windows data, so a Windows host + correctly reports `unsupported` rather than a clean bill of health. - **Both `server` and `web` scale horizontally** — see "Running more than one server replica" below. `web` holds nothing; `server` holds per-agent state that is routed between replicas over Redis rather than duplicated. - **Deletion lives in the control plane** — admin sends the warnings because it knows the billing address; the control plane performs the delete because it is the only service that knows which collections carry `instance_id`. Mirroring that list into admin would drift, and a drift there deletes the wrong rows. diff --git a/docsite/docs/getting-started/first-server.md b/docsite/docs/getting-started/first-server.md index 6796c94..4450697 100644 --- a/docsite/docs/getting-started/first-server.md +++ b/docsite/docs/getting-started/first-server.md @@ -55,8 +55,11 @@ It writes the config to `%ProgramData%\vantage\config.yaml`, installs the agent as a Windows service and starts it. :::info Windows servers do not get SSH key management -Windows agents register, report inventory and run workflow steps. Managing -`authorized_keys` is a Linux-only feature. +Windows agents register, heartbeat, report inventory, run workflow steps, +serve the browser console, check and apply OS updates, and report workloads +(services and containers). Managing `authorized_keys` is a Linux-only +feature, and so is package inventory and CVE scanning — the vulnerability +feeds this project uses carry no Windows data. ::: ## 3. Watch it come up diff --git a/docsite/docs/vantage/servers.md b/docsite/docs/vantage/servers.md index 7c18e03..baeee07 100644 --- a/docsite/docs/vantage/servers.md +++ b/docsite/docs/vantage/servers.md @@ -89,10 +89,13 @@ metrics is normal rather than a fault. ### OS updates -Agents check for pending package updates hourly and report the count. From the -server page you can: +Agents check for pending package updates hourly and report the count — the +machine's own package manager on Linux, the Windows Update COM API on Windows. +From the server page you can: -- **Apply updates** runs the machine's own package manager and reports back. +- **Apply updates** runs that check's install path and reports back. The agent + never reboots the machine; if one is owed, a **reboot required** badge + appears on the next inventory snapshot instead. - **Update agent** upgrades the Vantage agent on that machine. See [Agent updates](../operations/agent-updates.md). @@ -107,8 +110,11 @@ Opens a browser SSH, RDP or VNC session. See [Browser console](./browser-console ## Windows servers -Windows agents register, run workflow steps and report inventory. They do not -manage `authorized_keys`. +Windows agents register, heartbeat, run workflow steps, report inventory, +check and apply OS updates, report workloads (services and containers), and +serve the browser console. They do not manage `authorized_keys`, and they are +not covered by package inventory or CVE scanning — the vulnerability feeds +this project uses carry no Windows data. ## Removing a server diff --git a/docsite/docs/vantage/workloads.md b/docsite/docs/vantage/workloads.md index 962eaea..34d7464 100644 --- a/docsite/docs/vantage/workloads.md +++ b/docsite/docs/vantage/workloads.md @@ -4,23 +4,24 @@ title: Workloads sidebar_label: Workloads --- -A **workload** is one Docker container or one systemd service. Each Linux server -reports what it is running, and you can start, stop and restart those workloads, -and read their recent logs, without opening a console. +A **workload** is one Docker container or one service — a systemd unit on +Linux, a Windows service on Windows. Every server reports what it is running, +and you can start, stop and restart those workloads, and read their recent +logs, without opening a console. Available on every instance. No licence feature is required. ## What gets reported -Linux servers only, reported every 60 seconds. +Every server, Linux and Windows, reported every 60 seconds. - **Containers**: every container, running or not, with its image, published - ports, health, restart count and the compose stack it belongs to. -- **Services**: systemd units that are running, failed, or enabled but stopped. - The operating system's own units are hidden, since a typical host has hundreds - of them and they bury the ones you care about. - -Windows servers report no workloads at all. + ports, health, restart count and the compose stack it belongs to. Requires + Docker (or Docker Desktop on Windows). +- **Services**: systemd units on Linux that are running, failed, or enabled but + stopped, and Windows services in the equivalent states. The operating + system's own units and platform services are hidden, since a typical host + has hundreds of them and they bury the ones you care about. ## Docker not in use is not an error