CREATE DATABASE IF NOT EXISTS eventcollector CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE eventcollector; CREATE TABLE IF NOT EXISTS agents ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, hostname VARCHAR(255) NOT NULL, api_key_hash CHAR(64) NOT NULL, first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), last_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), last_ip VARCHAR(64) NOT NULL DEFAULT '', is_enabled TINYINT(1) NOT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE KEY ux_agents_hostname (hostname), KEY ix_agents_last_seen (last_seen) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS event_logs ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, agent_id BIGINT UNSIGNED NOT NULL, hostname VARCHAR(255) NOT NULL, channel_name VARCHAR(128) NOT NULL, event_id INT UNSIGNED NOT NULL, source VARCHAR(255) NOT NULL, computer VARCHAR(255) NOT NULL DEFAULT '', provider_name VARCHAR(255) NOT NULL DEFAULT '', level_value INT UNSIGNED NOT NULL DEFAULT 0, task_value INT UNSIGNED NOT NULL DEFAULT 0, opcode_value INT UNSIGNED NOT NULL DEFAULT 0, keywords VARCHAR(255) NOT NULL DEFAULT '', target_user VARCHAR(255) NOT NULL DEFAULT '', target_domain VARCHAR(255) NOT NULL DEFAULT '', subject_user VARCHAR(255) NOT NULL DEFAULT '', subject_domain VARCHAR(255) NOT NULL DEFAULT '', workstation VARCHAR(255) NOT NULL DEFAULT '', src_ip VARCHAR(64) NOT NULL DEFAULT '', src_port VARCHAR(32) NOT NULL DEFAULT '', logon_type VARCHAR(32) NOT NULL DEFAULT '', process_name VARCHAR(512) NOT NULL DEFAULT '', authentication_package VARCHAR(128) NOT NULL DEFAULT '', logon_process VARCHAR(128) NOT NULL DEFAULT '', status_text VARCHAR(64) NOT NULL DEFAULT '', sub_status_text VARCHAR(64) NOT NULL DEFAULT '', failure_reason VARCHAR(512) NOT NULL DEFAULT '', ts DATETIME(6) NOT NULL, received_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), msg LONGTEXT NOT NULL, msg_sha256 CHAR(64) NOT NULL, PRIMARY KEY (id), KEY ix_event_logs_ts (ts), KEY ix_event_logs_received_at (received_at), KEY ix_event_logs_agent_ts (agent_id, ts), KEY ix_event_logs_eventid_ts (event_id, ts), KEY ix_event_logs_hostname_ts (hostname, ts), KEY ix_event_logs_channel_event_ts (channel_name, event_id, ts), KEY ix_event_logs_target_user_ts (target_user, ts), KEY ix_event_logs_src_ip_ts (src_ip, ts), KEY ix_event_logs_target_user_src_ip_ts (target_user, src_ip, ts), KEY ix_event_logs_eventid_srcip_ts (event_id, src_ip, ts), KEY ix_event_logs_eventid_targetuser_ts (event_id, target_user, ts), KEY ix_event_logs_eventid_logontype_ts (event_id, logon_type, ts), CONSTRAINT fk_event_logs_agent FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS detections ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, rule_name VARCHAR(128) NOT NULL, severity VARCHAR(32) NOT NULL, hostname VARCHAR(255) NOT NULL, channel_name VARCHAR(128) NOT NULL DEFAULT '', event_id INT UNSIGNED NOT NULL DEFAULT 0, score DOUBLE NOT NULL DEFAULT 0, window_start DATETIME(6) NOT NULL, window_end DATETIME(6) NOT NULL, summary VARCHAR(512) NOT NULL, details_json JSON NOT NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY ux_detection_dedupe (rule_name, hostname, channel_name, event_id, window_start, window_end), KEY ix_detections_created (created_at), KEY ix_detections_rule_host_time (rule_name, hostname, created_at), KEY ix_detections_severity_time (severity, created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE detection_rules ( id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE, description TEXT, severity VARCHAR(16) NOT NULL DEFAULT 'medium', channel VARCHAR(255) NOT NULL DEFAULT 'Security', event_ids VARCHAR(255) NOT NULL, match_field VARCHAR(255) DEFAULT '', match_operator VARCHAR(16) DEFAULT '', match_value TEXT, threshold_count INT NOT NULL DEFAULT 1, threshold_window_seconds INT NOT NULL DEFAULT 0, suppress_for_seconds INT NOT NULL DEFAULT 3600, enabled TINYINT(1) NOT NULL DEFAULT 1, created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) ); CREATE INDEX idx_detection_rules_enabled ON detection_rules (enabled); CREATE INDEX idx_event_logs_dynamic_rules ON event_logs (channel_name, event_id, ts, hostname); INSERT INTO detection_rules ( name, description, severity, channel, event_ids, match_field, match_operator, match_value, threshold_count, threshold_window_seconds, suppress_for_seconds, enabled ) VALUES -- ============================================================ -- Kritische Manipulationen / Spurenverwischung -- ============================================================ ( 'security_log_cleared', 'Security Log wurde gelöscht. Das ist fast immer sicherheitsrelevant.', 'high', 'Security', '1102', '', '', '', 1, 0, 86400, 1 ), ( 'audit_policy_changed', 'Audit Policy wurde geändert.', 'high', 'Security', '4719', '', '', '', 1, 0, 3600, 1 ), ( 'system_audit_policy_changed', 'System Audit Policy wurde geändert.', 'high', 'Security', '4902,4904,4905,4906,4907,4908,4912', '', '', '', 1, 0, 3600, 1 ), ( 'special_logon', 'Anmeldung mit speziellen Rechten erkannt.', 'medium', 'Security', '4672', '', '', '', 1, 0, 900, 1 ), ( 'privileged_service_called', 'Privilegierter Dienst wurde aufgerufen.', 'medium', 'Security', '4673,4674', '', '', '', 10, 300, 1800, 1 ), -- ============================================================ -- Benutzerverwaltung -- ============================================================ ( 'user_created', 'Neuer AD-Benutzer wurde erstellt.', 'medium', 'Security', '4720', '', '', '', 1, 0, 1800, 1 ), ( 'user_enabled', 'AD-Benutzer wurde aktiviert.', 'medium', 'Security', '4722', '', '', '', 1, 0, 1800, 1 ), ( 'user_disabled', 'AD-Benutzer wurde deaktiviert.', 'low', 'Security', '4725', '', '', '', 1, 0, 1800, 1 ), ( 'user_deleted', 'AD-Benutzer wurde gelöscht.', 'medium', 'Security', '4726', '', '', '', 1, 0, 3600, 1 ), ( 'user_changed', 'AD-Benutzerobjekt wurde geändert.', 'low', 'Security', '4738', '', '', '', 1, 0, 1800, 1 ), ( 'password_changed_by_user', 'Benutzer hat eigenes Passwort geändert.', 'low', 'Security', '4723', '', '', '', 1, 0, 900, 1 ), ( 'password_reset', 'Passwort wurde durch Admin oder berechtigten Benutzer zurückgesetzt.', 'medium', 'Security', '4724', '', '', '', 1, 0, 1800, 1 ), ( 'account_lockout', 'Benutzerkonto wurde gesperrt.', 'low', 'Security', '4740', '', '', '', 1, 0, 900, 1 ), ( 'account_lockout_spike', 'Viele Account Lockouts innerhalb kurzer Zeit.', 'medium', 'Security', '4740', '', '', '', 5, 300, 1800, 1 ), -- ============================================================ -- Gruppenverwaltung allgemein -- ============================================================ ( 'security_group_created', 'Security-Gruppe wurde erstellt.', 'medium', 'Security', '4727,4731,4754', '', '', '', 1, 0, 1800, 1 ), ( 'security_group_deleted', 'Security-Gruppe wurde gelöscht.', 'medium', 'Security', '4730,4734,4758', '', '', '', 1, 0, 3600, 1 ), ( 'security_group_changed', 'Security-Gruppe wurde geändert.', 'medium', 'Security', '4735,4737,4755', '', '', '', 1, 0, 1800, 1 ), ( 'group_member_added', 'Mitglied wurde zu einer Security-Gruppe hinzugefügt.', 'medium', 'Security', '4728,4732,4756', '', '', '', 1, 0, 1800, 1 ), ( 'group_member_removed', 'Mitglied wurde aus einer Security-Gruppe entfernt.', 'medium', 'Security', '4729,4733,4757', '', '', '', 1, 0, 1800, 1 ), -- ============================================================ -- Privilegierte Gruppen -- Achtung: target_user ist hier normalerweise der Gruppenname. -- ============================================================ ( 'privileged_group_member_added', 'Mitglied wurde zu einer privilegierten AD-Gruppe hinzugefügt.', 'high', 'Security', '4728,4732,4756', 'target_user', 'in', 'Domain Admins,Enterprise Admins,Schema Admins,Administrators,Account Operators,Server Operators,Backup Operators,Print Operators,DNSAdmins,Group Policy Creator Owners,Cert Publishers,Key Admins,Enterprise Key Admins', 1, 0, 3600, 1 ), ( 'privileged_group_member_removed', 'Mitglied wurde aus einer privilegierten AD-Gruppe entfernt.', 'medium', 'Security', '4729,4733,4757', 'target_user', 'in', 'Domain Admins,Enterprise Admins,Schema Admins,Administrators,Account Operators,Server Operators,Backup Operators,Print Operators,DNSAdmins,Group Policy Creator Owners,Cert Publishers,Key Admins,Enterprise Key Admins', 1, 0, 3600, 1 ), ( 'domain_admins_changed', 'Änderung an Domain Admins erkannt.', 'high', 'Security', '4728,4729,4735,4737', 'target_user', 'eq', 'Domain Admins', 1, 0, 3600, 1 ), ( 'enterprise_admins_changed', 'Änderung an Enterprise Admins erkannt.', 'high', 'Security', '4728,4729,4735,4737', 'target_user', 'eq', 'Enterprise Admins', 1, 0, 3600, 1 ), ( 'schema_admins_changed', 'Änderung an Schema Admins erkannt.', 'high', 'Security', '4728,4729,4735,4737', 'target_user', 'eq', 'Schema Admins', 1, 0, 3600, 1 ), ( 'dnsadmins_changed', 'Änderung an DNSAdmins erkannt. DNSAdmins können in vielen Umgebungen kritisch sein.', 'high', 'Security', '4728,4729,4732,4733,4756,4757', 'target_user', 'eq', 'DNSAdmins', 1, 0, 3600, 1 ), -- ============================================================ -- Computer-Konten -- ============================================================ ( 'computer_account_created', 'Computer-Konto wurde erstellt.', 'low', 'Security', '4741', '', '', '', 1, 0, 1800, 1 ), ( 'computer_account_changed', 'Computer-Konto wurde geändert.', 'low', 'Security', '4742', '', '', '', 1, 0, 1800, 1 ), ( 'computer_account_deleted', 'Computer-Konto wurde gelöscht.', 'medium', 'Security', '4743', '', '', '', 1, 0, 3600, 1 ), -- ============================================================ -- Kerberos / Authentifizierung -- ============================================================ ( 'kerberos_preauth_failure', 'Kerberos PreAuth Fehler erkannt.', 'low', 'Security', '4771', '', '', '', 1, 0, 300, 1 ), ( 'kerberos_preauth_spike', 'Viele Kerberos PreAuth Fehler. Möglicher Password-Spray oder Bruteforce.', 'high', 'Security', '4771', '', '', '', 20, 300, 1800, 1 ), ( 'kerberos_tgt_failed_spike', 'Viele fehlgeschlagene Kerberos-TGT-Anfragen.', 'medium', 'Security', '4768', '', '', '', 30, 300, 1800, 1 ), ( 'kerberos_service_ticket_spike', 'Viele Kerberos-Service-Ticket-Anfragen. Kann auf Kerberoasting oder ungewöhnliche Service-Nutzung hindeuten.', 'medium', 'Security', '4769', '', '', '', 100, 300, 1800, 1 ), ( 'ntlm_authentication_spike', 'Viele NTLM-Authentifizierungen erkannt.', 'medium', 'Security', '4776', '', '', '', 50, 300, 1800, 1 ), ( 'logon_failed_spike', 'Viele fehlgeschlagene Logons.', 'medium', 'Security', '4625', '', '', '', 25, 300, 1800, 1 ), ( 'explicit_credentials_used', 'Anmeldung mit expliziten Anmeldeinformationen erkannt.', 'medium', 'Security', '4648', '', '', '', 1, 0, 900, 1 ), ( 'many_explicit_credentials_used', 'Viele Anmeldungen mit expliziten Anmeldeinformationen.', 'high', 'Security', '4648', '', '', '', 20, 300, 1800, 1 ), -- ============================================================ -- Dienste, Tasks, Persistenz -- ============================================================ ( 'service_installed_security', 'Neuer Dienst laut Security Log installiert.', 'high', 'Security', '4697', '', '', '', 1, 0, 3600, 1 ), ( 'service_installed_system', 'Neuer Dienst laut System Log installiert.', 'high', 'System', '7045', '', '', '', 1, 0, 3600, 1 ), ( 'scheduled_task_created', 'Geplanter Task wurde erstellt.', 'high', 'Security', '4698', '', '', '', 1, 0, 3600, 1 ), ( 'scheduled_task_updated', 'Geplanter Task wurde geändert.', 'medium', 'Security', '4702', '', '', '', 1, 0, 1800, 1 ), ( 'scheduled_task_deleted', 'Geplanter Task wurde gelöscht.', 'medium', 'Security', '4699', '', '', '', 1, 0, 1800, 1 ), ( 'scheduled_task_enabled_disabled', 'Geplanter Task wurde aktiviert oder deaktiviert.', 'medium', 'Security', '4700,4701', '', '', '', 1, 0, 1800, 1 ), -- ============================================================ -- Prozess / PowerShell / Script Logging -- Nur aktivieren, wenn diese Events bei dir tatsächlich gesammelt werden. -- ============================================================ ( 'process_created', 'Neuer Prozess wurde erstellt. Nur sinnvoll bei aktiviertem Process Creation Auditing.', 'low', 'Security', '4688', '', '', '', 1, 0, 300, 0 ), ( 'suspicious_powershell_process', 'Verdächtiger PowerShell-Aufruf im Prozess-Event.', 'high', 'Security', '4688', 'msg', 'contains', 'powershell', 1, 0, 1800, 0 ), ( 'powershell_script_block', 'PowerShell Script Block Logging Event erkannt.', 'medium', 'Windows PowerShell,Microsoft-Windows-PowerShell/Operational', '4104', '', '', '', 1, 0, 900, 0 ), ( 'suspicious_powershell_encodedcommand', 'PowerShell EncodedCommand erkannt.', 'high', 'Windows PowerShell,Microsoft-Windows-PowerShell/Operational,Security', '4104,4688', 'msg', 'contains', 'EncodedCommand', 1, 0, 1800, 0 ), ( 'suspicious_powershell_downloadstring', 'PowerShell DownloadString erkannt.', 'high', 'Windows PowerShell,Microsoft-Windows-PowerShell/Operational,Security', '4104,4688', 'msg', 'contains', 'DownloadString', 1, 0, 1800, 0 ), ( 'suspicious_powershell_iex', 'PowerShell Invoke-Expression / IEX erkannt.', 'high', 'Windows PowerShell,Microsoft-Windows-PowerShell/Operational,Security', '4104,4688', 'msg', 'contains', 'Invoke-Expression', 1, 0, 1800, 0 ), -- ============================================================ -- GPO / AD Objektänderungen -- Hinweis: 5136/5137/5141 kommen aus Directory Service Changes. -- Dafür muss das passende Auditing auf DCs aktiv sein. -- ============================================================ ( 'directory_object_modified', 'AD-Objekt wurde geändert.', 'medium', 'Security', '5136', '', '', '', 1, 0, 900, 0 ), ( 'directory_object_created', 'AD-Objekt wurde erstellt.', 'medium', 'Security', '5137', '', '', '', 1, 0, 900, 0 ), ( 'directory_object_deleted', 'AD-Objekt wurde gelöscht.', 'medium', 'Security', '5141', '', '', '', 1, 0, 1800, 0 ), ( 'gpo_changed', 'Mögliche GPO-Änderung erkannt.', 'high', 'Security', '5136', 'msg', 'contains', 'CN=Policies,CN=System', 1, 0, 3600, 0 ), ( 'adminsdholder_changed', 'AdminSDHolder wurde geändert. Sehr sicherheitsrelevant.', 'high', 'Security', '5136', 'msg', 'contains', 'CN=AdminSDHolder', 1, 0, 86400, 0 ), ( 'domain_root_changed', 'Domain-Root-Objekt wurde geändert.', 'high', 'Security', '5136', 'msg', 'contains', 'DC=', 1, 0, 3600, 0 ), -- ============================================================ -- Objektzugriff / ACL -- Hinweis: 4662/4670 brauchen passende SACLs. -- ============================================================ ( 'object_permissions_changed', 'Berechtigungen eines Objekts wurden geändert.', 'high', 'Security', '4670', '', '', '', 1, 0, 3600, 0 ), ( 'directory_service_object_access', 'Directory-Service-Objektzugriff erkannt.', 'medium', 'Security', '4662', '', '', '', 10, 300, 1800, 0 ), -- ============================================================ -- Share / SMB / SYSVOL / administrative Zugriffe -- Hinweis: Kann sehr laut werden. -- ============================================================ ( 'network_share_accessed', 'Netzwerkfreigabe wurde genutzt.', 'low', 'Security', '5140', '', '', '', 50, 300, 900, 0 ), ( 'network_share_object_checked', 'Detaillierter Netzwerkfreigabezugriff erkannt.', 'low', 'Security', '5145', '', '', '', 100, 300, 900, 0 ), ( 'sysvol_access_spike', 'Viele Zugriffe auf SYSVOL erkannt.', 'low', 'Security', '5140,5145', 'msg', 'contains', 'SYSVOL', 100, 300, 900, 0 ), ( 'admin_share_access', 'Zugriff auf administrative Freigabe erkannt.', 'medium', 'Security', '5140,5145', 'msg', 'contains', 'ADMIN$', 1, 0, 1800, 0 ), ( 'c_share_access', 'Zugriff auf C$ erkannt.', 'medium', 'Security', '5140,5145', 'msg', 'contains', 'C$', 1, 0, 1800, 0 ), -- ============================================================ -- System / Neustart / Agent-Kontext -- ============================================================ ( 'system_startup', 'System wurde gestartet.', 'low', 'System', '6005', '', '', '', 1, 0, 300, 0 ), ( 'system_shutdown', 'System wurde heruntergefahren.', 'low', 'System', '6006', '', '', '', 1, 0, 300, 0 ), ( 'planned_shutdown_or_restart', 'Geplanter Shutdown oder Neustart erkannt.', 'low', 'System', '1074', '', '', '', 1, 0, 900, 1 ), ( 'unexpected_shutdown', 'Unerwarteter Shutdown erkannt.', 'medium', 'System', '6008', '', '', '', 1, 0, 1800, 1 ), ( 'reboot_spike_dynamic', 'Viele Neustart-/Shutdown-Events in kurzer Zeit.', 'medium', 'System', '1074,6005,6006,6008', '', '', '', 3, 900, 1800, 0 ), -- ============================================================ -- Windows Defender / Security Center -- Event IDs können je nach Version/Quelle variieren. -- ============================================================ ( 'defender_malware_detected', 'Microsoft Defender hat Malware erkannt.', 'high', 'Microsoft-Windows-Windows Defender/Operational', '1116', '', '', '', 1, 0, 3600, 0 ), ( 'defender_malware_remediated', 'Microsoft Defender hat Malware bereinigt.', 'medium', 'Microsoft-Windows-Windows Defender/Operational', '1117', '', '', '', 1, 0, 1800, 0 ), ( 'defender_action_failed', 'Microsoft Defender Aktion fehlgeschlagen.', 'high', 'Microsoft-Windows-Windows Defender/Operational', '1118,1119', '', '', '', 1, 0, 3600, 0 ), ( 'defender_disabled_or_config_changed', 'Defender-Konfiguration wurde geändert oder Schutz deaktiviert.', 'high', 'Microsoft-Windows-Windows Defender/Operational', '5007,5013', '', '', '', 1, 0, 3600, 0 ), -- ============================================================ -- Zertifikatsdienste / AD CS -- Nur aktivieren, wenn AD CS vorhanden und Events gesammelt werden. -- ============================================================ ( 'certificate_request_issued', 'Zertifikat wurde ausgestellt.', 'medium', 'Security', '4886,4887', '', '', '', 1, 0, 1800, 0 ), ( 'certificate_template_changed', 'Zertifikatstemplate wurde geändert.', 'high', 'Security', '4898,4899,4900', '', '', '', 1, 0, 86400, 0 ), ( 'cert_services_config_changed', 'AD-CS-Konfiguration wurde geändert.', 'high', 'Security', '4882,4885,4890,4891,4892', '', '', '', 1, 0, 86400, 0 ); UPDATE detection_rules SET description = '' WHERE description IS NULL; UPDATE detection_rules SET match_field = '' WHERE match_field IS NULL; UPDATE detection_rules SET match_operator = '' WHERE match_operator IS NULL; UPDATE detection_rules SET match_value = '' WHERE match_value IS NULL; ALTER TABLE detection_rules MODIFY description TEXT NULL, MODIFY match_value TEXT NULL, MODIFY match_field VARCHAR(64) NOT NULL DEFAULT '', MODIFY match_operator VARCHAR(16) NOT NULL DEFAULT ''; CREATE TABLE baseline_event_stats ( id BIGINT AUTO_INCREMENT PRIMARY KEY, hostname VARCHAR(255) NOT NULL, channel_name VARCHAR(255) NOT NULL, event_id INT NOT NULL, hour_of_day TINYINT NOT NULL, day_of_week TINYINT NOT NULL, avg_count DOUBLE NOT NULL DEFAULT 0, m2_count DOUBLE NOT NULL DEFAULT 0, stddev_count DOUBLE NOT NULL DEFAULT 0, sample_count INT NOT NULL DEFAULT 0, last_updated TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), UNIQUE KEY uniq_baseline_event ( hostname, channel_name, event_id, hour_of_day, day_of_week ) ); CREATE INDEX idx_baseline_event_lookup ON baseline_event_stats ( hostname, channel_name, event_id, hour_of_day, day_of_week, sample_count ); ALTER TABLE detections ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT 'open', ADD COLUMN analyst_note TEXT NULL, ADD COLUMN reviewed_by VARCHAR(128) NULL, ADD COLUMN reviewed_at TIMESTAMP(6) NULL, ADD COLUMN is_false_positive TINYINT(1) NOT NULL DEFAULT 0, ADD COLUMN is_legitimate TINYINT(1) NOT NULL DEFAULT 0; CREATE INDEX idx_detections_status_created ON detections (status, created_at); CREATE INDEX idx_detections_rule_status ON detections (rule_name, status); CREATE TABLE detection_suppressions ( id BIGINT AUTO_INCREMENT PRIMARY KEY, rule_name VARCHAR(128) NOT NULL, hostname VARCHAR(255) DEFAULT '', channel_name VARCHAR(255) DEFAULT '', event_id INT DEFAULT 0, reason TEXT NULL, created_by VARCHAR(128) DEFAULT '', created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), expires_at TIMESTAMP(6) NULL, enabled TINYINT(1) NOT NULL DEFAULT 1 ); CREATE INDEX idx_suppressions_lookup ON detection_suppressions (enabled, rule_name, hostname, channel_name, event_id); CREATE TABLE baseline_exclusions ( id BIGINT AUTO_INCREMENT PRIMARY KEY, hostname VARCHAR(255) NOT NULL DEFAULT '', channel_name VARCHAR(255) NOT NULL DEFAULT '', event_id INT NOT NULL DEFAULT 0, reason TEXT NULL, created_by VARCHAR(128) NOT NULL DEFAULT '', created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), expires_at TIMESTAMP(6) NULL, enabled TINYINT(1) NOT NULL DEFAULT 1 ); CREATE INDEX idx_baseline_exclusions_lookup ON baseline_exclusions (enabled, hostname, channel_name, event_id, expires_at);