da3dffd81f
feat: add host self-enrollment workflow v0.1.7
CI Pipeline / Rust Format Check (push) Successful in 5s
CI Pipeline / Clippy Lints (push) Successful in 53s
CI Pipeline / Rust Unit Tests (push) Successful in 1m11s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 14s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-05-16 17:03:28 +00:00
7b067b2813
Phase 4: Exhaustive analysis fixes, security hardening, and code quality improvements
2026-05-15 22:10:05 +00:00
d76450759a
fix: add public SSO config endpoint for login page
...
The SSO button on the login page was not appearing because the settings
API requires authentication, but the login page cannot authenticate before
the user logs in.
Changes:
- Backend: Add GET /api/v1/auth/sso/config public endpoint that returns
only enabled, display_name, and auth_url (no secrets exposed)
- Backend: Mount sso::public_router() at /api/v1/auth/sso in main.rs
(was previously missing - only azure_compat_router was mounted)
- Frontend: Replace settingsApi.get() call in LoginPage.tsx with
ssoConfigApi.get() which calls the public endpoint
- Frontend: Add SsoConfigResponse interface and ssoConfigApi helper
to client.ts
- Frontend: Use auth_url from config response instead of hardcoded path
2026-05-13 14:53:12 +00:00
69d2e88bbd
feat: OIDC SSO provider support (Keycloak, Azure AD, custom)
...
CI Pipeline / Rust Format Check (push) Successful in 4s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m11s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Refactored azure_sso.rs to sso.rs with generic OIDC provider support
- Added OIDC discovery URL lookup with 1hr TTL caching
- Added PKCE for all providers, client_secret optional for public clients
- Added /api/v1/auth/sso/login and /api/v1/auth/sso/callback routes
- Added /api/v1/auth/azure/* backward-compatible routes
- Added POST /settings/sso/discover and POST /settings/sso/test endpoints
- Frontend: Provider dropdown (Keycloak/Azure AD/Custom OIDC)
- Frontend: Auto-fill discovery URL for Keycloak
- Frontend: Discover Endpoints and Test Connection buttons
- Frontend: Dynamic SSO button based on provider display name
- Made migration 014 idempotent with DO blocks and IF NOT EXISTS
- Fixed debian/install to use /usr/local/bin/ for binaries
- Fixed frontend file path in .deb package
- Reset admin password on dev server
- Fixed database permissions for oidc_config table
2026-05-13 13:32:24 +00:00
cc1214a963
feat: Phase 4 - password validation, force password reset flow, account lockout, QR code for MFA
CI Pipeline / Rust Format Check (push) Failing after 6s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m2s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-05-07 17:53:16 +00:00
0a70afbbe9
feat: Phase 1 - user/password API extensions and auth route fix
CI Pipeline / Rust Format Check (push) Failing after 5s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-05-07 16:21:53 +00:00
0e9cb1c915
fix: add HealthCheckListResponse type to match API response structure
...
CI Pipeline / Rust Format Check (push) Successful in 6s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Added HealthCheckListResponse type { checks: [...], total: number }
- Updated healthChecksApi.list() return type to HealthCheckListResponse
- Fixed HostDetailPage to use res.data?.checks instead of Array.isArray
- Added Target column to health checks table
- Added git pre-commit/pre-push hooks to prevent format CI failures
- Updated lessons.md
2026-05-06 16:18:29 +00:00
aa0cb9ab3c
feat: cert bundle download with CA root, re-issue endpoint, and enhanced cert UI
CI Pipeline / Rust Format Check (push) Failing after 4s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m2s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-05-05 23:06:48 +00:00
1aa90c7eb0
fix: add host creation form for Add Host button
CI Pipeline / Rust Format Check (push) Failing after 5s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m3s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-05-05 20:48:14 +00:00
93828e1976
feat: health check configuration and worker engine (Phase 3+4)
...
CI Pipeline / Rust Format Check (push) Failing after 4s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Added health_check_poller.rs: periodic service/HTTP health checks
- Added pre-patch health gate in job_executor.rs
- Added waiting_health_check job status (migration 008)
- Added health_check_status to HostSummary and hosts API
- Added health check types and API functions to frontend
- Added health check UI section to HostDetailPage
- Added health check status indicators to HostsPage and PatchDeploymentPage
- Added serde default for health_check_poll_interval_secs
- Fixed missing AgentClient import in health_check_poller.rs
- Fixed missing ws_relay import in main.rs
- Fixed missing closing paren in retry_pending_jobs SQL
- Added ReadWritePaths for /etc/patch-manager/keys in systemd services
2026-05-05 14:10:37 +00:00
eec976d093
fix: graceful login error handling and remove hard redirects
...
CI Pipeline / Rust Format Check (push) Failing after 35s
CI Pipeline / Clippy Lints (push) Successful in 45s
CI Pipeline / Rust Unit Tests (push) Successful in 1m2s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 13s
CI Pipeline / Build .deb & Release (push) Has been skipped
- LoginPage.tsx: proper error handling for network errors, rate limiting
(429), MFA required, account disabled, and server errors
- LoginPage.tsx: dismissible error alerts with onClose
- LoginPage.tsx: added 🐉 branding to login title
- client.ts: removed window.location.href hard redirects on auth failure
(now uses React state-based logout instead of full page reload)
- client.ts: auth errors now propagate naturally through React Router
2026-04-29 01:27:58 +00:00
f00853b5c0
Fix ESLint warnings with disable comments for legitimate cases
CI Pipeline / Rust Format Check (push) Successful in 5s
CI Pipeline / Clippy Lints (push) Successful in 44s
CI Pipeline / Rust Unit Tests (push) Successful in 59s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 11s
CI Pipeline / Build .deb & Release (push) Has been skipped
2026-04-27 21:59:50 +00:00
2fd3eb89b4
Fix all frontend ESLint errors
...
CI Pipeline / Rust Format Check (push) Successful in 3s
CI Pipeline / Clippy Lints (push) Successful in 45s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 3s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 4s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Add eslint-plugin-react-hooks to package.json and config
- Fix duplicate imports in HostsPage.tsx
- Remove non-null assertion in main.tsx
- Fix != to !== in HostDetailPage.tsx and MaintenanceWindowsPage.tsx
- Fix unused variable in ReportsPage.tsx
- Change console.debug to console.warn in useJobWebSocket.ts
2026-04-27 21:20:25 +00:00
297bf1bd83
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
2026-04-24 00:45:51 +00:00
84ab92f4f0
feat(M10): Settings page - Azure SSO, SMTP, polling, IP whitelist, TLS strategy
2026-04-23 21:40:37 +00:00
7b7fac315e
feat(M8+M9): CA certificates page + Reporting CSV/PDF with charts
2026-04-23 18:56:11 +00:00
a5d52ffab0
feat: M6 maintenance windows + M7 WebSocket relay (real-time job status)
...
M6 - Maintenance Windows:
- routes/maintenance_windows.rs: full CRUD API
- migrations/004_maintenance_windows.sql
- frontend/MaintenanceWindowsPage.tsx
- HostDetailPage.tsx: maintenance window config panel
M7 - WebSocket Relay:
- pm-web: POST /api/v1/ws/ticket (JWT-auth, single-use, 60s TTL)
- pm-web: WS /api/v1/ws/jobs?ticket=... (PgListener -> browser push)
- pm-web: DashMap<String,WsTicket> in AppState, 30s cleanup task
- pm-worker: ws_relay.rs subscribes to agent WS, updates patch_job_hosts,
fires pg_notify(job_update) for real-time fan-out
- frontend: useJobWebSocket hook with auto-reconnect + exponential backoff
- frontend: JobsPage live updates with WS status indicator
- types: JobWsEvent interface
- api/client: wsApi.createTicket()
All tasks marked complete in tasks/todo.md
cargo build: zero errors, zero warnings
2026-04-23 17:42:51 +00:00
6f9c6dc881
M5: Patch Deployment & Job Management
...
Backend:
- migrations/003_jobs_scheduling.sql: retry_next_at/last_error columns,
pg_notify trigger for immediate job dispatch, retry index
- pm-agent-client: ApplyPatchesRequest/Response, AgentJobStatus,
RollbackResponse types; apply_patches/job_status/rollback_job
client methods + generic POST helper
- pm-core/models: JobStatus, JobKind, PatchJob, PatchJobHost,
CreateJobRequest, PatchJobSummary
- pm-web/routes/jobs.rs: POST/GET /api/v1/jobs, GET /jobs/:id,
POST /jobs/:id/cancel, POST /jobs/:id/rollback
- pm-worker/job_executor.rs: NOTIFY listener, periodic scanner,
execute_host_job, poll_running_jobs, handle_host_failure (3-retry
exponential backoff 1m/5m/30m), sync_job_status, retry_pending_jobs
- pm-worker/main.rs: spawn job_executor
Frontend:
- types/index.ts: PatchInfo, PatchJobHost, PatchJob, PatchJobSummary,
CreateJobRequest interfaces
- api/client.ts: jobsApi (list/get/create/cancel/rollback),
patchesApi (getHostPatches)
- pages/PatchDeploymentPage.tsx: 3-step MUI Stepper
(host select → configure → result)
- pages/JobsPage.tsx: job list table, expandable per-host detail,
cancel/rollback actions with confirm dialog, load-more pagination
- App.tsx: /jobs and /deployment routes wired to real pages
cargo check: 0 errors | vite build: 0 errors
2026-04-23 17:08:43 +00:00
6811f84a7c
feat(M2): Authentication, Authorization & Frontend Shell
...
- pm-auth::password: Argon2id (m=65536,t=3,p=1) hashing + verification
- pm-auth::jwt: EdDSA/Ed25519 JWT issuance + validation (15-min TTL)
- pm-auth::refresh: Opaque 256-bit refresh tokens, SHA-256 hashed,
1-hour sliding inactivity timeout, rotation on use, revocable
- pm-auth::mfa_totp: TOTP setup/verify (HMAC-SHA1, 6-digit, 30s)
with otpauth:// URI generation (Google Authenticator compatible)
- pm-auth::mfa_webauthn: Stub (full implementation deferred)
- pm-auth::rbac: Axum middleware for JWT auth + IP whitelist +
admin/operator role enforcement + FromRequestParts extractor
- pm-auth::session: Full login flow (password → MFA → tokens),
token refresh, logout, force-logout
- pm-web auth routes: POST /api/v1/auth/login|refresh|logout,
GET /api/v1/auth/mfa/setup, POST /api/v1/auth/mfa/verify
- IP whitelist middleware on all protected connection points
- migrations/002_seed_admin.sql: Default admin account seed
- Frontend: Auth store (Zustand with persistence), login page with
MFA prompt, MFA setup page (stepper), JWT auto-refresh interceptor,
route guards (RequireAuth), updated App.tsx routing
- cargo check --workspace: zero errors, 1 minor warning
Closes M2.
2026-04-23 16:10:08 +00:00
da5a94d838
feat(M1): Project scaffolding, DB schema, core infrastructure
...
- Initialize Rust workspace with 7 crates (pm-web, pm-worker, pm-core,
pm-agent-client, pm-auth, pm-ca, pm-reports)
- React + TypeScript + Vite + MUI frontend scaffold
- Full PostgreSQL schema: all 17 tables with indexes and constraints
- pm-core: config (TOML+env), db (SQLx pool + migrations), error
(unified AppError + JSON envelope), request_id (ULID middleware),
logging (tracing JSON/pretty)
- pm-web: Axum skeleton, /status/health endpoint, static file serving
- pm-worker: Tokio skeleton, heartbeat writer, schema version check
- Embedded sqlx migrations with advisory lock (single-writer)
- systemd unit files, setup.sh, build-frontend.sh
- config.example.toml with all configuration keys
- docs/runbooks/restore.md
- cargo check passes with zero warnings
Closes M1.
2026-04-23 15:55:53 +00:00