Commit graph

774 commits

Author SHA1 Message Date
rcourtman
24f5b1cb31 fix(patrol): cap per-run tokens and reset patrol session history 2026-02-24 11:29:47 +00:00
rcourtman
b445f8d8fa fix(agent): preserve user-configured host URL during agent re-registration (#1283)
When an agent re-registers with the same token, the DHCP matching case
would overwrite the Host field with the agent's local IP — even if the
user had edited it to a public URL or different IP. Now agent source
re-registrations always preserve the existing host, while non-agent
DHCP updates still work. Adds 5 regression tests covering hostname
preservation, public-IP preservation, agent DHCP, non-agent DHCP, and
PBS parity.
2026-02-21 12:46:02 +00:00
rcourtman
1d07c1cd30 fix(agent): prevent duplicate PVE entries on agent re-registration (#1245)
Two changes to prevent duplicates in Settings > Virtual Environment:

1. Install script: only clear Proxmox state files on fresh installs,
   not upgrades. Previously every install forced re-registration.

2. Auto-register dedup: match agent re-registrations by server name
   when both the existing entry and new request have Pulse-created
   tokens (pulse-monitor@pam!pulse-*). This catches the case where
   the agent creates a new token after state files are cleared.
2026-02-20 19:38:03 +00:00
rcourtman
6c78d78fc7 fix(webhooks): test button in edit form sends redacted headers (#1273)
When editing an existing webhook, header values are masked as
***REDACTED*** for security. The "Test" button in the edit form
sent these redacted values to the webhook endpoint, causing auth
failures (HTTP 403) on services like ntfy.sh that require tokens.

The test button outside the edit form worked because it used the
server-side saved config with real header values.

Fix: frontend now includes the webhook ID in test payloads for
existing webhooks, and the backend TestWebhook handler merges
redacted values with the saved originals before sending the test
(same logic already used by UpdateWebhook).
2026-02-20 13:31:52 +00:00
rcourtman
afb4dcc2bd fix(sso): return full provider config for edit form and register SSO users in RBAC (#1255)
Two remaining issues from #1255 after the 5.1.10 fixes:

1. OIDC/SAML provider edit fields appeared blank because the GET
   endpoint returned a flattened response while the frontend reads
   nested oidc/saml objects. Now returns the full provider config
   with secrets redacted (client secret, SP private key).

2. SSO users didn't appear in Settings > Users because RBAC entries
   were only created when group-role mappings matched. Now ensures
   every SSO user is registered in RBAC on login, even without
   role mappings.

Also fixes: SAML SP private key and certificate lost on edit (no
preservation logic existed), OIDC client secret preservation
hardened to check actual secret presence not just flag.
2026-02-20 13:31:52 +00:00
rcourtman
9d8f8b45b5 fix(docker,metrics): preserve container metadata on update and reduce DB writes
Docker container URL preserved on update (#1054): container updates
recreate the container with a new runtime ID. The agent now includes
{oldContainerId, newContainerId} in the completion ACK payload; the
server uses this to copy persisted metadata (custom URLs, descriptions,
tags) to the new ID so nothing is lost. Migration is a copy, not a move,
so rollback scenarios still find metadata under the original ID.

Reduce metrics.db write amplification (#1124): add a UNIQUE index on
(resource_type, resource_id, metric_type, timestamp, tier) so rollup
reprocessing after a failed checkpoint uses INSERT OR IGNORE instead of
creating duplicate rows. Existing duplicates are deduplicated once on
startup if the index creation would otherwise fail. Also sets
wal_autocheckpoint(500) to checkpoint the WAL more frequently, preventing
unbounded WAL growth.

Fixes #1054
Fixes #1124
2026-02-18 12:56:46 +00:00
rcourtman
7522f6599c fix(agent): three backend fixes for FreeBSD, Docker rootless, and duplicate PVE hosts
FreeBSD auto-update (#1254): determineArch() now includes freebsd in its
OS switch, producing freebsd-amd64/arm64 instead of falling through to
a uname -m fallback that incorrectly returned linux-<arch>. FreeBSD agents
were downloading Linux ELF binaries and failing to exec them.

Docker rootless socket (#1200): buildRuntimeCandidates() now probes
/run/user/<uid>/docker.sock before the system-wide /var/run/docker.sock,
enabling auto-detection of Docker rootless installations.

Duplicate PVE/PBS hosts (#1245, #1252): handleSecureAutoRegister() now
deduplicates by host URL, updating the existing instance's token in-place
instead of appending a duplicate entry on each re-run of the setup script.

Fixes #1254
Fixes #1200
Fixes #1245
Fixes #1252

(cherry picked from commit 0f1d9e9b9fea6c8b9e65872e8a78e25f93653eef)
2026-02-18 12:53:25 +00:00
rcourtman
97aee77ae7 fix(sso): preserve oidc/saml sub-config when toggle sends flat update payload
The enable/disable toggle PUT sends back the flat list-response shape
(no nested oidc/saml objects). handleUpdateSSOProvider was unmarshaling
this directly, leaving OIDC and SAML as nil and overwriting all stored
credentials on every toggle.

Now preserves existing sub-config objects when the incoming payload omits
them, matching the existing ClientSecret preservation behaviour.

Fixes part of #1255

(cherry picked from commit 44868e99d66aa157f5c62d100151a6f8bc940205)
2026-02-18 12:53:18 +00:00
rcourtman
a210b01a03 fix(sso): load SSO config at startup and expose providers on login page
r.ssoConfig was never loaded from persistence in NewRouter(), so on every
restart all SSO providers were silently discarded (handleListSSOProviders
would reinitialize to an empty config on the first request).

Also adds ssoProviders to /api/security/status so the login page can
render SAML/OIDC login buttons for enabled providers.

Fixes part of #1255

(cherry picked from commit 395cd101ff4acb1b7f89ec3d907b84cbec217dc8)
2026-02-18 12:53:15 +00:00
rcourtman
2fb6ebc25f fix: add SAML auth bypass and update route inventory tests
The SAML route registration (bee3d05f) was incomplete: the auth
middleware uses exact-match for public paths, so /api/saml/{id}/login
etc. would be blocked. Add prefix-based auth bypass for /api/saml/
paths and update route inventory tests for both SSO and SAML routes.
2026-02-11 13:48:16 +00:00
rcourtman
bee3d05f0d fix: register SAML login flow routes (login, ACS, metadata, logout, SLO)
The SAML handler functions existed but were never registered in
setupRoutes(), causing 404s for all SAML authentication flows.
Adds /api/saml/ prefix route with dispatcher for all 5 endpoints.
2026-02-11 13:29:05 +00:00
rcourtman
89969079b9 fix: register SSO provider API routes
The SSO handler functions and frontend were implemented but the HTTP
routes were never registered in setupRoutes(), causing 404 on all
/api/security/sso/providers endpoints.

Fixes #1248
2026-02-11 13:17:51 +00:00
rcourtman
6140cb5be4 fix: auto-default discovery interval to 24h when enabled
When users enable AI discovery without setting an interval, the
default of 0 silently stays in manual-only mode. Now normalizes
0 to 24h on save so discovery actually starts automatically.

Fixes #1225
2026-02-10 21:45:59 +00:00
rcourtman
7336ec2d87 fix(metrics): normalize docker resource type in metrics history API (#1229)
Frontend sends resourceType="docker" but the SQLite store uses
"dockerContainer". The /api/metrics-store/history handler now
normalizes the alias so queries return the correct historical data
instead of falling back to a single live data point.
2026-02-09 22:33:24 +00:00
rcourtman
815c990e85 fix(proxmox): avoid 403 on apt update checks 2026-02-09 20:28:09 +00:00
rcourtman
0f961054c6 fix: allow agent tokens to auto-register Proxmox nodes
The security hardening in beae4c86 added a settings:write scope
requirement to /api/auto-register, but agent install tokens only have
host-agent:report scope. This broke Proxmox auto-registration for all
agent-generated tokens. Accept either settings:write or host-agent:report
scope for auto-registration.

Fixes #1191
2026-02-04 22:55:25 +00:00
rcourtman
f6338f34fa fix: add agent:exec scope to generated agent tokens
Agent tokens created from the Settings UI and the backend install
command handler were missing the agent:exec scope, which was added
as a security requirement in 60f9e6f0. This caused all newly
installed agents to fail registration with "Agent exec token missing
required scope: agent:exec".

Fixes #1191
2026-02-04 22:33:01 +00:00
rcourtman
5bbc4329bd Remove pprof diagnostics endpoint 2026-02-04 20:44:00 +00:00
rcourtman
a37b59b7e4 Add admin-gated pprof diagnostics endpoint 2026-02-04 20:39:24 +00:00
rcourtman
ee0e89871d fix: reduce metrics memory 86x by reverting buffer and adding LTTB downsampling
The in-memory metrics buffer was changed from 1000 to 86400 points per
metric to support 30-day sparklines, but this pre-allocated ~18 MB per
guest (7 slices × 86400 × 32 bytes). With 50 guests that's 920 MB —
explaining why users needed to double their LXC memory after upgrading
to 5.1.0.

- Revert in-memory buffer to 1000 points / 24h retention
- Remove eager slice pre-allocation (use append growth instead)
- Add LTTB (Largest Triangle Three Buckets) downsampling algorithm
- Chart endpoints now use a two-tier strategy: in-memory for ranges
  ≤ 2h, SQLite persistent store + LTTB for longer ranges
- Reduce frontend ring buffer from 86400 to 2000 points

Related to #1190
2026-02-04 19:49:52 +00:00
rcourtman
502766b9b7 fix: proxy agent binary from GitHub instead of redirecting
When the server doesn't have agent binaries locally (common for
LXC/bare-metal installations), it was redirecting to GitHub releases.
The agent's HTTP client followed the redirect, but GitHub doesn't
provide the X-Checksum-Sha256 header that agents require for security
verification, causing every update attempt to fail silently.

Proxy the download through the server instead, computing and attaching
the checksum header so agents can verify and install the update.
2026-02-04 19:31:33 +00:00
rcourtman
7e55c4dc52 Expand proxy non-admin coverage for permissioned routes 2026-02-04 18:12:30 +00:00
rcourtman
422271d103 Require proxy admin for permissioned endpoints 2026-02-04 18:11:12 +00:00
rcourtman
4741307c4c Require proxy admin for quick security setup 2026-02-04 18:08:40 +00:00
rcourtman
25285e64bc Require proxy admin for AI test endpoints 2026-02-04 16:30:22 +00:00
rcourtman
5a494b10a5 Cover proxy auth for AI settings updates 2026-02-04 16:27:48 +00:00
rcourtman
34f35f0322 Protect discovery notes secrets for proxy users 2026-02-04 16:25:16 +00:00
rcourtman
12038e4e9a Guard discovery settings against proxy non-admin 2026-02-04 16:23:08 +00:00
rcourtman
a2f01f14af Require proxy admin for token regeneration 2026-02-04 16:19:57 +00:00
rcourtman
0867490ae0 Block proxy non-admin password changes 2026-02-04 16:17:00 +00:00
rcourtman
27d8cc92dc Cover proxy auth on config export/import 2026-02-04 16:13:15 +00:00
rcourtman
ce9ee2481a Enforce proxy user RBAC via RequirePermission 2026-02-04 16:11:41 +00:00
rcourtman
9d4d392026 fix: host network sparklines showing cumulative bytes instead of rates
Host network sparklines were displaying wildly incorrect values (e.g., 147 GB/s
for an idle Raspberry Pi) because cumulative byte counters (total bytes since
boot) were being stored directly instead of being converted to rates.

Changes:
- monitor.go: Use RateTracker to calculate network rates for hosts, matching
  the existing pattern used for VMs and containers. Only record network
  metrics when we have enough samples to calculate valid rates.
- router.go: Remove network metrics from live fallback for hosts since we
  can't calculate rates from a single snapshot. Better to show nothing than
  misleading cumulative totals.

The fix follows the established codebase pattern where:
1. Agent reports cumulative RXBytes/TXBytes
2. RateTracker compares consecutive samples to calculate bytes/second
3. Rates are stored in metrics history for sparkline display
2026-02-04 16:11:04 +00:00
rcourtman
f7bc69fac2 Add AI reapprove scope and license tests 2026-02-04 16:04:46 +00:00
rcourtman
c724bb04cf Extend proxy admin denial coverage 2026-02-04 16:00:43 +00:00
rcourtman
5f2990deec Require proxy admin for SSH config endpoints 2026-02-04 15:57:59 +00:00
rcourtman
145e5c46bb Require admin for host config patch and delete 2026-02-04 15:56:07 +00:00
rcourtman
5ede1f6a97 Harden apply-restart auth for proxy/OIDC 2026-02-04 15:48:06 +00:00
rcourtman
0f2122ea85 Cover proxy admin gating for config management 2026-02-04 15:45:31 +00:00
rcourtman
093235b0a9 Extend proxy admin gating to agent manage endpoints 2026-02-04 15:44:24 +00:00
rcourtman
df799c66d5 Expand proxy admin gating for host and profiles 2026-02-04 15:42:54 +00:00
rcourtman
e9860eb4c6 Block proxy non-admin for security restart and OIDC 2026-02-04 15:41:50 +00:00
rcourtman
248f4c69a5 Ensure proxy non-admins blocked for AI admin endpoints 2026-02-04 15:40:14 +00:00
rcourtman
773ba13ada Require ai:execute for approvals approve/deny 2026-02-04 15:39:04 +00:00
rcourtman
23cc5af69f Require proxy admin for test-notification 2026-02-04 15:34:30 +00:00
rcourtman
e3179e49ac Cover RBAC mutation license gating 2026-02-04 15:22:38 +00:00
rcourtman
4e3811e69e Cover RBAC mutations in permission denial tests 2026-02-04 15:21:02 +00:00
rcourtman
895a7e07e2 Verify host uninstall enforces token binding 2026-02-04 15:16:12 +00:00
rcourtman
e069507d97 Add scope checks for notification endpoints 2026-02-04 15:10:02 +00:00
rcourtman
d257815564 Reject recovery via untrusted XFF 2026-02-04 15:01:09 +00:00