"""Compliance models — frameworks, controls, and technique mappings. Maps compliance frameworks (NIST 800-53, DORA, NIS2, ISO 27001) to MITRE ATT&CK techniques, enabling compliance gap analysis. """ # Import uuid import uuid # Import from sqlalchemy from sqlalchemy import ( Boolean, Column, DateTime, ForeignKey, Index, String, Text, UniqueConstraint, func, ) # Import UUID from sqlalchemy.dialects.postgresql from sqlalchemy.dialects.postgresql import UUID # Import relationship from sqlalchemy.orm from sqlalchemy.orm import relationship # Import Base from app.database from app.database import Base # Define class ComplianceFramework class ComplianceFramework(Base): """A compliance framework (e.g. NIST 800-53, ISO 27001).""" # Assign __tablename__ = "compliance_frameworks" __tablename__ = "compliance_frameworks" # Assign id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Assign name = Column(String, unique=True, nullable=False) name = Column(String, unique=True, nullable=False) # Assign version = Column(String, nullable=True) version = Column(String, nullable=True) # Assign description = Column(Text, nullable=True) description = Column(Text, nullable=True) # Assign url = Column(String, nullable=True) url = Column(String, nullable=True) # Assign is_active = Column(Boolean, default=True) is_active = Column(Boolean, default=True) # Assign created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships controls = relationship( # Literal argument value "ComplianceControl", # Keyword argument: back_populates back_populates="framework", # Keyword argument: cascade cascade="all, delete-orphan", ) # Define class ComplianceControl class ComplianceControl(Base): """A control within a compliance framework (e.g. AC-2, PR.AC-1).""" # Assign __tablename__ = "compliance_controls" __tablename__ = "compliance_controls" # Assign id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Assign framework_id = Column( framework_id = Column( UUID(as_uuid=True), ForeignKey("compliance_frameworks.id", ondelete="CASCADE"), # Keyword argument: nullable nullable=False, ) # Assign control_id = Column(String, nullable=False) # e.g. "AC-2" control_id = Column(String, nullable=False) # e.g. "AC-2" # Assign title = Column(String, nullable=False) title = Column(String, nullable=False) # Assign description = Column(Text, nullable=True) description = Column(Text, nullable=True) # Assign category = Column(String, nullable=True) category = Column(String, nullable=True) # Relationships framework = relationship("ComplianceFramework", back_populates="controls") # Assign technique_mappings = relationship( technique_mappings = relationship( # Literal argument value "ComplianceControlMapping", # Keyword argument: back_populates back_populates="compliance_control", # Keyword argument: cascade cascade="all, delete-orphan", ) # Assign __table_args__ = ( __table_args__ = ( Index('ix_compliance_controls_framework', 'framework_id'), ) # Define class ComplianceControlMapping class ComplianceControlMapping(Base): """Maps a compliance control to a MITRE ATT&CK technique.""" # Assign __tablename__ = "compliance_control_mappings" __tablename__ = "compliance_control_mappings" # Assign id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Assign compliance_control_id = Column( compliance_control_id = Column( UUID(as_uuid=True), ForeignKey("compliance_controls.id", ondelete="CASCADE"), # Keyword argument: nullable nullable=False, ) # Assign technique_id = Column( technique_id = Column( UUID(as_uuid=True), ForeignKey("techniques.id", ondelete="CASCADE"), # Keyword argument: nullable nullable=False, ) # Relationships compliance_control = relationship( # Literal argument value "ComplianceControl", back_populates="technique_mappings" ) # Assign technique = relationship("Technique") technique = relationship("Technique") # Assign __table_args__ = ( __table_args__ = ( Index('ix_compliance_mappings_control', 'compliance_control_id'), Index('ix_compliance_mappings_technique', 'technique_id'), UniqueConstraint( # Literal argument value 'compliance_control_id', 'technique_id', # Keyword argument: name name='uq_control_technique', ), )