Commit Graph

590 Commits

Author SHA1 Message Date
rcourtman 563f4893fb test: guard ai settings endpoints by scope 2026-02-04 10:39:28 +00:00
rcourtman 86b75c9e7c test: enforce monitoring:write for metadata mutations 2026-02-04 10:38:48 +00:00
rcourtman 9409969ddd test: require monitoring:read for core data endpoints 2026-02-04 10:37:53 +00:00
rcourtman 8ed47b8971 test: enforce agent scope checks 2026-02-04 10:37:06 +00:00
rcourtman 37f909c6dd test: guard discovery endpoints by scope 2026-02-04 10:35:43 +00:00
rcourtman ad21be68f3 test: enforce settings:write for config node mutations 2026-02-04 10:34:41 +00:00
rcourtman ead8eb7087 test: require ai:execute scope on more ai endpoints 2026-02-04 10:33:53 +00:00
rcourtman c68e386d01 test: cover ai patrol and run-command scopes 2026-02-04 10:32:05 +00:00
rcourtman b9eee668e5 test: expand security regression coverage 2026-02-04 10:28:41 +00:00
rcourtman 5c1487e406 feat: add resource picker and multi-resource report generation
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").
2026-02-04 10:24:23 +00:00
rcourtman f60050a801 fix(security): restrict query-string token auth to WebSocket upgrades only
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.
2026-02-04 09:52:32 +00:00
rcourtman a6f2a674eb fix: resolve test failures blocking release
- 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
2026-02-03 23:53:54 +00:00
rcourtman 6059759958 feat: Add sparkline support for unified host agents on hosts page
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.
2026-02-03 22:59:55 +00:00
rcourtman 7c1ebbecd5 fix(security): enhance webhook validation, enforce API scopes, and improve test coverage 2026-02-03 22:41:44 +00:00
rcourtman 5a990dd554 Fix sparkline data inconsistency and support 30d range 2026-02-03 22:39:50 +00:00
rcourtman b7a94bad9f security: fix websocket scope and agent impersonation
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
2026-02-03 20:40:08 +00:00
rcourtman 0dfe3d16b3 security: secure socket.io, test-notification, and stats endpoints
1. Secure /socket.io/ endpoint
   - Previously allowed unauthenticated WebSocket upgrades via transport=websocket
   - Now enforces CheckAuth() before upgrade

2. Secure /api/test-notification
   - Previously unauthenticated and allowed broadcasting to all clients
   - Now requires Admin + settings:write scope

3. Secure /simple-stats
   - Added authentication requirement (was public)
