Skip to content

SynapCores / Recipe

Security Alert Management

Manage security alerts, notifications, and response workflows

All recipes· security-surveillance· 10 minutesintermediate
Instance: localhost:8080

Opens your running SynapCores (Security Alert Management will be staged for a preview — nothing runs until you click Run). No instance yet? Install free in ~30s.

Share

Objective

Create a comprehensive security alert management system for tracking alerts, managing notifications, and coordinating response workflows across security operations.

Step 1: Create Alert Types Table

Define alert categories.

CREATE TABLE alert_types (
    id INTEGER PRIMARY KEY,
    type_code VARCHAR(50) NOT NULL UNIQUE,
    type_name VARCHAR(100),
    category VARCHAR(50),
    default_priority VARCHAR(20),
    default_sla_minutes INTEGER,
    auto_escalate BOOLEAN DEFAULT FALSE,
    escalation_minutes INTEGER,
    notification_template TEXT,
    is_active BOOLEAN DEFAULT TRUE
);

Step 2: Create Alert Sources Table

Track alert origins.

CREATE TABLE alert_sources (
    id INTEGER PRIMARY KEY,
    source_id VARCHAR(50) NOT NULL UNIQUE,
    source_name VARCHAR(200),
    source_type VARCHAR(50),
    location VARCHAR(200),
    zone VARCHAR(100),
    is_active BOOLEAN DEFAULT TRUE,
    last_alert_time TIMESTAMP,
    total_alerts INTEGER DEFAULT 0
);

Step 3: Create Security Alerts Table

Store alert records.

CREATE TABLE security_alerts (
    id INTEGER PRIMARY KEY,
    alert_uid VARCHAR(100) NOT NULL UNIQUE,
    alert_type_id INTEGER NOT NULL,
    source_id INTEGER NOT NULL,
    alert_time TIMESTAMP NOT NULL,
    priority VARCHAR(20),
    title VARCHAR(255),
    description TEXT,
    alert_data TEXT,
    snapshot IMAGE(JPEG),
    video_clip VIDEO(MP4),
    status VARCHAR(50) DEFAULT 'new',
    assigned_to VARCHAR(100),
    acknowledged BOOLEAN DEFAULT FALSE,
    acknowledged_by VARCHAR(100),
    acknowledged_at TIMESTAMP,
    resolved BOOLEAN DEFAULT FALSE,
    resolved_by VARCHAR(100),
    resolved_at TIMESTAMP,
    resolution_code VARCHAR(50),
    resolution_notes TEXT,
    false_positive BOOLEAN DEFAULT FALSE,
    sla_due_at TIMESTAMP,
    sla_breached BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (alert_type_id) REFERENCES alert_types(id),
    FOREIGN KEY (source_id) REFERENCES alert_sources(id)
);

Step 4: Create Alert Notifications Table

Track notification delivery.

CREATE TABLE alert_notifications (
    id INTEGER PRIMARY KEY,
    alert_id INTEGER NOT NULL,
    notification_type VARCHAR(50),
    recipient VARCHAR(200),
    recipient_role VARCHAR(100),
    channel VARCHAR(50),
    sent_at TIMESTAMP,
    delivered BOOLEAN DEFAULT FALSE,
    delivered_at TIMESTAMP,
    read_status BOOLEAN DEFAULT FALSE,
    read_at TIMESTAMP,
    response_action VARCHAR(100),
    FOREIGN KEY (alert_id) REFERENCES security_alerts(id)
);

Step 5: Create Alert Escalations Table

Track escalation history.

CREATE TABLE alert_escalations (
    id INTEGER PRIMARY KEY,
    alert_id INTEGER NOT NULL,
    escalation_level INTEGER,
    escalated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    escalated_to VARCHAR(100),
    escalation_reason VARCHAR(255),
    previous_assignee VARCHAR(100),
    FOREIGN KEY (alert_id) REFERENCES security_alerts(id)
);

Step 6: Create Alert Comments Table

Store investigation notes.

CREATE TABLE alert_comments (
    id INTEGER PRIMARY KEY,
    alert_id INTEGER NOT NULL,
    comment_text TEXT,
    comment_by VARCHAR(100),
    comment_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_internal BOOLEAN DEFAULT TRUE,
    attachment_type VARCHAR(50),
    attachment_file IMAGE(JPEG),
    FOREIGN KEY (alert_id) REFERENCES security_alerts(id)
);

Step 7: Insert Alert Types

Define alert categories.

