Commit Graph

52 Commits

Author SHA1 Message Date
pulse-triage[bot] 399618939d Name scoped legacy PCT access without implying root is required
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
2026-10-14 06:27:36 +01:00
pulse-triage[bot] acd5603878 Keep confined PVE filesystem help consistent with its collector
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
2026-10-14 06:22:43 +01:00
rcourtman 8a99b16d6c docs: correct customer docs that drifted from the source
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.
2026-10-11 13:59:56 +01:00
pulse-triage[bot] 3e88805623 Incorporate the batch-start upstream frontier
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
2026-10-06 12:16:57 +01:00
rcourtman 6b1fc6eaaf Collect LXC filesystems without pmxcfs or LXC socket IPC
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.
2026-10-06 11:14:21 +01:00
pulse-triage[bot] 63fcae0a3a Preserve partial PVE filesystem readings without widening helper access
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
2026-10-05 18:22:01 +01:00
pulse-triage[bot] 3c249ecacf Make Proxmox permission help token-aware and backup-safe
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
2026-10-05 03:43:34 +01:00
rcourtman 45dd45fe29 Record rootless runtime qualification evidence 2026-09-01 22:09:22 +01:00
rcourtman 53267e149d Harden least-privilege installer lifecycle state 2026-09-01 15:53:02 +01:00
rcourtman 11aadbfb1b Add rootless runtime qualification harness 2026-09-01 12:29:44 +01:00
rcourtman 60d0651a88 Cancel abandoned typed agent operations 2026-09-01 11:21:26 +01:00
rcourtman 2aece859a5 Harden safe rootless runtime recovery 2026-08-31 22:17:07 +01:00
rcourtman 70c1d0a178 Authenticate RC artifacts before qualification 2026-08-31 09:49:41 +01:00
rcourtman 7650fdaba3 Wire secure runtime RC qualification 2026-08-31 01:50:48 +01:00
Richard Courtman fec48928ee Record schema v6 secure runtime qualification 2026-08-31 01:12:15 +01:00
Richard Courtman 08f7c5f0d5 Harden secure agent runtime boundaries 2026-08-31 00:06:24 +01:00
pulse-triage[bot] e094a55b45 Integrate typed helper container summaries 2026-08-30 21:29:11 +01:00
Richard Courtman d9e9bf3679 Prove production action runner credential lifecycle 2026-08-30 21:03:37 +01:00
Richard Courtman b0de28c7c4 Record schema-v4 secure runtime qualification 2026-08-30 19:38:34 +01:00
Richard Courtman 98e8f86806 Harden secure runtime qualification provenance 2026-08-30 18:17:36 +01:00
Richard Courtman 770733fc92 Make action runner rotation activation-safe 2026-08-30 18:00:33 +01:00
Richard Courtman 34849268e5 Enforce collector credential scope allowlists 2026-08-30 17:18:38 +01:00
Pulse Test a7f1a5e25f Clarify safe profile host privilege requirements 2026-08-30 15:16:56 +01:00
Pulse Test 87a37e8d2f Publish secure runtime qualification matrix 2026-08-30 15:15:36 +01:00
Pulse Test 5b2e377843 Expose secure agent runtime posture 2026-08-30 00:38:44 +01:00
Pulse Test d607d5cf46 Separate agent remediation runtime 2026-08-29 23:48:28 +01:00
Pulse Test 6d4ee48000 Add typed agent privilege helper 2026-08-29 22:51:58 +01:00
Pulse Test a966264bb1 Contain agent command authority 2026-08-29 22:12:41 +01:00
rcourtman 87ee3cd449 Fix command policy after agent reinstall
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.
2026-08-23 23:39:20 +01:00
rcourtman df1290066e Relax NoNewPrivileges only when a least-privilege sudo grant is active
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.
2026-08-20 21:36:34 +01:00
rcourtman 4686efd8c8 Add a supported least-privilege agent install profile
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.
2026-08-20 20:49:44 +01:00
rcourtman a4d37447a0 Give the Docker-in-LXC opt-in an admin Settings toggle
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).
2026-08-20 14:27:12 +01:00
courtmanr@gmail.com 4dac4dd163 Allow agents to include filtered disk mounts 2026-08-11 16:37:37 +01:00
courtmanr@gmail.com 9b6df327ad feat(proxmox): show all LXC filesystems 2026-07-30 22:42:04 +01:00
courtmanr@gmail.com c0233ad56b feat(agent): add secure custom numeric sensors 2026-07-30 18:34:02 +01:00
rcourtman c41edb65a0 Fix agent command channel admission 2026-07-24 13:00:03 +01:00
rcourtman e17916e3bc Surface v5 agent migration security guidance
Warn when update readiness includes v5 agents and document the trusted-transport first hop.
2026-06-03 09:18:07 +01:00
rcourtman 1afd708e5a Harden unified agent update preflight
Record the single pulse-agent product invariant and clarify Docker / Podman module terminology.
2026-06-02 23:54:48 +01:00
rcourtman f8ca38587c docs: document split-port agent ingest for operators (MSP isolation)
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).
2026-05-29 09:54:11 +01:00
rcourtman 90482607da Bind Proxmox install command tokens on first use 2026-05-19 09:47:05 +01:00
rcourtman 0c1cdf7488 Add opt-in Proxmox LXC Docker inventory 2026-05-18 23:44:24 +01:00
rcourtman 5a405f7f07 Protect inside-guest Docker visibility boundaries 2026-05-18 14:16:15 +01:00
rcourtman 30180727ad Harden Proxmox setup token ACLs 2026-05-05 14:19:50 +01:00
rcourtman c61ea4947a Make Proxmox onboarding API-first 2026-05-05 13:25:17 +01:00
rcourtman cf103ca9fe Harden root agent service defaults 2026-05-05 13:03:13 +01:00
rcourtman 0bfed25e45 docs: clarify agent privilege guidance
Refs #1453
2026-05-04 18:04:04 +01:00
rcourtman 6955dc5379 Document unified agent privilege model 2026-05-01 20:28:11 +01:00
rcourtman 7be844f23a Require signed unified agent release assets 2026-04-22 02:00:29 +01:00
rcourtman 778a2577b6 feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
rcourtman 3f0808e9f9 docs: comprehensive core and Pro documentation overhaul
- 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
2026-01-07 17:38:27 +00:00