6.4 KiB
6.4 KiB
20. Backend Router — Alert Correlation & Normalization Engine
meta: id: shieldai-unified-restructure-20 feature: shieldai-unified-restructure priority: P1 depends_on: [shieldai-unified-restructure-15, shieldai-unified-restructure-16, shieldai-unified-restructure-17, shieldai-unified-restructure-18, shieldai-unified-restructure-19] tags: [backend, trpc, correlation, alerts, api]
objective:
- Build the tRPC router and service layer for the cross-service alert correlation and normalization engine. Port logic from
packages/correlation/into a unifiedcorrelationrouter that aggregates alerts from all services into a unified threat view.
deliverables:
web/src/server/api/routers/correlation.ts— Correlation router:correlation.getAlerts—protectedProcedurereturning normalized alerts for usercorrelation.getAlertDetails—protectedProcedurereturning single alert with correlated datacorrelation.getGroups—protectedProcedurereturning correlation groupscorrelation.getGroupDetails—protectedProcedurereturning group with all member alertscorrelation.resolveAlert—protectedProceduremarking alert as resolved or false positivecorrelation.getStats—protectedProcedurereturning alert statistics
web/src/server/services/correlation.service.ts— Core business logic:normalizeAlert(source, sourceAlertId, category, severity, userId, title, description, entities)— create NormalizedAlertcorrelateAlerts(userId)— group related alerts by shared entities (email, phone, SSN)getAlertTimeline(userId, filters?)— chronological view of all alertsresolveAlert(alertId, resolution)— mark as resolved or false positivegetThreatScore(userId)— calculate overall threat score based on alert severity and frequency
web/src/server/services/correlation/engine.ts— Correlation engine:findRelatedAlerts(alert)— find alerts sharing entities with given alertcreateCorrelationGroup(alerts)— group related alerts into CorrelationGroupupdateGroupSeverity(group)— recalculate highest severity for groupdeduplicateAlerts(alerts)— remove duplicate alerts based on sourceAlertId
web/src/server/services/correlation/normalizer.ts— Alert normalization:normalizeDarkWatchAlert(exposure)— convert exposure to NormalizedAlertnormalizeSpamShieldAlert(detection)— convert spam detection to NormalizedAlertnormalizeVoicePrintAlert(analysis)— convert voice analysis to NormalizedAlertnormalizeHomeTitleAlert(change)— convert property change to NormalizedAlertnormalizeRemoveBrokersAlert(listing)— convert broker listing to NormalizedAlert
steps:
- Create
web/src/server/api/routers/correlation.ts. - Define Zod schemas:
alertFilterSchema:source: z.enum([...]).optional(),severity: z.enum([...]).optional(),status: z.enum([...]).optional(),page,limitresolveSchema:alertId: z.string().uuid(),resolution: z.enum(['RESOLVED', 'FALSE_POSITIVE'])
- Implement router procedures:
- Alert listing with filtering and pagination
- Group listing and details
- Alert resolution with audit logging
- Stats aggregation
- Create
web/src/server/services/correlation.service.ts:- Port from
packages/correlation/src/ - Implement normalization pipeline
- Implement correlation grouping
- Port from
- Create correlation engine:
findRelatedAlerts: query alerts by shared entities (email, phone, SSN) within time windowcreateCorrelationGroup: create group record, link alertsupdateGroupSeverity: aggregate severity of all alerts in groupdeduplicateAlerts: ensure no duplicate sourceAlertId in normalized table
- Create normalizer module:
- One function per service domain that converts domain-specific alert to NormalizedAlert
- Map domain severity to NormalizedAlertSeverity enum
- Extract entities (emails, phones, SSNs) from payload for correlation
- Implement threat scoring:
- Formula: weighted sum of alert severities over 30-day window
- Decay older alerts
- Return score 0-100
- Integrate with other services:
- Call
correlationService.normalizeAlert()from each service's alert pipeline - DarkWatch (task 15), VoicePrint (task 16), SpamShield (task 17), HomeTitle (task 18), RemoveBrokers (task 19)
- Call
- Wire router into
web/src/server/api/root.ts. - Write unit tests for engine functions.
steps:
- Unit:
normalizeAlertcreates correct NormalizedAlert for each source type - Unit:
findRelatedAlertsgroups alerts sharing an email address - Unit:
createCorrelationGroupcreates group with correct highest severity - Unit:
deduplicateAlertsprevents duplicate sourceAlertId - Unit:
getThreatScorereturns higher score for more severe/recent alerts - Integration: tRPC
getAlertsreturns normalized alerts for authenticated user
acceptance_criteria:
- Alerts from all 5 services are normalized into a unified schema
- Related alerts are grouped by shared entities (email, phone, SSN)
- Correlation groups update their severity when new alerts are added
- Users can resolve alerts or mark them as false positives
- Alert timeline provides chronological view across all services
- Threat score accurately reflects user's current risk level
- Deduplication prevents duplicate alerts from the same source
validation:
- Create normalized alerts from different services with shared email
- Verify correlation engine groups them into a single group
- Resolve an alert and verify status updated in DB
- Calculate threat score for a user with mixed alert severities
- Run
cd web && pnpm testfor correlation unit tests
notes:
- Reference legacy:
packages/correlation/src/,packages/api/src/routes/correlation.routes.ts - The correlation engine is the "brain" that makes ShieldAI feel unified. Invest time in getting the entity extraction and grouping logic right.
- Entity extraction should use regex patterns for emails, phones, and SSNs. Consider using a library like
compromisefor NLP extraction if payloads are unstructured. - Time window for correlation: alerts within 30 days sharing an entity should be grouped. Adjust based on testing.
- The threat score algorithm should be transparent to users. Consider showing the breakdown (e.g., "+20 from DarkWatch exposure, +15 from SpamShield detection").
- False positive tracking is important for ML model improvement. Log all false positive marks with context.