INSERT INTO alert_types (id, type_code, type_name, category, default_priority, default_sla_minutes, auto_escalate, escalation_minutes) VALUES
    (1, 'MOTION_RESTRICTED', 'Motion in Restricted Area', 'intrusion', 'high', 5, TRUE, 10),
    (2, 'MOTION_AFTER_HOURS', 'After-Hours Motion', 'intrusion', 'medium', 15, TRUE, 30),
    (3, 'ACCESS_DENIED', 'Access Denied Alert', 'access_control', 'low', 30, FALSE, NULL),
    (4, 'ACCESS_TAILGATING', 'Tailgating Detected', 'access_control', 'high', 5, TRUE, 10),
    (5, 'DOOR_HELD_OPEN', 'Door Held Open', 'access_control', 'medium', 10, TRUE, 20),
    (6, 'CAMERA_OFFLINE', 'Camera Offline', 'system', 'medium', 15, TRUE, 30),
    (7, 'LPR_WATCHLIST', 'Watchlist Vehicle Detected', 'vehicle', 'critical', 2, TRUE, 5),
    (8, 'FACE_WATCHLIST', 'Watchlist Face Detected', 'biometric', 'critical', 2, TRUE, 5),
    (9, 'PANIC_BUTTON', 'Panic Button Activated', 'emergency', 'critical', 1, TRUE, 3),
    (10, 'FIRE_ALARM', 'Fire Alarm Triggered', 'emergency', 'critical', 1, TRUE, 2),
    (11, 'PERIMETER_BREACH', 'Perimeter Breach', 'intrusion', 'critical', 2, TRUE, 5),
    (12, 'LOITERING', 'Loitering Detected', 'behavioral', 'low', 30, FALSE, NULL);

Step 8: Insert Alert Sources

Add alert origins.

INSERT INTO alert_sources (id, source_id, source_name, source_type, location, zone, total_alerts) VALUES
    (1, 'CAM-SERVER-001', 'Server Room Camera', 'camera', 'Building A Floor 2', 'Restricted Zone', 45),
    (2, 'CAM-LOBBY-001', 'Lobby Camera', 'camera', 'Building A Ground', 'Common Area', 128),
    (3, 'CAM-PARK-001', 'Parking Lot Camera', 'camera', 'Parking Lot A', 'Parking Zone', 256),
    (4, 'ACC-MAIN-001', 'Main Entrance Access', 'access_control', 'Building A Ground', 'Entry Zone', 89),
    (5, 'ACC-SERVER-001', 'Server Room Access', 'access_control', 'Building A Floor 2', 'Restricted Zone', 23),
    (6, 'LPR-GATE-001', 'Main Gate LPR', 'lpr', 'Main Gate', 'Perimeter', 312),
    (7, 'FR-MAIN-001', 'Main Entrance FR', 'facial_recognition', 'Building A Ground', 'Entry Zone', 67),
    (8, 'PANIC-LOBBY-001', 'Lobby Panic Button', 'panic', 'Building A Ground', 'Common Area', 3),
    (9, 'FIRE-BLD-A', 'Building A Fire System', 'fire', 'Building A', 'Entire Building', 2),
    (10, 'FENCE-NORTH', 'North Fence Sensor', 'perimeter', 'North Perimeter', 'Perimeter', 18);

Step 9: Insert Security Alerts

Add sample alerts.

