nis2-agile/docs/sql/024_evidence_automation.sql
DevEnv nis2-agile 307993fbad [FEAT] Evidence Automation + Continuous Control Monitoring (P1)
Colma il gap competitivo vs Vanta/Drata (compliance automation):
- ServicesController::ingestEvidence -> POST /services/evidence-ingest (scope ingest:evidence)
  raccolta evidenze automatiche dai connettori (M365/Google/AWS/Azure/IdP/EDR/SIEM), batch fino a 200, upsert idempotente su external_ref
- recomputeControlMonitoring: ricalcolo monitoring_status (healthy/warning/stale/failing) per freschezza+esito
- controlsMonitoring -> GET /services/controls-monitoring (scope read:compliance): coverage + summary semafori
- Migrazione 024: tabella control_evidence_auto + compliance_controls.{monitoring_status,last_checked_at,freshness_days}
- Route POST:evidenceIngest, GET:controlsMonitoring

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 08:55:26 +02:00

60 lines
3.6 KiB
SQL

-- ============================================================================
-- Migration 024 - Evidence Automation + Continuous Control Monitoring (P1)
-- ----------------------------------------------------------------------------
-- Colma il gap competitivo vs Vanta/Drata: raccolta automatica evidenze di
-- conformita (NIS2 Art.21) dai connettori esterni e monitoraggio continuo
-- della freschezza/stato dei controlli.
--
-- 1) Tabella control_evidence_auto: ogni evidenza raccolta da un collector
-- esterno (M365, AWS, EDR, ...) per uno specifico control_code.
-- 2) compliance_controls += monitoring_status, last_checked_at, freshness_days.
--
-- Idempotente via information_schema. Rilanciabile.
-- mysql -h localhost nis2_agile_db -e "source docs/sql/024_evidence_automation.sql"
-- ============================================================================
CREATE TABLE IF NOT EXISTS control_evidence_auto (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
organization_id INT NOT NULL,
control_code VARCHAR(50) NOT NULL COMMENT 'Codice controllo (compliance_controls.control_code)',
source ENUM('m365','google','aws','azure','idp','edr','siem','api','manual') NOT NULL DEFAULT 'api',
source_system VARCHAR(120) NULL COMMENT 'Sistema sorgente (es. Microsoft 365, CrowdStrike)',
status ENUM('pass','fail','warning','not_applicable') NOT NULL DEFAULT 'pass' COMMENT 'Esito del check automatico',
summary VARCHAR(255) NULL COMMENT 'Sintesi leggibile evidenza',
payload JSON NULL COMMENT 'Dettaglio raw evidenza (oggetto del check)',
external_ref VARCHAR(190) NULL COMMENT 'ID check esterno (idempotenza per re-collect)',
collected_at DATETIME NOT NULL COMMENT 'Quando il collector ha raccolto evidenza',
valid_until DATETIME NULL COMMENT 'Scadenza freschezza evidenza (oltre = stale)',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_evi_org_control (organization_id, control_code),
KEY idx_evi_collected (organization_id, collected_at),
UNIQUE KEY uq_evi_external (organization_id, control_code, external_ref)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Evidenze raccolte automaticamente dai connettori (Continuous Control Monitoring)';
-- Colonne monitoraggio continuo su compliance_controls
DELIMITER //
DROP PROCEDURE IF EXISTS _mig024_add_col //
CREATE PROCEDURE _mig024_add_col(IN col VARCHAR(64), IN ddl TEXT)
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'compliance_controls' AND COLUMN_NAME = col
) THEN
SET @sql = CONCAT('ALTER TABLE compliance_controls ADD COLUMN ', ddl);
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
END IF;
END //
DELIMITER ;
CALL _mig024_add_col('monitoring_status', "monitoring_status ENUM('not_monitored','healthy','warning','stale','failing') NOT NULL DEFAULT 'not_monitored' COMMENT 'Stato monitoraggio continuo (calcolato da evidenze automatiche)' AFTER status");
CALL _mig024_add_col('last_checked_at', "last_checked_at DATETIME NULL COMMENT 'Ultima evidenza automatica ricevuta' AFTER last_verified_at");
CALL _mig024_add_col('freshness_days', "freshness_days SMALLINT NOT NULL DEFAULT 30 COMMENT 'Giorni entro cui un controllo deve essere ri-verificato da evidenza automatica'");
DROP PROCEDURE IF EXISTS _mig024_add_col;
-- ROLLBACK:
-- DROP TABLE IF EXISTS control_evidence_auto;
-- ALTER TABLE compliance_controls DROP COLUMN monitoring_status, DROP COLUMN last_checked_at, DROP COLUMN freshness_days;