Files
Aegis/backend/app/models/decay_policy.py
kitos 1fe150963c
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
feat(dlm): Phase 8 — Detection Lifecycle Management [FASE-8]
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>
2026-05-19 15:45:16 +02:00

33 lines
1.6 KiB
Python

"""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)