INSERT INTO security_alerts (id, alert_uid, alert_type_id, source_id, alert_time, priority, title, description, status, assigned_to, acknowledged, acknowledged_by, acknowledged_at, resolved, resolved_by, resolved_at, resolution_code, resolution_notes, false_positive, sla_due_at, sla_breached) VALUES
    (1, 'ALT-20240115-001', 1, 1, '2024-01-15 02:30:45', 'high', 'Motion in Server Room', 'Motion detected in server room during non-business hours', 'resolved', 'Security Team Lead', TRUE, 'Officer Jones', '2024-01-15 02:32:00', TRUE, 'Officer Jones', '2024-01-15 02:45:00', 'authorized', 'Scheduled maintenance by IT team verified', FALSE, '2024-01-15 02:35:45', FALSE),
    (2, 'ALT-20240115-002', 4, 4, '2024-01-15 08:45:22', 'high', 'Tailgating at Main Entrance', 'Multiple badge reads within 3 seconds at main entrance', 'resolved', 'Security Officer', TRUE, 'Officer Smith', '2024-01-15 08:46:00', TRUE, 'Officer Smith', '2024-01-15 08:55:00', 'genuine', 'Two employees entered together, policy reminder issued', FALSE, '2024-01-15 08:50:22', FALSE),
    (3, 'ALT-20240115-003', 7, 6, '2024-01-15 09:15:30', 'critical', 'Watchlist Vehicle at Gate', 'Vehicle on security watchlist detected at main gate', 'investigating', 'Security Manager', TRUE, 'Security Manager', '2024-01-15 09:16:00', FALSE, NULL, NULL, NULL, NULL, FALSE, '2024-01-15 09:17:30', FALSE),
    (4, 'ALT-20240115-004', 2, 2, '2024-01-15 22:30:00', 'medium', 'After-Hours Motion in Lobby', 'Motion detected in lobby after business hours', 'resolved', 'Night Security', TRUE, 'Officer Davis', '2024-01-15 22:32:00', TRUE, 'Officer Davis', '2024-01-15 22:40:00', 'false_alarm', 'Cleaning crew, verified on schedule', TRUE, '2024-01-15 22:45:00', FALSE),
    (5, 'ALT-20240115-005', 6, 2, '2024-01-15 14:22:18', 'medium', 'Camera Offline', 'Lobby camera lost connection', 'resolved', 'IT Support', TRUE, 'IT Tech', '2024-01-15 14:25:00', TRUE, 'IT Tech', '2024-01-15 14:45:00', 'technical', 'Network cable reconnected', FALSE, '2024-01-15 14:37:18', FALSE),
    (6, 'ALT-20240115-006', 5, 5, '2024-01-15 10:05:00', 'medium', 'Server Room Door Held Open', 'Server room door held open beyond threshold', 'resolved', 'Security Officer', TRUE, 'Officer Jones', '2024-01-15 10:06:00', TRUE, 'Officer Jones', '2024-01-15 10:10:00', 'genuine', 'Equipment delivery, supervised entry logged', FALSE, '2024-01-15 10:15:00', FALSE),
    (7, 'ALT-20240115-007', 12, 3, '2024-01-15 15:45:00', 'low', 'Loitering in Parking Lot', 'Individual loitering near building entrance for 15+ minutes', 'new', NULL, FALSE, NULL, NULL, FALSE, NULL, NULL, NULL, NULL, FALSE, '2024-01-15 16:15:00', FALSE),
    (8, 'ALT-20240115-008', 11, 10, '2024-01-15 03:22:45', 'critical', 'North Fence Breach', 'Perimeter sensor triggered on north fence', 'resolved', 'Response Team', TRUE, 'Team Lead', '2024-01-15 03:23:30', TRUE, 'Team Lead', '2024-01-15 03:35:00', 'false_alarm', 'Wildlife (deer) confirmed on camera', TRUE, '2024-01-15 03:24:45', FALSE);

Step 10: Insert Notifications

Track notification delivery.

INSERT INTO alert_notifications (id, alert_id, notification_type, recipient, recipient_role, channel, sent_at, delivered, delivered_at, read_status, read_at, response_action) VALUES
    (1, 1, 'initial', 'security-team@company.com', 'Security Team', 'email', '2024-01-15 02:30:48', TRUE, '2024-01-15 02:30:50', TRUE, '2024-01-15 02:31:30', 'acknowledged'),
    (2, 1, 'initial', '+1-555-0101', 'On-Duty Officer', 'sms', '2024-01-15 02:30:48', TRUE, '2024-01-15 02:30:49', TRUE, '2024-01-15 02:31:00', 'responded'),
    (3, 3, 'initial', 'security-manager@company.com', 'Security Manager', 'email', '2024-01-15 09:15:32', TRUE, '2024-01-15 09:15:34', TRUE, '2024-01-15 09:15:50', 'acknowledged'),
    (4, 3, 'initial', '+1-555-0100', 'Security Manager', 'sms', '2024-01-15 09:15:32', TRUE, '2024-01-15 09:15:33', TRUE, '2024-01-15 09:15:45', 'responded'),
    (5, 3, 'initial', 'Security Operations', 'SOC', 'push', '2024-01-15 09:15:32', TRUE, '2024-01-15 09:15:33', TRUE, '2024-01-15 09:15:40', 'viewed'),
    (6, 8, 'initial', 'response-team@company.com', 'Response Team', 'email', '2024-01-15 03:22:48', TRUE, '2024-01-15 03:22:50', TRUE, '2024-01-15 03:23:00', 'acknowledged'),
    (7, 8, 'initial', '+1-555-0102', 'Response Team Lead', 'sms', '2024-01-15 03:22:48', TRUE, '2024-01-15 03:22:49', TRUE, '2024-01-15 03:23:10', 'responded');

