feat(settings): surface security, notifications, and app store on remote nodes (#716)

Flip Security (Trivy), Notifications (agents + history), and App Store from
global-and-hidden-on-remote to node-scoped so operators can manage them when a
remote node is selected in the node picker. The primary instance proxies the
calls to each remote, which resolves the correct per-instance binary state,
agent config, and template registry.

Backend: key `agents` and `notification_history` by `node_id` with idempotent
column-add migrations and a `(node_id, type)` unique index on agents, matching
the Labels pattern. Thread `req.nodeId` through the /api/agents and
/api/notifications routes. Internal NotificationService and ImageUpdateService
writes resolve the middleware default via `NodeRegistry.getDefaultNodeId()` so
monitor-emitted rows share a bucket with user-facing ones (avoids split-brain
where the UI sees test notifications but not internal alerts).

Frontend: split Security on remote to render only the scanner card and hide
scan policies and CVE suppressions (those remain control-plane-only). Drop the
misleading "Always Local" badge on Developer since retention windows govern
backend jobs, not UI state. Flip the App Store registry to node-scoped.

Docs: add a "What Settings apply per node" table to multi-node, clarify
remote alert setup in alerts-notifications, and note Trivy's per-host install
in vulnerability-scanning.
This commit is contained in:
Anso
2026-04-20 21:04:09 -04:00
committed by GitHub
parent a42cc5bf03
commit 08f57c7141
14 changed files with 172 additions and 95 deletions
+16
View File
@@ -83,6 +83,22 @@ Click the **calendar icon** on any node row to jump directly to the Schedules vi
When a node is deleted, all scheduled tasks and update status data associated with it are automatically cleaned up.
## What Settings apply per node
When you select a remote node in the node picker, the Settings hub filters to the panels that control that specific instance. Values saved here never cross over to other nodes.
| Panel | Scope | Notes |
|-------|:-----:|-------|
| Appearance | Per browser | Density and theme preferences are stored in your browser, not on the node. |
| System Limits | Per node | Host CPU, RAM, disk, and crash-loop thresholds for the selected node. |
| Notifications | Per node | Discord, Slack, and Webhook channels fire from the node that detects the event. |
| Labels | Per node | Stack and container label palettes. |
| Security | Per node | Trivy install, update, and scanner status. Scan policies and CVE suppressions are managed on the control node and apply fleet-wide. |
| Developer | Per node | Retention windows for metrics and logs, plus Developer Mode. |
| App Store | Per node | Template registry URL for the selected node's catalog. |
Panels that manage control-plane concerns (Account, License, Users, SSO, API Tokens, Registries, Nodes, Routing, Webhooks) are hidden when a remote node is active.
## License enforcement across nodes
When you have a paid license (Skipper or Admiral) on your primary instance, all remote nodes automatically inherit that license tier for proxied requests. You do not need to activate a license on each remote node separately.