The legacy grant-pct path deliberately permits only list and df outside the typed helper. Keep that distinction instead of calling every fallback a full-trust collector, and describe configured mounts rather than promising every mounted filesystem.
Contract-Neutral: Guidance wording only; no telemetry, privilege, API, installer or availability contract delta.
Change-source: pulse-maintainer
The deployment table still calls the typed helper a pct reader, while the implementation uses socket-free discovery and command fallback cannot recover within PrivateNetwork. Link the deployment choice, collector help and support matrix to one shipped explanation of partial, unavailable and older-helper readings, without recommending privilege or state changes.
Contract-Neutral: Guidance and consuming-proof coverage only; no telemetry, privilege, API, installer or availability contract delta.
Change-source: pulse-maintainer
Audited the customer-facing docs against the code: about 5,200 concrete
claims (env vars, endpoints, flags, defaults, ports, UI labels), plus every
environment variable the code reads. Each discrepancy was re-verified
against the source before editing, and every edit was reviewed again.
What users would have hit following the old text:
- UI paths and labels that no longer exist (Settings > Relay, Platform
connections, Access Control, SSO Providers, Create Organization) and
Patrol mode names (now Ask first, Safe auto-fix, Autopilot).
- Wrong values and behaviour: LOG_MAX_AGE=0 does not disable cleanup,
Patrol evidence budget is 10 calls and 12 turns, ALLOW_UNPROTECTED_EXPORT
covers private networks too, PULSE_AUDIT_ASYNC defaults on.
- Agent install: install.sh ignores PULSE_ENABLE_KUBERNETES and
PULSE_ENABLE_PROXMOX, rejects --disable-auto-update, and the token
fallback lives in the state directory.
- API: audit endpoints answer 402 on Community, onboarding QR is GET,
type=container is rejected, several routes need admin plus a scope.
- HTTP_REDIRECT_PORT was not documented anywhere.
Docs are mirrored under frontend-modern/public/docs, so each change is
applied to both copies. The tests that pinned the old wording (including
three that asserted claims the code contradicts) are updated alongside.
Contract-Neutral: Customer docs corrected to match shipped behaviour; no runtime, API or contract change.
Preserve published helper filesystem collection and vSphere activity commits. Resolve mirrored helper capability documentation to the upstream implementation account and retain both parents\x27 independent helper regression tests. No frontend source resolution or receipt rebinding.
Change-source: pulse-maintainer
The typed helper runs with PrivateNetwork=true. pct list, pct df and
lxc-info reach pmxcfs and the LXC monitor through abstract Unix
sockets, which belong to the network namespace, so inside the helper
they always fail. Least-privilege installs using the helper therefore
reported provider_unavailable for proxmox.lxc_filesystems on every
report and never got per-mount guest usage (#2511).
Discover running guests without commands: list /etc/pve/lxc through the
pmxcfs mount, find each guest's init in /sys/fs/cgroup/lxc/<vmid> (NSpid
exactly "<pid> 1", cgroup inside lxc/<vmid>), and name it by hostname or
CT<vmid> as pct list does. Discovery hands the whole node back to pct
whenever a guest's state cannot be established, so a guest it could not
read never disappears from a healthy-looking inventory.
Read usage through the shared filesystem prober instead of a second,
plain statfs path. It now accepts lxc requests: it pins the process,
requires the guest's exact cgroup and init (a nested namespace's PID 1
cannot stand in), skips declared mounts that are not mounted, and keeps
one bounded probe per guest. The helper's RestrictSUIDSGID makes
systemd answer openat2 with ENOSYS, so the prober falls back to a
component walk that refuses every symbolic link rather than resolving
it; Docker and Podman reads gain the same fallback.
Exercised on a disposable PVE 9.2.18 node under the helper unit's
sandbox properties: unprivileged and privileged guests matched pct df,
a stopped guest was omitted, and the prober's Linux tests passed as
root. A second opinion reviewed the design and the first draft; this
version addresses its findings.
Replace the rejected global host-network proposal with the unchanged private namespace on every platform, including native linux-386. Carry successful rows and omitted VMIDs through operation v2 without clearing degraded health or renewing omitted measurements; retain strict complete-only v1 compatibility. Restart the installer-owned helper only after isolated-unit and socket checks, and document the unresolved pmxcfs IPC limitation rather than claiming PVE recovery.
Change-source: pulse-maintainer
Remove the user placeholder command that Bash treats as file redirection. Diagnose the configured account and privilege-separated token on the affected scope without broader grants, token rotation or guest probes. Clarify that API-only guest reads still use the backup channel and preserve the monitoring-outage precaution in the existing help. Connected shipped-Markdown controls bind both entry points to the generated token/ACL contract.
Contract-Neutral: Existing help and regression controls only; no runtime, schema, collector, token, ACL, navigation or dependency contract change.
Change-source: pulse-maintainer
Project freshly minted installer command intent onto the stable host before returning remote config, and consume that intent once so later admin policy changes remain authoritative.
Live proof on a real systemd host (Debian 12 container, full
install/report/update/uninstall cycle) caught what no unit test did:
NoNewPrivileges=true blocks sudo outright, so the --grant-smart and
--grant-pct helpers failed inside the service and SMART/pct silently
disappeared while the install reported success. A unit with an active
grant now sets NoNewPrivileges=false, keeping the rest of the hardening;
a grantless least-privilege install keeps NNP enabled. Docs and contracts
state the trade-off: each grant is a scoped, auditable widening.
Also proven in the same live cycle: the flag-conflict refusals, user and
sudoers provisioning, wrapper execution as the service user, the healthy
privilege report ({runningAsRoot:false, serviceUser:pulse-agent,
smartctlHelper:true}), --update preserving the profile without repeated
flags, and uninstall removing the sudoers file and helpers.
The unified agent's Linux installer only offered the root profile, and the
docs called non-root unsupported. That default is the most-cited reason
security-conscious evaluators reject Pulse without trying it. install.sh
gains --least-privilege: the service runs as a dedicated nologin
pulse-agent system user with every existing hardening directive, no
LXC-attach ambient capabilities, docker-group membership for socket reads,
and refusal (not silent root fallback) on appliance platforms, non-systemd
init systems, and --enable-commands. Optional --grant-smart and --grant-pct
restore the only two collectors that need elevation through
visudo-validated exact-command sudoers rules and root-owned wrappers the
agent reaches via new absolute-path-only PULSE_SMARTCTL_PATH /
PULSE_PCT_PATH overrides; the pct grant covers pct list and pct df only
and can never widen into pct exec. --update preserves the profile and its
grants by reading the installed unit.
The agent now authors a privilege block in its report (effective root,
service user, active helpers), carried through models into the fleet
doctor as a descriptive field: Agent Doctor shows the profile and its
helpers instead of presenting intentionally absent collectors as a fault,
and a least-privilege agent can never be marked unhealthy on that evidence
alone.
Discovering Docker inside Proxmox LXC guests previously required an
undocumented environment variable plus a hand-edited systemd unit,
which is how the surface kept shipping invisible. The opt-in is now a
persisted system setting with an admin-only toggle in Settings →
System → General, presented as its own "Docker in Proxmox LXCs" card
under the existing Docker/Podman updates card, with the requirements
(node agent with command execution) and data-collection bounds stated
inline.
The setting rides the admin-gated system settings endpoint
(RequireAdmin + settings:write, matching every other server-wide
toggle). Flipping it persists first, then applies to the runtime
config and fires a reconfigure hook so the router rebuilds the
monitor's Docker checker and inventory collector immediately — no
restart. PULSE_ENABLE_PROXMOX_GUEST_DOCKER_INVENTORY remains
authoritative: when set it locks the toggle (EnvironmentLockBadge in
the UI, HTTP 400 from the API), and an unrelated settings save can
never clobber the runtime value. The opt-in guardrail test now pins
the settings path, the env lock, and the persisted field.
Installer and node setup-guide callouts now point at the toggle first
with the environment variable as the locking override, and the docs,
their public mirrors, and the agent-lifecycle subsystem contract say
the same. New i18n strings shipped for en/de/es.
Verified live in mock mode: toggle off/on from the UI drives the
collector teardown/setup log lines, the value survives a server
restart, and all three touched surfaces render at desktop and mobile
widths (receipt in frontend-modern/browser-verification.json).
PULSE_AGENT_INGEST_PORT existed in code but was absent from operator-facing
docs, so the network-isolation feature (dedicated agent-ingest port serving
only /api/agents/*, firewalled from the web UI/management API) was
undiscoverable. Adds it to CONFIGURATION.md (env-var row + Split-Port Agent
Ingest section with the security model and agent wiring via
PULSE_AGENT_CONNECT_URL) and an API Security cross-reference in
AGENT_SECURITY.md. Also aligns WEBHOOKS.md multi-tenant licensing wording with
MULTI_TENANT.md / API.md (Enterprise license + multi_tenant capability).
- Major updates to README.md and docs/README.md for Pulse v5
- Added technical deep-dives for Pulse Pro (docs/PULSE_PRO.md) and AI Patrol (docs/AI.md)
- Updated Prometheus metrics documentation and Helm schema for metrics separation
- Refreshed security, installation, and deployment documentation for unified agent models
- Cleaned up legacy summary files