From 87a37e8d2f784bc45b99e3b48d95f2f56adc34cc Mon Sep 17 00:00:00 2001 From: Pulse Test Date: Sun, 30 Aug 2026 15:15:36 +0100 Subject: [PATCH] Publish secure runtime qualification matrix --- docs/AGENT_SECURITY.md | 26 +++++++++++ .../internal/AGENT_PRIVILEGE_BOUNDARY_PLAN.md | 4 +- ...ime-qualification-foundation-2026-08-30.md | 4 +- .../v6/internal/subsystems/agent-lifecycle.md | 7 +++ frontend-modern/public/docs/AGENT_SECURITY.md | 26 +++++++++++ .../secure_runtime_platform_matrix_test.go | 44 +++++++++++++++++++ 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 scripts/installtests/secure_runtime_platform_matrix_test.go diff --git a/docs/AGENT_SECURITY.md b/docs/AGENT_SECURITY.md index 3d9d56d89b..0143087bee 100644 --- a/docs/AGENT_SECURITY.md +++ b/docs/AGENT_SECURITY.md @@ -184,6 +184,32 @@ live-host migration and helper update staging/activation/rollback exercises, container-runtime parity, and appliance qualification are still required before the profile can become the general default. +### Safe-profile support and qualification matrix + +`Qualified` below means the named evidence exercised the behavior on a real +operating-system boundary. `Implemented, unqualified` means the closed code +path and focused regressions exist, but representative live-provider evidence +does not. `Unavailable` means the safe installer refuses or visibly degrades +that capability; it never falls back to a root collector, Docker group, sudo, +or generic command path. + +| Platform or capability | Preferred boundary | Safe-profile behavior | Qualification and default implication | Residual owner and removal condition | +|---|---|---|---|---| +| Proxmox VE/PBS/PMG inventory, status, storage, and ordinary metrics | API-only connection with a narrowly scoped token; no host agent | No collector, helper, or runner authority is required for this data | Supported independently of the safe host-agent profile; it does not prove host-local SMART, LXC filesystem, or action parity | `agent-lifecycle`: keep API permissions and returned telemetry covered by provider tests | +| Standard Linux systemd host telemetry and collector update | Unprivileged `pulse-agent` plus the root-owned typed helper | Core `/proc`, filesystem, network, RAID, and hwmon telemetry stays in the collector; signed update activation crosses the fixed helper transaction | **Qualified on disposable Ubuntu 24.04.4 arm64 at committed main** for install, migration, explicit/automatic rollback, update, helper health, reporting continuity, and process/credential separation. Remains opt-in pending exact-RC reproduction and external review | `deployment-installability` and `security-privacy`: reproduce the twelve-scenario receipt from the designated release candidate and accept the external boundary review | +| Linux SMART telemetry | `smart.snapshot` through the no-network helper; no caller-selected device or arguments | Implemented, unqualified on representative physical disks. Helper failure omits/degrades SMART only; the collector does not retry as root | Does not yet justify SMART parity or a default change | `agent-lifecycle`: record live SATA, SAS/controller, USB bridge, and NVMe evidence, including standby, permission failure, timeout, and partial-data cases | +| Proxmox node-local LXC filesystem telemetry | `proxmox.lxc_filesystems` through the no-network helper using fixed bounded `pct` operations | Implemented, unqualified on a representative PVE node. Helper failure omits/degrades this snapshot only | Does not yet justify Proxmox host-agent parity or a default change | `agent-lifecycle`: record live running/stopped LXC, mount, timeout, output-bound, and helper-loss behavior on supported PVE versions | +| Rootful Docker or Podman inventory | No direct collector access to a root-equivalent daemon socket | **Unavailable in the safe profile.** Migration disables the provider visibly. A closed helper `container.inventory` operation exists, but collector integration and live parity are not qualified | Rootful container parity is an explicit default blocker; the legacy/root profile is not safe-profile evidence | `agent-lifecycle`: either integrate and qualify bounded helper inventory or retain the explicit degradation permanently | +| Collector-owned rootless Docker or Podman | Direct access only to one usable runtime socket owned by the `pulse-agent` UID | Implemented, unqualified live. Ambiguous, root-owned, unreadable, unwritable, or unavailable sockets disable container monitoring | Does not yet justify container-runtime parity or a default change | `deployment-installability`: record fresh install, migration, restart, socket-loss, ambiguity, and telemetry parity on both rootless Docker and rootless Podman | +| Separate runner package update and package-cache cleanup | Root-owned `pulse-agent-runner`, host-bound action credential, typed request, postcondition, and durable receipt | A real verified apt-cache mutation, stale-fingerprint refusal, replay, rotation, and self-revocation are qualified in the committed-main systemd receipt | Qualified only for the exercised apt-cache mutation; it does not qualify every runner operation or an exact release candidate | `agent-lifecycle` and `api-contracts`: reproduce from the RC and add representative package-update success/failure/cancellation evidence | +| Separate runner Proxmox guest and container lifecycle/update actions | Root-owned runner with closed typed protocols; never the monitoring collector | Implemented, unqualified on representative PVE and container-runtime targets | No live-provider action-parity claim and no default change | `agent-lifecycle`: record target-bound success, stale-state refusal, cancellation, reconnect/replay, and independent postconditions on disposable real targets | +| Appliance, non-systemd, Windows, and macOS host-agent profiles | Platform API where sufficient; otherwise an explicitly named legacy/full-trust profile | **Unavailable for safe-profile apply.** The installer fails closed instead of silently installing a root-equivalent profile | Excluded from the Linux safe-profile claim | `deployment-installability`: land a platform-specific service, filesystem, update, helper, migration, rollback, and live-proof contract before marking that platform supported | + +The committed-main Linux evidence is recorded in +`docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md`. +That receipt is artifact-bound operator self-attestation, not an independently +authenticated external assessment. The safe profile therefore remains opt-in. + Monitoring never implies remediation. On the supported Linux systemd profile, an operator may separately enroll the typed action runner: diff --git a/docs/release-control/v6/internal/AGENT_PRIVILEGE_BOUNDARY_PLAN.md b/docs/release-control/v6/internal/AGENT_PRIVILEGE_BOUNDARY_PLAN.md index 7ccb4d1e9a..273fe8364a 100644 --- a/docs/release-control/v6/internal/AGENT_PRIVILEGE_BOUNDARY_PLAN.md +++ b/docs/release-control/v6/internal/AGENT_PRIVILEGE_BOUNDARY_PLAN.md @@ -366,7 +366,9 @@ Required proof: Deliver: -- publish the per-platform privilege and telemetry matrix +- publish and keep current the per-platform privilege and telemetry matrix in + `docs/AGENT_SECURITY.md`; every unqualified row names its owner, visible + fail-closed behavior, and removal condition - run migration rehearsals on representative Proxmox, Linux, Docker/Podman, SMART, and update environments - complete an external security review focused on the local helper protocol, diff --git a/docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md b/docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md index de1a5feb9b..93967263d2 100644 --- a/docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md +++ b/docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md @@ -126,7 +126,9 @@ unauthenticated, artifact-bound self-attestation rather than independent proof. Focused regressions and the schema-v3 guarded systemd evidence cover the current committed-main semantics. They are not a substitute for exact release-candidate reproduction, representative provider/appliance qualification, or external -review. +review. The canonical support and residual matrix is published in +`docs/AGENT_SECURITY.md`; unqualified rows remain explicit blockers rather than +being inferred from the generic Linux result. The safe profile therefore remains opt-in. The default may not ratchet until the exact release candidate reproduces the complete systemd result; diff --git a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md index 5bed587911..dff4265b57 100644 --- a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md +++ b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md @@ -43,6 +43,13 @@ host-storage-cleanup, Proxmox guest lifecycle, and container lifecycle/update operations. Generic shell, exec, unrestricted `read_file`, and deploy requests are forbidden. Removing or disabling the runner leaves collector monitoring and the helper unchanged. +`docs/AGENT_SECURITY.md` owns the canonical safe-profile platform, +privilege, telemetry, and action qualification matrix, and its shipped frontend +copy must remain byte-identical. Each unqualified or unavailable row must name +the fail-closed behavior, residual owner, and concrete removal condition. +Implemented or mocked behavior is never promoted to live-provider +qualification, and the safe profile cannot become the general default while a +matrix row required by that default remains unqualified. Safe-profile collector credentials carry only `agent:report` and the host-bound `agent:config:read` capability; they carry neither `agent:exec` nor the broader `agent:manage` scope. Migration to that profile must durably remove diff --git a/frontend-modern/public/docs/AGENT_SECURITY.md b/frontend-modern/public/docs/AGENT_SECURITY.md index 3d9d56d89b..0143087bee 100644 --- a/frontend-modern/public/docs/AGENT_SECURITY.md +++ b/frontend-modern/public/docs/AGENT_SECURITY.md @@ -184,6 +184,32 @@ live-host migration and helper update staging/activation/rollback exercises, container-runtime parity, and appliance qualification are still required before the profile can become the general default. +### Safe-profile support and qualification matrix + +`Qualified` below means the named evidence exercised the behavior on a real +operating-system boundary. `Implemented, unqualified` means the closed code +path and focused regressions exist, but representative live-provider evidence +does not. `Unavailable` means the safe installer refuses or visibly degrades +that capability; it never falls back to a root collector, Docker group, sudo, +or generic command path. + +| Platform or capability | Preferred boundary | Safe-profile behavior | Qualification and default implication | Residual owner and removal condition | +|---|---|---|---|---| +| Proxmox VE/PBS/PMG inventory, status, storage, and ordinary metrics | API-only connection with a narrowly scoped token; no host agent | No collector, helper, or runner authority is required for this data | Supported independently of the safe host-agent profile; it does not prove host-local SMART, LXC filesystem, or action parity | `agent-lifecycle`: keep API permissions and returned telemetry covered by provider tests | +| Standard Linux systemd host telemetry and collector update | Unprivileged `pulse-agent` plus the root-owned typed helper | Core `/proc`, filesystem, network, RAID, and hwmon telemetry stays in the collector; signed update activation crosses the fixed helper transaction | **Qualified on disposable Ubuntu 24.04.4 arm64 at committed main** for install, migration, explicit/automatic rollback, update, helper health, reporting continuity, and process/credential separation. Remains opt-in pending exact-RC reproduction and external review | `deployment-installability` and `security-privacy`: reproduce the twelve-scenario receipt from the designated release candidate and accept the external boundary review | +| Linux SMART telemetry | `smart.snapshot` through the no-network helper; no caller-selected device or arguments | Implemented, unqualified on representative physical disks. Helper failure omits/degrades SMART only; the collector does not retry as root | Does not yet justify SMART parity or a default change | `agent-lifecycle`: record live SATA, SAS/controller, USB bridge, and NVMe evidence, including standby, permission failure, timeout, and partial-data cases | +| Proxmox node-local LXC filesystem telemetry | `proxmox.lxc_filesystems` through the no-network helper using fixed bounded `pct` operations | Implemented, unqualified on a representative PVE node. Helper failure omits/degrades this snapshot only | Does not yet justify Proxmox host-agent parity or a default change | `agent-lifecycle`: record live running/stopped LXC, mount, timeout, output-bound, and helper-loss behavior on supported PVE versions | +| Rootful Docker or Podman inventory | No direct collector access to a root-equivalent daemon socket | **Unavailable in the safe profile.** Migration disables the provider visibly. A closed helper `container.inventory` operation exists, but collector integration and live parity are not qualified | Rootful container parity is an explicit default blocker; the legacy/root profile is not safe-profile evidence | `agent-lifecycle`: either integrate and qualify bounded helper inventory or retain the explicit degradation permanently | +| Collector-owned rootless Docker or Podman | Direct access only to one usable runtime socket owned by the `pulse-agent` UID | Implemented, unqualified live. Ambiguous, root-owned, unreadable, unwritable, or unavailable sockets disable container monitoring | Does not yet justify container-runtime parity or a default change | `deployment-installability`: record fresh install, migration, restart, socket-loss, ambiguity, and telemetry parity on both rootless Docker and rootless Podman | +| Separate runner package update and package-cache cleanup | Root-owned `pulse-agent-runner`, host-bound action credential, typed request, postcondition, and durable receipt | A real verified apt-cache mutation, stale-fingerprint refusal, replay, rotation, and self-revocation are qualified in the committed-main systemd receipt | Qualified only for the exercised apt-cache mutation; it does not qualify every runner operation or an exact release candidate | `agent-lifecycle` and `api-contracts`: reproduce from the RC and add representative package-update success/failure/cancellation evidence | +| Separate runner Proxmox guest and container lifecycle/update actions | Root-owned runner with closed typed protocols; never the monitoring collector | Implemented, unqualified on representative PVE and container-runtime targets | No live-provider action-parity claim and no default change | `agent-lifecycle`: record target-bound success, stale-state refusal, cancellation, reconnect/replay, and independent postconditions on disposable real targets | +| Appliance, non-systemd, Windows, and macOS host-agent profiles | Platform API where sufficient; otherwise an explicitly named legacy/full-trust profile | **Unavailable for safe-profile apply.** The installer fails closed instead of silently installing a root-equivalent profile | Excluded from the Linux safe-profile claim | `deployment-installability`: land a platform-specific service, filesystem, update, helper, migration, rollback, and live-proof contract before marking that platform supported | + +The committed-main Linux evidence is recorded in +`docs/release-control/v6/internal/records/secure-agent-runtime-qualification-foundation-2026-08-30.md`. +That receipt is artifact-bound operator self-attestation, not an independently +authenticated external assessment. The safe profile therefore remains opt-in. + Monitoring never implies remediation. On the supported Linux systemd profile, an operator may separately enroll the typed action runner: diff --git a/scripts/installtests/secure_runtime_platform_matrix_test.go b/scripts/installtests/secure_runtime_platform_matrix_test.go new file mode 100644 index 0000000000..b4a0ee2722 --- /dev/null +++ b/scripts/installtests/secure_runtime_platform_matrix_test.go @@ -0,0 +1,44 @@ +package installtests + +import ( + "bytes" + "os" + "strings" + "testing" +) + +func TestSecureRuntimePlatformMatrixRemainsExplicitAndShipped(t *testing.T) { + canonical, err := os.ReadFile(repoFile("docs", "AGENT_SECURITY.md")) + if err != nil { + t.Fatalf("read canonical agent security documentation: %v", err) + } + shipped, err := os.ReadFile(repoFile("frontend-modern", "public", "docs", "AGENT_SECURITY.md")) + if err != nil { + t.Fatalf("read shipped agent security documentation: %v", err) + } + if !bytes.Equal(canonical, shipped) { + t.Fatal("shipped Agent Security documentation differs from the canonical source") + } + + content := string(canonical) + required := []string{ + "### Safe-profile support and qualification matrix", + "Standard Linux systemd host telemetry and collector update", + "Linux SMART telemetry", + "Proxmox node-local LXC filesystem telemetry", + "Rootful Docker or Podman inventory", + "Collector-owned rootless Docker or Podman", + "Separate runner package update and package-cache cleanup", + "Separate runner Proxmox guest and container lifecycle/update actions", + "Appliance, non-systemd, Windows, and macOS host-agent profiles", + "Implemented, unqualified", + "**Unavailable in the safe profile.**", + "The safe profile therefore remains opt-in.", + "Residual owner and removal condition", + } + for _, marker := range required { + if !strings.Contains(content, marker) { + t.Errorf("secure-runtime platform matrix is missing %q", marker) + } + } +}