Replace manual resource ID entry with a searchable, filterable resource
picker that uses live WebSocket state. Support selecting multiple
resources (up to 50) for combined fleet reports.
Multi-resource PDFs include a cover page, fleet summary table with
aggregate health status, and condensed per-resource detail pages with
overlaid CPU/memory charts. Multi-resource CSVs include a summary
section followed by interleaved time-series data with resource columns.
New POST /api/admin/reports/generate-multi endpoint handles multi-resource
requests while the existing single-resource GET endpoint remains unchanged.
Also fixes resource ID validation regex to allow colons used in
VM/container IDs (e.g., "instance:node:vmid").
API tokens passed via ?token= query parameter were accepted on all HTTP
requests. This is a security concern because tokens in URLs can leak via
server logs, browser history, referrer headers, and proxy logs.
The query-string token path exists solely for WebSocket connections which
cannot set custom headers during the upgrade handshake. This change adds
an isWebSocketUpgrade check to all three query-string extraction sites
in CheckAuth and extractAndStoreAuthContext, rejecting ?token= on regular
HTTP requests while preserving WebSocket functionality.
No frontend impact — the kiosk flow stores the token in sessionStorage
then uses X-API-Token headers for all API calls.
- KnowledgeStore: use atomic write (temp+rename) to prevent file
corruption from concurrent async saves
- Change password tests: add auth headers since endpoint now requires
authentication
- ClearSession test: expect 2 cookies (pulse_session + pulse_csrf)
matching updated clearSession behavior
- API token test: update to match current behavior where query-string
tokens are accepted (needed for WebSocket connections)
- Host agent config: allow ScopeHostManage to resolve any host, not
just token-bound hosts
Backend:
- Add HostData field to ChartResponse struct in types.go
- Add host data processing in /api/charts endpoint using 'host:' prefix key
- Include hosts count in debug logging for chart responses
Frontend:
- Add 'host' to MetricResourceKind type in metricsKeys.ts
- Add hostData field to ChartsResponse interface in charts.ts
- Process hostData in seedFromBackend() in metricsHistory.ts
- Pass resourceId to EnhancedCPUBar and StackedMemoryBar in HostsOverview.tsx
- Add '7d' and '30d' to TIME_RANGE_OPTIONS in metricsViewMode.ts
This enables sparkline trend visualization for unified host agents,
consistent with Proxmox guests. Data accumulates over time at 30s intervals.
1. Enforce monitoring:read scope on WebSocket upgrades
- Prevents low-privilege tokens (e.g. host-agent:report) from accessing
full infra state via requestData on the main WebSocket.
2. Enforce agent token binding to prevent impersonation
- Added Metadata field to APITokenRecord to support bound_agent_id
- Updated agentexec server to validate token-to-agent binding if present
- Prevents agent:exec tokens from registering as arbitrary agent IDs
1. Host agent link/unlink/delete now require settings:write scope
- Prevents compromised host-agent:manage tokens from manipulating
or deleting unrelated hosts
- Host tokens scoped to one host can no longer affect other hosts
2. AI investigation endpoints now require ai:execute scope
- /api/ai/findings/* was only protected by RequireAuth
- Low-privilege tokens could read investigation details and chat logs
3. Notification DLQ endpoints now require settings:read/write scope
- DLQ entries contain notification configs (webhooks, SMTP, etc.)
- Prevents monitoring:read tokens from reading credential data
- DLQ retry/delete operations require settings:write
CRITICAL FIX: This endpoint previously allowed unauthenticated users to
trigger service restarts, which is a denial-of-service vulnerability.
Now requires:
- Authentication (CheckAuth) when auth is configured
- Admin role for proxy auth users
- settings:write scope for API tokens
Initial setup (no auth configured yet) remains accessible to allow
first-time security configuration to trigger restart.
- AI Intelligence endpoints (/api/ai/intelligence/*, /api/ai/forecast/*,
/api/ai/unified/findings, etc.) now require ai:execute scope to prevent
low-privilege tokens from reading sensitive intelligence data
- AI Knowledge endpoints (/api/ai/knowledge/*) now require ai:chat scope
to prevent arbitrary guest data access across the fleet
- AI Debug Context (/api/ai/debug/context) now requires settings:read scope
to prevent system prompt and infrastructure details leakage
- WebSocket origin check now validates peer IP is private when allowing
private network origins, mitigating CSWSH attacks where a malicious page
on the same LAN tries to hijack connections using victim's session cookie
- OAuth endpoints now require settings:write scope (not just admin)
- Approval endpoints now require ai:execute scope
- Added CommandHash to approvals for replay protection
- Approvals are now single-use (consumed on first use)
- consumeApprovalWithValidation validates command matches approval