import { OperationsHealth, SafeAuditEvent, ComponentHealthStatus, HealthComponentKey, } from '../components/ops/types'; export const HEALTH_COMPONENT_METADATA: Record< HealthComponentKey, { name: string; description: string } > = { operations_api: { name: 'Operations API', description: 'FastAPI core endpoint runtime & ingress', }, operations_database: { name: 'Operations Database', description: 'PostgreSQL ops schema relational persistence', }, session_validation: { name: 'Session Validation', description: '__Host-motorsignal_ops token verification & authority', }, audit_persistence: { name: 'Audit Persistence', description: 'Immutable operational security activity persistence', }, }; export const APPROVED_AUDIT_METADATA_KEYS = new Set([ 'component', 'status_code', 'subsystem', 'duration_ms', 'policy', 'action_scope', 'session_valid', 'mfa_verified', 'migration_version', 'records_affected', ]); export function isValidHealthStatus(status: unknown): status is ComponentHealthStatus { return ( status === 'available' || status === 'degraded' || status === 'unavailable' || status === 'unknown' ); } export function normalizeHealthResponse(raw: unknown): OperationsHealth { const fallbackCheckedAt = new Date().toISOString(); if (!raw || typeof raw !== 'object') { return { status: 'unavailable', checked_at: fallbackCheckedAt, components: { operations_api: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_api.description }, operations_database: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_database.description }, session_validation: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.session_validation.description }, audit_persistence: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.audit_persistence.description }, }, }; } const obj = raw as Record; const rawStatus = obj.status; const overallStatus: ComponentHealthStatus = isValidHealthStatus(rawStatus) ? rawStatus : 'unknown'; const checkedAt = typeof obj.checked_at === 'string' && obj.checked_at.length > 0 ? obj.checked_at : fallbackCheckedAt; const rawComponents = obj.components && typeof obj.components === 'object' ? (obj.components as Record) : {}; const keys: HealthComponentKey[] = [ 'operations_api', 'operations_database', 'session_validation', 'audit_persistence', ]; const components: Record< HealthComponentKey, { status: ComponentHealthStatus; description: string } > = { operations_api: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_api.description }, operations_database: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_database.description }, session_validation: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.session_validation.description }, audit_persistence: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.audit_persistence.description }, }; for (const key of keys) { const rawComp = rawComponents[key] as Record | undefined; const compStatus = rawComp && isValidHealthStatus(rawComp.status) ? rawComp.status : isValidHealthStatus(obj[key]) ? (obj[key] as ComponentHealthStatus) : overallStatus; components[key] = { status: compStatus, description: (rawComp?.description as string) || HEALTH_COMPONENT_METADATA[key].description, }; } return { status: overallStatus, checked_at: checkedAt, components, }; } export function sanitizeAuditEvent(raw: unknown): SafeAuditEvent | null { if (!raw || typeof raw !== 'object') { return null; // Fail closed } const obj = raw as Record; // Required: timestamp (ISO string) if (typeof obj.timestamp !== 'string' || !obj.timestamp.trim()) { return null; } const timestamp = obj.timestamp.trim(); // Required: action if (typeof obj.action !== 'string' || !obj.action.trim()) { return null; } const action = obj.action.trim(); // Required: result if (typeof obj.result !== 'string' || !obj.result.trim()) { return null; } const result = obj.result.trim(); // Required: actor_identity (exact OPS-3B contract, no actor_email alias) if (typeof obj.actor_identity !== 'string' || !obj.actor_identity.trim()) { return null; // Fail closed: missing verified identity } const actor_identity = obj.actor_identity.trim(); // Optional transport ID (unrendered in UI) const id = typeof obj.id === 'string' && obj.id.trim() ? obj.id.trim() : undefined; // Optional: actor_role const actor_role = typeof obj.actor_role === 'string' && obj.actor_role.trim() ? obj.actor_role.trim() : undefined; // Optional: target_resource (exact OPS-3B contract, no target alias) const target_resource = typeof obj.target_resource === 'string' && obj.target_resource.trim() ? obj.target_resource.trim() : undefined; // Optional: reason_code const reason_code = typeof obj.reason_code === 'string' && obj.reason_code.trim() ? obj.reason_code.trim() : undefined; // Optional: case_reference const case_reference = typeof obj.case_reference === 'string' && obj.case_reference.trim() ? obj.case_reference.trim() : undefined; // Explicit Allowlist Metadata Projection only let metadata: Record | undefined = undefined; if (obj.metadata && typeof obj.metadata === 'object' && !Array.isArray(obj.metadata)) { const rawMeta = obj.metadata as Record; const safeMeta: Record = {}; for (const [k, v] of Object.entries(rawMeta)) { if (!APPROVED_AUDIT_METADATA_KEYS.has(k)) { continue; // Drop unapproved metadata key } if (typeof v === 'string' && v.length <= 100) { safeMeta[k] = v; } else if (typeof v === 'number' || typeof v === 'boolean') { safeMeta[k] = v; } } if (Object.keys(safeMeta).length > 0) { metadata = safeMeta; } } return { id, timestamp, action, result, actor_identity, actor_role, target_resource, reason_code, case_reference, metadata, }; } // ============================================================ // Incident Sanitizers & Validators (OPS-4) // ============================================================ export function isValidIncidentSeverity(severity: unknown): severity is import('../components/ops/types').IncidentSeverity { return ( severity === 'low' || severity === 'medium' || severity === 'high' || severity === 'critical' ); } export function isValidIncidentStatus(status: unknown): status is import('../components/ops/types').IncidentStatus { return ( status === 'open' || status === 'investigating' || status === 'monitoring' || status === 'resolved' || status === 'closed' || status === 'archived' ); } const ALLOWED_INCIDENT_TRANSITIONS: Record> = { open: new Set(['investigating', 'resolved', 'closed']), investigating: new Set(['monitoring', 'resolved', 'closed']), monitoring: new Set(['investigating', 'resolved', 'closed']), resolved: new Set(['closed', 'investigating']), closed: new Set(['investigating']), // Reopen (Owner only) archived: new Set(), // Terminal }; export function isValidStatusTransition( current: import('../components/ops/types').IncidentStatus, target: import('../components/ops/types').IncidentStatus, role: import('../components/ops/types').OperationsRole ): boolean { if (current === target) return false; if (current === 'archived') return false; // Terminal if (target === 'archived') return role === 'owner'; // Owner only if (current === 'closed' && target === 'investigating') return role === 'owner'; // Owner only const allowed = ALLOWED_INCIDENT_TRANSITIONS[current]; return allowed ? allowed.has(target) : false; } export function sanitizeIncidentSummary(raw: unknown): import('../components/ops/types').SafeIncidentSummary | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; if (typeof obj.case_reference !== 'string' || !obj.case_reference.trim()) return null; const case_reference = obj.case_reference.trim(); if (typeof obj.title !== 'string' || !obj.title.trim()) return null; const title = obj.title.trim(); if (!isValidIncidentSeverity(obj.severity)) return null; const severity = obj.severity; if (!isValidIncidentStatus(obj.status)) return null; const status = obj.status; if (typeof obj.created_at !== 'string' || !obj.created_at.trim()) return null; const created_at = obj.created_at.trim(); const updated_at = typeof obj.updated_at === 'string' && obj.updated_at.trim() ? obj.updated_at.trim() : created_at; return { case_reference, title, severity, status, created_at, updated_at, }; } export function sanitizeIncidentDetail(raw: unknown): import('../components/ops/types').SafeIncidentDetail | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; const summaryData = sanitizeIncidentSummary(raw); if (!summaryData) return null; if (typeof obj.summary !== 'string' || !obj.summary.trim()) return null; const summary = obj.summary.trim(); if (typeof obj.created_by_identity !== 'string' || !obj.created_by_identity.trim()) return null; const created_by_identity = obj.created_by_identity.trim(); const closed_at = typeof obj.closed_at === 'string' && obj.closed_at.trim() ? obj.closed_at.trim() : null; const resolution = typeof obj.resolution === 'string' && obj.resolution.trim() ? obj.resolution.trim() : null; const closed_by_identity = typeof obj.closed_by_identity === 'string' && obj.closed_by_identity.trim() ? obj.closed_by_identity.trim() : null; return { ...summaryData, summary, created_by_identity, closed_at, resolution, closed_by_identity, }; } export function sanitizeIncidentNote(raw: unknown): import('../components/ops/types').SafeIncidentNote | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; if (typeof obj.created_at !== 'string' || !obj.created_at.trim()) return null; const created_at = obj.created_at.trim(); if (typeof obj.created_by_identity !== 'string' || !obj.created_by_identity.trim()) return null; const created_by_identity = obj.created_by_identity.trim(); if (typeof obj.body !== 'string' || !obj.body.trim()) return null; const body = obj.body.trim(); return { created_at, created_by_identity, body, }; }