""" Security incident model for tracking security events and remediation. This model captures security incidents, their investigation, and resolution including BEC, backdoors, malware, and other security threats. """ from datetime import datetime from typing import Optional from sqlalchemy import ( CHAR, CheckConstraint, ForeignKey, Index, String, Text, ) from sqlalchemy.orm import Mapped, mapped_column, relationship from api.models.base import Base, TimestampMixin, UUIDMixin class SecurityIncident(UUIDMixin, TimestampMixin, Base): """ Security incident tracking and remediation. Records security incidents from detection through investigation to resolution, including details about the incident type, severity, and remediation steps. Attributes: id: UUID primary key client_id: Reference to affected client service_id: Reference to affected service infrastructure_id: Reference to affected infrastructure incident_type: Type of security incident incident_date: When the incident occurred severity: Severity level (critical, high, medium, low) description: Detailed description of the incident findings: Investigation results and findings remediation_steps: Steps taken to remediate status: Current status of incident handling resolved_at: When the incident was resolved notes: Additional notes created_at: Creation timestamp updated_at: Last update timestamp """ __tablename__ = "security_incidents" # Foreign keys client_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("clients.id", ondelete="CASCADE"), nullable=True, doc="Reference to affected client", ) service_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("services.id", ondelete="SET NULL"), nullable=True, doc="Reference to affected service", ) infrastructure_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("infrastructure.id", ondelete="SET NULL"), nullable=True, doc="Reference to affected infrastructure", ) # Incident details incident_type: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, doc="Type of security incident", ) incident_date: Mapped[datetime] = mapped_column( nullable=False, doc="When the incident occurred", ) severity: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, doc="Severity level", ) description: Mapped[str] = mapped_column( Text, nullable=False, doc="Detailed description of the incident", ) # Investigation and remediation findings: Mapped[Optional[str]] = mapped_column( Text, nullable=True, doc="Investigation results and findings", ) remediation_steps: Mapped[Optional[str]] = mapped_column( Text, nullable=True, doc="Steps taken to remediate the incident", ) # Status tracking status: Mapped[str] = mapped_column( String(50), nullable=False, server_default="'investigating'", doc="Current status of incident handling", ) resolved_at: Mapped[Optional[datetime]] = mapped_column( nullable=True, doc="When the incident was resolved", ) # Additional information notes: Mapped[Optional[str]] = mapped_column( Text, nullable=True, doc="Additional notes and context", ) # Table constraints __table_args__ = ( CheckConstraint( "incident_type IN ('bec', 'backdoor', 'malware', 'unauthorized_access', 'data_breach', 'phishing', 'ransomware', 'brute_force')", name="ck_security_incidents_type", ), CheckConstraint( "severity IN ('critical', 'high', 'medium', 'low')", name="ck_security_incidents_severity", ), CheckConstraint( "status IN ('investigating', 'contained', 'resolved', 'monitoring')", name="ck_security_incidents_status", ), Index("idx_incidents_client", "client_id"), Index("idx_incidents_type", "incident_type"), Index("idx_incidents_status", "status"), ) def __repr__(self) -> str: """String representation of the security incident.""" return f""