feat(dlm): Phase 8 — Detection Lifecycle Management [FASE-8]
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Tasks 8.1-8.5: Models (8.1): - DetectionAsset: SIEM/EDR/Sigma rule assets with auto-hash - DetectionTechniqueMapping: N:M asset ↔ technique coverage - DetectionValidation: immutable validation records with expiry - TechniqueConfidenceScore: computed multi-factor confidence - InfrastructureChangeLog: infra changes that invalidate detections - DecayPolicy: configurable freshness thresholds per platform/tactic Services (8.2, 8.3): - detection_asset_service: CRUD + SHA-256 rule hashing + auto- invalidation on rule/infra changes - decay_engine_service: daily decay engine — expires stale validations, recalculates confidence (recency/coverage/health/diversity factors), processes infrastructure change propagation Router (8.4): 15 endpoints under /api/v1/detection-lifecycle: assets CRUD, technique mappings, validations, confidence scores, infrastructure changes, decay trigger, executive dashboard Scheduler (8.3): decay engine runs daily at 02:00 Seed (8.5): default policy (90/180/365d) + strict initial-access policy Migration: b034dlm (6 tables, 11 indexes) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
32
backend/app/models/decay_policy.py
Normal file
32
backend/app/models/decay_policy.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""Decay Policy model — configurable detection validity rules."""
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, String, Integer, Float, Boolean, DateTime, Text
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class DecayPolicy(Base):
|
||||
__tablename__ = "decay_policies"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
name = Column(String(200), nullable=False)
|
||||
description = Column(Text)
|
||||
applies_to_platform = Column(String(100))
|
||||
applies_to_asset_type = Column(String(50))
|
||||
applies_to_tactic = Column(String(100))
|
||||
fresh_days = Column(Integer, default=90, server_default='90')
|
||||
aging_days = Column(Integer, default=180, server_default='180')
|
||||
stale_days = Column(Integer, default=365, server_default='365')
|
||||
default_validity_days = Column(Integer, default=180, server_default='180')
|
||||
silent_threshold_days = Column(Integer, default=30, server_default='30')
|
||||
noisy_threshold_daily = Column(Integer, default=100, server_default='100')
|
||||
recency_weight = Column(Float, default=0.3, server_default='0.3')
|
||||
coverage_weight = Column(Float, default=0.3, server_default='0.3')
|
||||
health_weight = Column(Float, default=0.25, server_default='0.25')
|
||||
diversity_weight = Column(Float, default=0.15, server_default='0.15')
|
||||
is_default = Column(Boolean, default=False, server_default='false')
|
||||
is_active = Column(Boolean, default=True, server_default='true')
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow)
|
||||
Reference in New Issue
Block a user