Security Alert Management

Manage security alerts, notifications, and response workflows

All recipes· security-surveillance· 10 minutesintermediate

Security Alert Management

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

Run this on your own machine

Install SynapCores Community Edition free, paste the SQL or Cypher above into the bundled web UI, and watch it run.

Download Free CE