dora
doraincident-reportingarticle-17postgresql

DORA ICT Incident Reporting: Database-Level Implementation Guide

Implement DORA Article 17-19 incident reporting in PostgreSQL. Structured breach logging, classification, and regulatory notification timelines.

RL
Robert Langner
Managing Director, NILS Software GmbH · · 3 min read

DORA Incident Lifecycle

DORA requires a structured incident management process:

1. Detection and Classification

SELECT pgcomply.report_breach(
  'Database connection pool exhaustion',
  'Connection pool saturated at 100/100. Application returning 503 errors for 12 minutes.',
  'major',
  cause := 'Runaway query from analytics dashboard held connections',
  affected_services := ARRAY['payment-api', 'user-auth'],
  subjects_count := 0
);

2. Tracking and Updates

-- Update investigation progress
SELECT pgcomply.update_breach('INC-2026-0004',
  status := 'contained',
  remediation := 'Killed runaway query. Added statement_timeout = 30s for analytics role.'
);

-- Check timeline
SELECT * FROM pgcomply.breach_status();

3. Regulatory Reporting

For major incidents, generate the structured report:

-- Pro: Generate DORA incident report
SELECT pgcomply.dora_report('incident', 'INC-2026-0004');

4. Post-Incident Review

SELECT pgcomply.update_breach('INC-2026-0004',
  status := 'resolved',
  root_cause := 'Missing statement_timeout for analytics role allowed unbounded queries',
  lessons_learned := 'All non-admin roles now have statement_timeout. Added connection monitoring alert.',
  preventive_actions := ARRAY[
    'Set statement_timeout = 30s for all non-admin roles',
    'Added pg_stat_activity monitoring via pgcomply.idle_users()',
    'Weekly health_check now includes connection utilization'
  ]
);

Building an Incident History

DORA Article 12 requires organizations to learn from incidents. Query your incident history:

SELECT id, title, severity, status, created_at, resolved_at,
  resolved_at - created_at AS resolution_time
FROM pgcomply.breach_log
ORDER BY created_at DESC;

Track metrics over time: mean time to detection, mean time to resolution, incidents by category, and recurring root causes.

Incident Classification Framework

Not every issue is a DORA-reportable incident. Use this classification:

| Severity | Criteria | Reporting | Timeline | |----------|----------|-----------|----------| | Critical | Core services down, data loss, widespread client impact | Regulator + Board | 4h initial, 72h intermediate, 1m final | | Major | Significant degradation, limited data exposure, many clients affected | Regulator | 4h initial, 72h intermediate, 1m final | | Minor | Limited impact, no data loss, few clients affected | Internal only | Document within 1 week | | Near-miss | Vulnerability found but not exploited | Internal only | Document for learning |

-- Classification determines reporting obligations
SELECT pgcomply.report_breach(
  'Connection pool exhaustion during peak load',
  'Payment API returned 503 errors for 8 minutes affecting ~200 transactions',
  'minor',   -- Internal documentation only
  cause := 'Insufficient connection pool sizing for Black Friday traffic',
  affected_services := ARRAY['payment-api'],
  subjects_count := 200
);

Building an Incident Playbook

Before an incident occurs, define your response procedure:

-- Pre-create your incident response checklist
SELECT pgcomply.checklist_update('dora', 'ART-17',
  'implemented',
  assigned_to := 'CTO',
  evidence := 'Incident playbook v2.1 in Confluence, pgcomply.report_breach() configured'
);

The playbook should define:

  1. Who declares an incident — typically the on-call engineer or security team lead
  2. Classification criteria — use the table above, adapted to your business
  3. Communication channels — Slack #incident channel, phone tree for critical
  4. Regulatory contacts — your BaFin or national authority contact details
  5. Evidence collectionpgcomply.breach_status(), pgcomply.ddl_history(), pgcomply.dml_history()

Post-Incident Analysis Template

After resolution, document the full lifecycle:

SELECT pgcomply.update_breach('INC-2026-0004',
  status := 'resolved',
  root_cause := 'Connection pool configured for 50 connections, peak load required 120. '
    || 'Analytics dashboard held 15 idle connections reducing available pool.',
  lessons_learned := 'Implemented per-role connection limits. Analytics role now has '
    || 'statement_timeout=30s and max 10 connections via pgbouncer.',
  preventive_actions := ARRAY[
    'Per-role connection limits via PgBouncer',
    'Automated connection_audit() alerting via webhook',
    'Load testing added to quarterly resilience testing calendar'
  ]
);

Summary

DORA incident reporting requires structure, speed, and evidence. pgcomply provides structured incident logging with classification, timeline tracking, regulatory report generation, and post-incident documentation. Build the process before you need it — the clock starts ticking the moment an incident is detected.

Frequently Asked Questions

How does DORA classify ICT incidents?
DORA uses impact-based classification. Major incidents are those affecting critical functions, causing significant financial loss, or impacting a large number of clients. The classification determines reporting obligations: major incidents require regulatory notification, while minor incidents need only internal documentation.
What is the reporting timeline for DORA incidents?
For major incidents: initial notification within 4 hours of classification, intermediate report within 72 hours, and final report within one month. The initial notification must include: incident classification, affected services, estimated impact, and initial remediation actions.

Related Articles