Private
Public Access
1
0

feat(M11+M12): Email notifications, audit hardening, deployment packaging, backup/DR, integration testing

M11 - Email Notifications + Audit Logging Hardening:
- Email notifier (lettre crate) with templates for patch failure, job completion, maintenance reminders
- Audit log hash chaining (prev_hash + row_hash) for tamper-evident logging
- Periodic + on-demand audit integrity verification
- Audit logging for all config changes and certificate operations
- Frontend: email settings integration, audit integrity verification action

M12 - Deployment Packaging, Backup/DR, Integration Testing:
- scripts/backup.sh: Nightly pg_dump, CA backup (GPG), config backup (secrets excluded unless encrypted)
- scripts/setup.sh: Enhanced with backup dir, seed migration, backup cron, systemd target install
- systemd units: Restart=always, WatchdogSec, ReadWritePaths, security hardening
- systemd/patch-manager.target: Service target for coordinated lifecycle
- docs/runbooks/restore.md: Full DR runbook with RPO 24h / RTO 4h targets
- scripts/integration-test.sh: 9 test suites covering full API lifecycle
- scripts/performance-test.sh: NFR validation (dashboard <5s, CIDR /22 <10s, API <2s)
- docs/security-review.md: Comprehensive security control verification
- docs/compliance-mapping.md: HIPAA (6 sections) + PCI-DSS v4.0 (9 requirements) mapped
This commit is contained in:
2026-04-24 00:45:51 +00:00
parent 84ab92f4f0
commit 297bf1bd83
26 changed files with 2651 additions and 65 deletions

View File

@ -1,9 +1,11 @@
//! pm-worker — Linux Patch Manager background worker.
//!
//! Handles scheduled polling, job execution, maintenance window scheduling,
//! retry logic, email notifications, and data pruning.
//! retry logic, email notifications, audit integrity verification, and data pruning.
mod agent_loader;
mod audit_verifier;
mod email;
mod health_poller;
mod maintenance_scheduler;
mod patch_poller;
@ -20,6 +22,7 @@ use sqlx::PgPool;
use std::{sync::Arc, time::Duration};
use tokio::time;
use audit_verifier::run_audit_verifier;
use health_poller::run_health_poller;
use maintenance_scheduler::run_maintenance_scheduler;
use patch_poller::run_patch_poller;
@ -30,7 +33,7 @@ use ws_relay::run_ws_relay;
/// Minimum number of applied migrations the worker requires before
/// accepting work. Prevents the worker from running against a schema
/// that hasn't been migrated yet.
const REQUIRED_MIGRATION_COUNT: i64 = 1;
const REQUIRED_MIGRATION_COUNT: i64 = 5;
/// How long to wait between schema-version checks before giving up.
const SCHEMA_CHECK_TIMEOUT: Duration = Duration::from_secs(120);
@ -80,6 +83,9 @@ async fn main() -> anyhow::Result<()> {
// M7: WS relay — streams agent job events → DB → pg_notify → browser WS
let ws_relay_handle = tokio::spawn(run_ws_relay(pool.clone(), config.clone()));
// M11: audit integrity verification (runs every 24 hours)
let audit_verifier_handle = tokio::spawn(run_audit_verifier(pool.clone(), config.clone()));
tracing::info!("Worker tasks started");
// Wait for all tasks (they run indefinitely)
@ -91,6 +97,7 @@ async fn main() -> anyhow::Result<()> {
job_exec_handle,
maint_sched_handle,
ws_relay_handle,
audit_verifier_handle,
);
Ok(())