Commit Graph

7 Commits

Author SHA1 Message Date
Proudlock
d11ba5c5d6 Add server certificate management UI (Settings > Endpoints > Server Certificate)
Operational Feature: Web UI for TLS certificate management

Problem:
- Server certificate (nginx HTTPS) managed manually via certs/ directory
- No visibility into cert expiry from UI
- Regeneration required command-line OpenSSL knowledge
- No warning when cert approaching expiration
- Agents using thumbprint pinning need new thumbprint after renewal

Solution:
- New admin-only settings page: Settings > Endpoints > Server Certificate
- View current certificate details (CN, SANs, expiry, thumbprint)
- Warning banner when cert expires within 30 days
- Generate self-signed certificate (configure CN, SANs, validity)
- Upload CA-signed certificate (PEM format)
- Automatic nginx restart after certificate changes
- Copy-to-clipboard for agent thumbprint pinning

Frontend:
- plugins/endpoints/frontend/views/ServerCertSettings.vue
  - Certificate status display with expiry countdown
  - Self-signed generation form (CN, SANs, days)
  - CA certificate upload (cert + key files)
  - Documentation collapsibles (requirements, pinning, air-gapped)
- plugins/endpoints/frontend/routes.js
  - Route: /settings/endpoints/server-cert (admin-only)

Backend API:
- plugins/endpoints/api/routes.py
  - GET /api/endpoints/settings/server-cert (view cert details)
    - Uses openssl to extract CN, issuer, dates, thumbprint, SANs
    - Calculates days until expiry (warns if < 30)
    - Returns self-signed status
  - POST /api/endpoints/settings/server-cert/generate
    - Generates self-signed cert with custom CN/SANs/validity
    - Backs up old certificate with timestamp
    - Writes new cert/key to certs/ directory
    - Restarts nginx (docker-compose restart nginx)
    - Audit logged: endpoints.server_cert.generated
  - POST /api/endpoints/settings/server-cert/upload
    - Validates PEM format (cert + unencrypted key)
    - Backs up old certificate
    - Writes uploaded files to certs/
    - Restarts nginx automatically
    - Audit logged: endpoints.server_cert.uploaded
  - All endpoints admin-only (@require_role('admin'))

Navigation:
- plugins/endpoints/plugin.py
  - Added menu item: Settings > Endpoints > Server Certificate
  - Icon: shield-check, Position: 29

Security:
- Admin-only access (certificate management is privileged operation)
- Private key validation (rejects encrypted keys)
- Certificate format validation (PEM-encoded)
- Audit logging for all cert operations
- Automatic backup before replacement (timestamped .backup files)

Operational Notes:
- Certificate changes restart nginx (brief HTTPS interruption)
- Agents using ServerCertThumbprint pinning must be updated after renewal
- Self-signed certs valid 1 year by default (configurable)
- Air-gapped sites: cert files in certs/ directory bundled automatically

Related:
- Complements certs/README.md and regeneration scripts (commit fd6240772e)
- Agents validate via Windows roots or thumbprint pinning (CertificateRenewal.cs)
- Client certificate renewal uses same nginx TLS surface (routes.py:3455)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-14 15:07:54 -04:00
benjamin.baker
fd18099199 Gate the script library on the grant that pushes scripts
The script library was gated on applications.*, so anyone holding the
software-delivery grant could rewrite the bytes of a script that a separately
trusted operator later pushed to a bay. The push was gated on
endpoints.runscript; the CONTENT of what got pushed was not. An installer is a
vendor artefact, but a script here is arbitrary PowerShell this site wrote that
the agent runs as SYSTEM, so the write and the push must require the same
trust.

All six script routes now require endpoints.runscript, including the body
download - reading the bytes is not a lesser act than listing them. Core names
the permission as a string rather than importing it from the endpoints plugin
so the module stays importable with the plugin absent.

This tightens access and there is deliberately no backfill: the operator scope
reaches applications.create/edit, so operator-scope holders lose the library.
Granting them endpoints.runscript on upgrade would undo the change and hand
every operator remote SYSTEM code execution, since the same grant gates the
push. A test pins that no prebuilt scope confers it.

Adds the System Scripts settings page and card. The route requires the
permission rather than admin, because the grant is meant for non-admin
operators and the sibling admin gate would lock them out of the library the
grant exists for. The settings icon map gains terminal and key; the agent-key
card had been asking for key since it shipped and silently drawing a puzzle
piece.

The library had no test coverage before this.
2026-09-09 06:37:02 -04:00
benjamin.baker
187d371453 Remove the delivery test bench
The delivery test bench and its notes were scaffolding for validating the software-delivery path during development. That work is complete and covered by tests, so the bench is removed along with its route registration rather than left in the shipped UI where it would read as a supported feature.
2026-09-07 12:39:46 -04:00
benjamin.baker
42db980ca9 Add endpoint monitor catalog and warn-only drift reconciler
Operators need to see when a machine's running services or processes fall outside the desired state defined by policy. This adds a reusable monitor catalog (shipped read-only rows plus user-built local rows), computes drift server-side on agent check-in, and surfaces a warning on the endpoint panels. Remediation stays manual for now; automation can follow once demand is proven. Includes migrations 0006-0008 and the monitors API client.
2026-09-01 15:44:03 -04:00
benjamin.baker
188296ef58 Add endpoint software delivery: run_script and update_app push
Adds the two delivery actions to the endpoints command allowlist, each gated on a new endpoints.deploy permission ON TOP OF endpoints.command so pushing software is a heavier grant than a routine toggle. Enqueue validates update_app appversionid ownership and installer presence before queueing. New collector-authenticated download routes let the agent fetch installer packages and script bodies by digest rather than pre-staging them or sending bodies over the command wire. Wires the scriptsApi client, the siteagent generator routes, and a temporary dev-only Delivery test bench (view/route/nav) for exercising the path while the production UI is built.
2026-08-30 14:40:51 -04:00
benjamin.baker
01734e5449 harden CSV import reconciliation and preserve saved model selections
Default fuzzy reconcile threshold to 0 and refuse merges when digit runs differ so numbered labels like Bay 311 never bind to Bay 310. Keep edit forms from clearing saved model fields when category filtering hides untyped rows. Includes in-progress computers policy and endpoints command feature work.
2026-08-28 09:29:09 -04:00
benjamin.baker
8b1ba3c310 add endpoints plugin with fleet list view and monitoring drafts
Server-side RMM telemetry plugin: current-snapshot endpointstates plus append-only curated endpointevents, resolved to existing Computer assets by hostname. Adds ADR-010 asset panels (status, services, recent events), dashboard quiet and stability cards, and a minimal Fleet list view that links into existing PC detail pages. Registers the activity sidebar icon and a dev-only sample seeder. Ingest arrives on the generic collector route; the future C# agent design record lives in docs/DESIGN-DECISIONS-agent.md.
2026-08-27 05:41:06 -04:00