Step 11: Insert Alert Comments

Add investigation notes.

INSERT INTO alert_comments (id, alert_id, comment_text, comment_by, is_internal) VALUES
    (1, 1, 'Checked camera footage - IT maintenance team present with work order #IT-2024-0115', 'Officer Jones', TRUE),
    (2, 1, 'Verified with IT Manager - scheduled maintenance confirmed', 'Officer Jones', TRUE),
    (3, 3, 'Vehicle matched to banned former contractor. Security manager notified.', 'SOC Analyst', TRUE),
    (4, 3, 'Vehicle did not attempt entry - departed after 2 minutes at gate', 'Security Manager', TRUE),
    (5, 8, 'Response team dispatched immediately. ETA 2 minutes.', 'SOC Analyst', TRUE),
    (6, 8, 'On scene - no human presence detected. Reviewing camera footage.', 'Team Lead', TRUE),
    (7, 8, 'Camera footage shows deer crossing detection zone. False alarm confirmed.', 'Team Lead', TRUE);

Step 12: Get Active Alerts

List current alerts.

SELECT
    sa.alert_uid,
    at.type_name,
    asrc.source_name,
    sa.alert_time,
    sa.priority,
    sa.title,
    sa.status,
    sa.assigned_to,
    sa.acknowledged
FROM security_alerts sa
INNER JOIN alert_types at ON sa.alert_type_id = at.id
INNER JOIN alert_sources asrc ON sa.source_id = asrc.id
WHERE sa.resolved = FALSE
ORDER BY
    CASE sa.priority
        WHEN 'critical' THEN 1
        WHEN 'high' THEN 2
        WHEN 'medium' THEN 3
        WHEN 'low' THEN 4
    END,
    sa.alert_time DESC;

Step 13: Alert Response Time Analysis

Measure response performance.

SELECT
    at.type_name,
    at.default_sla_minutes as sla_target,
    COUNT(sa.id) as total_alerts,
    AVG(EXTRACT(EPOCH FROM (sa.acknowledged_at - sa.alert_time)) / 60) as avg_ack_minutes,
    COUNT(CASE WHEN sa.sla_breached THEN 1 END) as sla_breaches,
    COUNT(CASE WHEN sa.false_positive THEN 1 END) as false_positives
FROM security_alerts sa
INNER JOIN alert_types at ON sa.alert_type_id = at.id
WHERE sa.acknowledged = TRUE
GROUP BY at.id, at.type_name, at.default_sla_minutes
ORDER BY total_alerts DESC;

Step 14: Alert Volume by Source

Analyze alert patterns.

SELECT
    asrc.source_name,
    asrc.zone,
    asrc.source_type,
    COUNT(sa.id) as alert_count,
    COUNT(CASE WHEN sa.false_positive THEN 1 END) as false_positives,
    CAST(COUNT(CASE WHEN sa.false_positive THEN 1 END) AS DECIMAL) / NULLIF(COUNT(sa.id), 0) * 100 as false_positive_rate
FROM alert_sources asrc
LEFT JOIN security_alerts sa ON asrc.id = sa.source_id
    AND sa.alert_time >= CURRENT_DATE - 30
GROUP BY asrc.id, asrc.source_name, asrc.zone, asrc.source_type
ORDER BY alert_count DESC;

Step 15: Resolution Code Analysis

Review resolution patterns.

SELECT
    sa.resolution_code,
    COUNT(*) as count,
    AVG(EXTRACT(EPOCH FROM (sa.resolved_at - sa.alert_time)) / 60) as avg_resolution_min
FROM security_alerts sa
WHERE sa.resolved = TRUE
  AND sa.alert_time >= CURRENT_DATE - 30
GROUP BY sa.resolution_code
ORDER BY count DESC;

Cleanup (Optional)

DROP TABLE IF EXISTS alert_comments;
DROP TABLE IF EXISTS alert_escalations;
DROP TABLE IF EXISTS alert_notifications;
DROP TABLE IF EXISTS security_alerts;
DROP TABLE IF EXISTS alert_sources;
DROP TABLE IF EXISTS alert_types;

Expected Outcomes

  • Alert types defined
  • Alerts tracked
  • Notifications logged
  • Response measured
  • Patterns analyzed

Priority Levels

Priority Response Target
critical < 2 minutes
high < 5 minutes
medium < 15 minutes
low < 30 minutes

Key Concepts Learned

  • Alert categorization
  • SLA management
  • Notification tracking
  • Response analysis
  • False positive tracking

Tags

sqlintermediatesecurityalertsnotificationsworkflow