2026-02-03 20:08:16 +00:00
rcourtman dd47cbe5b4 security: fix host token binding, AI findings scope, and DLQ credential exposure
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
2026-02-03 19:59:46 +00:00
rcourtman fdc99418d6 security: add authentication to /api/security/apply-restart endpoint
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.
2026-02-03 19:55:29 +00:00
rcourtman 832fda6c96 security: add scope checks to alerts, AI models, patrol status/stream, and remaining AI endpoints
- /api/alerts/* now requires monitoring:read scope
- /api/ai/models now requires ai:chat scope
- /api/ai/patrol/status and /api/ai/patrol/stream now require ai:execute scope
- /api/ai/patrol/findings now requires ai:execute scope
- /api/ai/remediation/* endpoints now require ai:execute scope
- /api/ai/circuit/status now requires ai:execute scope
- /api/ai/incidents/* now requires ai:execute scope
- /api/ai/question/* now requires ai:chat scope
- /api/ai/agents now requires ai:execute scope
- /api/ai/cost/summary now requires settings:read scope
2026-02-03 19:48:43 +00:00
rcourtman c295ee277f security: add scope checks to AI endpoints and mitigate CSWSH
- 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
2026-02-03 19:40:46 +00:00
rcourtman 2ebe65bbc5 security: add scope checks to AI Patrol and agent profile endpoints
- AI Patrol mutation endpoints (acknowledge, dismiss, suppress, snooze, resolve,
  findings/note, suppressions/*) now require ai:execute scope to prevent
  low-privilege tokens from blinding patrol by hiding/suppressing findings

- Agent profile admin endpoints (/api/admin/profiles/*) now require
  settings:write scope to prevent low-privilege tokens from modifying
  fleet-wide agent behavior
2026-02-03 19:29:56 +00:00
rcourtman 69e3286e5e security: fix AI OAuth scope bypass, approval replay attacks, and approval endpoint scope gating
- 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
2026-02-03 19:15:15 +00:00
rcourtman 43c696896f security: fix high severity authz issues (AI chat, patrol autonomy, discovery, host config) 2026-02-03 19:00:56 +00:00
rcourtman 4fdc0cae64 feat(reporting): enrich metric reports with detailed resource info 2026-02-03 18:51:27 +00:00
rcourtman 225da6eb39 security: strengthen public URL capture to enforce scope and admin checks 2026-02-03 18:49:42 +00:00
rcourtman 83382ee251 security: enforce scope checks on admin diagnostics endpoint 2026-02-03 18:44:55 +00:00
rcourtman 8f92273e33 security: enforce scope checks for AI approvals and config management 2026-02-03 18:40:31 +00:00
rcourtman 60f9e6f07f security: fix multiple vulnerabilities (SAML, SSRF, Auth)
Addressed several security findings:
- SAML: Sanitized RelayState to prevent open redirects
- SAML: Fixed logout to properly invalidate server-side sessions
- Auth: Added auth, rate limiting, and logout checks to password change endpoint
- AI: Added admin/scope gating (ai:execute) for command execution
- AI: Blocked private IP ranges in fetch_url to prevent SSRF
- Config: Enforced settings:read/write scopes for export/import
- Agent: Added agent:exec scope requirement for WebSockets
2026-02-03 18:39:15 +00:00
rcourtman 442d29e9b9 feat(reporting): enhance PDF reports with Executive Summary and actionable insights
- Add professional cover page with branding and report period
- Add Executive Summary page with health status banner (HEALTHY/WARNING/CRITICAL)
- Add Quick Stats section with color-coded metrics and trend indicators
- Add Key Observations with automated analysis of CPU, memory, disk, and disk wear
- Add Recommended Actions section with prioritized, actionable items
- Add Resource Details page with hardware info, storage pools, physical disks
- Add color-coded tables for alerts, storage, and disk health
- Add performance charts with area fills and proper scaling
- Improve overall visual design with consistent color scheme
- Fix SAML session invalidation to use correct SessionStore method
2026-02-03 18:17:31 +00:00
rcourtman 2e4e7b06a8 fix(tests): update reporting handlers tests to match new signature
NewReportingHandlers now requires a MultiTenantMonitor parameter.
Pass nil since the tests don't need the monitor functionality.
2026-02-03 17:48:44 +00:00
rcourtman d716bbfdeb fix(security): add proper authorization to sensitive endpoints
- /api/agent-install-command: require admin + settings:write scope
  Previously only RequireAuth, allowing any authenticated user to mint
  high-privilege API tokens (host-agent:manage)

- /api/system/ssh-config: require settings:write scope
  Previously any authenticated token could modify ~/.ssh/config

- /api/system/verify-temperature-ssh: require settings:write scope
  Previously any authenticated token could trigger SSH connection
  attempts to arbitrary nodes (network scanning risk)

- /api/diagnostics: require admin privileges
  Previously exposed API token metadata (IDs, hints, usage mapping)
  to any authenticated token, enabling enumeration attacks
2026-02-03 17:47:40 +00:00
rcourtman 12a5a98117 fix: SSE race conditions, alert user spoofing, and security status oracle
SSE Broadcaster:
- Add per-client mutex to prevent concurrent writes to ResponseWriter
- Fix data race in cleanupLoop reading LastActive without synchronization
- Update LastActive in SendHeartbeat so clients aren't incorrectly pruned
  after 5 minutes of idle heartbeat traffic

Alert Acknowledgements:
- Extract authenticated user from X-Authenticated-User header instead of
  hardcoding 'admin' or trusting request body's User field
- Prevents audit log spoofing and ensures accurate user attribution

Security Status Endpoint:
- Remove ?token= query param validation from public /api/security/status
- Prevents endpoint from acting as a token validity oracle for attackers
- Authentication still works via session cookies and X-API-Token header
2026-02-03 17:40:58 +00:00
rcourtman beae4c860c fix: address 6 security and reliability issues
Security fixes:
- Auto-register now requires settings:write scope for API tokens
- X-Forwarded-For in auto-register only trusted from verified proxies
- Public URL capture requires authentication (no loopback bypass)
- Lockout reset now uses RequireAdmin for session users

Reliability fixes:
- Docker stop command expiration clears PendingUninstall flag
- Cancelled notifications get completed_at set and are cleaned up
2026-02-03 17:32:44 +00:00
rcourtman b2639ed5a5 Fix security vulnerabilities and critical bugs
- Fix WebSocket CORS bypass by strictly verifying origin
- Fix OIDC refresh token persistence by encrypting at rest
- Fix grouped webhook data mutation by cloning alerts
- Fix host agent uninstall authorization and config fetch logic
- Fix notification queue recovery for stuck sending items
- Fix ignored update history limit parameter
- Fix ineffective break statement in WebSocket write pump
2026-02-03 17:16:27 +00:00
rcourtman bd030c7c87 security: fix webhook SSRF, rate limit spoofing, metrics retention, and url poisoning
- Fix SSRF and rate limit bypass in SendEnhancedWebhook by validating the rendered URL.
- Fix rate limit spoofing in updates API by using secure IP extraction (trusted proxies).
- Fix memory leak in metrics history by correctly clearing fully stale data series.
- Fix public URL poisoning by preventing overwrites when explicitly configured.
2026-02-03 16:58:13 +00:00
rcourtman 4f40c3d751 fix: resolve critical stability and auth issues
- Fix data race in webhook notifications by removing shared state
- Fix duplicate monitors on config reload by stopping old instances
- Prevent metrics ID deletion on transient startup errors
- Support Bearer auth header for config export/import endpoints
2026-02-03 16:46:27 +00:00
rcourtman 935326ebb7 fix(api/ai): resolve critical auth, agent download, and lifecycle issues
- Fix API-only mode to accept Bearer tokens and query params
- Fix data race in API token validation using fine-grained locking
- Fix unified agent download serving wrong binary for invalid arch
- Fix AI infra discovery running when AI disabled and missing stop mechanism
2026-02-03 16:35:12 +00:00
rcourtman 3d8374e527 Fix AI investigation context and UI settings
- Ensure correct org context is used for AI chat service resolution

- Fix AI adapter tests

- Update AI Intelligence page UI for advanced settings
2026-02-03 16:24:56 +00:00
rcourtman bea3bbe5f6 Fix API token authentication and multi-tenancy logic
- Fix AuthContextMiddleware to use tenant-specific config for token validation

- Resolve data race in token LastUsedAt update

- Fix invalid org IDs returning 501/402 instead of 400

- Prevent unauthenticated organization directory creation (DoS protection)
2026-02-03 16:24:28 +00:00
rcourtman 88d95f40be feat: add Discovery Transparency & Trust features
- Add AI provider indicator showing local (Ollama) vs cloud (Anthropic/OpenAI) analysis
- Add "What Discovery Does" explanation section before first scan
- Show commands preview before scan so users know what will run
- Add scan details section showing raw command outputs for admins
- Filter sensitive Docker labels (passwords, secrets, tokens) before AI analysis
- Add comprehensive tests for label filtering

This improves sysadmin confidence by making discovery transparent about
what it does, what data it collects, and where that data goes.
2026-02-03 14:59:27 +00:00
rcourtman c2ed6067f1 Fix: discovery routing, host identification, and UX feedback
- Fix routing for POST/PUT/DELETE on /api/discovery/host/ endpoints
  (Go's http.ServeMux was matching the longer prefix before method-specific routes)
- Add HOST-specific AI prompt that focuses on identifying the host OS
  rather than services/containers running on it
- Add success message UI after discovery completes
- Fix timing so success appears after data is visible (not during refetch)
- Add error handling and display for failed discoveries
2026-02-03 14:10:54 +00:00
rcourtman a55ae78715 Revert "Add config option to disable tools for OpenAI-compatible endpoints"
This reverts commit 81229f206f.
2026-02-03 13:26:26 +00:00
rcourtman 81229f206f Add config option to disable tools for OpenAI-compatible endpoints
Some local LLM servers (LM Studio, llama.cpp) expose OpenAI-compatible
APIs but don't support function calling. When tools are sent to these
models, they output raw control tokens instead of proper responses.

This change adds:
- openai_tools_disabled config field in AIConfig
- AreToolsDisabledForProvider() method to check at runtime
- API support to get/set the new setting
- Tests for the new functionality

When enabled and using a custom OpenAI base URL, the chat service will
skip sending tools to the model, allowing basic chat functionality to
work even with models that don't support function calling.

Fixes #1154
2026-02-03 13:21:44 +00:00
rcourtman 744eeb0270 Chore: clean up staged changes for release
- Remove standalone pulse-assistant architecture doc (content lives in CLAUDE.md)
- Add CountdownTimer component for patrol schedule display
- Rewrite patrol handler test to focus on interval persistence
- Extract MockStateProvider to shared test file
2026-02-02 23:17:40 +00:00
rcourtman 02946d45ec test: expand api handler coverage 2026-02-02 23:01:29 +00:00
rcourtman bfa648ddd5 Test: expand api feature test coverage
Add tests for AI intelligence, Docker/K8s agents, log redaction, and general router helper functions.
2026-02-02 22:02:22 +00:00
rcourtman 43d7fffeef Test: add coverage for auth and security handlers
Add additional tests for OIDC, SAML, and tenant middleware to improve coverage of security-critical paths.
2026-02-02 22:02:11 +00:00
rcourtman 97a985efb8 Test: improve frontend embedding coverage
Enhance tests for frontend embedding to cover filesystem overrides, dev proxy configuration, and SPA header handling.
2026-02-02 22:01:46 +00:00
rcourtman eb2d07e48f Chore: enhance core api and metrics testability
Refactor Router to allow HTTP client injection for install script proxying. Add tests for unified agent install mechanism and additional metrics store coverage.
2026-02-02 22:01:36 +00:00