2026-04-17·18 min read·

DORA Art.28–30: ICT Third-Party Risk — TSP Due Diligence, Risk Register, and Contractual Provisions for Financial Services (2026)

Post #409 in the sota.io EU Cyber Compliance Series

DORA Chapter V is the most operationally demanding part of the regulation for any financial entity that relies on external providers — which is every financial entity. Art.28–30 form the entry-point of Chapter V: they establish the risk management policy, define the due diligence process, and specify what must appear in every ICT contract.

Where DORA Chapter II defines what you build internally (ICT risk management), Chapter V defines how you manage the risk that enters through your supply chain. The two chapters are tightly linked: Art.28(7) requires your ICT third-party risk strategy to be embedded in your overall ICT risk management framework.

This guide covers the three foundational articles of Chapter V:


1. The DORA Chapter V Architecture

DORA Chapter V spans Art.28 through Art.44 and introduces a layered third-party risk regime:

Article RangeSubjectKey Obligation
Art.28–30Third-party risk managementPolicy, register, due diligence, contracts
Art.31Critical ICT Third-Party Providers (CTPPs)Designation criteria, oversight framework
Art.32–39Lead overseer mechanismESA-appointed lead overseer, oversight powers
Art.40–43Oversight rules and cooperationInformation exchange, inspections, on-site visits
Art.44Sub-outsourcingSub-contractor chain requirements

This guide focuses on Art.28–30 — the obligations that apply to every financial entity before any contract is signed.


2. Art.28: General Principles and ICT Third-Party Risk Policy

2.1 The Mandatory Policy

Art.28(1) requires financial entities to adopt and regularly review a documented strategy for ICT third-party risk. This is not a standalone document — it must be "part of the ICT risk management framework" (Art.28(7)).

The policy must cover:

Policy ElementDORA RequirementPractical Content
Objectives and scopeDefine what the policy governsAll ICT arrangements incl. cloud, SaaS, managed services
Risk classification methodologyHow services are tiered by criticalityCritical / important / standard / commodity
Due diligence processWhat checks are required per tierArt.29 criteria mapped to internal process
Contractual standardsMinimum provisions per tierArt.30 clauses plus internal additions
Monitoring and reviewOngoing oversight cadenceQuarterly review for Tier-1, annual for Tier-2/3
Exit strategyHow to exit a provider if neededPre-planned substitution paths
Concentration risk limitsMaximum exposure to single providersDORA Recital 64 guidance

2.2 The ICT Register of Arrangements

Art.28(3) requires financial entities to maintain a comprehensive register of all ICT third-party arrangements. This register must be available to competent authorities on request — it is a regulatory document, not just an internal tool.

Minimum register fields per Art.28(3):

FieldDescriptionExample
Provider name and LEILegal Entity Identifier where availableAWS EMEA SARL, LEI: 529900...
Service descriptionWhat is providedCloud infrastructure, object storage, database PaaS
Criticality classificationCritical/important/standardCritical
Data categoriesPersonal data? Financial data? Secret?Personal data (Art.4(1) GDPR), payment data
Location of data processingEEA vs third countryFrankfurt (EU-CENTRAL-1), within EEA
SubstitutabilityCan this service be replaced in <72h?No — >30 days (CTPP concentration risk flag)
Contract start / endFor renewal management2023-01-01 / 2026-12-31
SLA summaryRTO/RPO, uptime commitment99.99% SLA, 4h RTO
Sub-contractorsKey sub-outsourcing chainsData centre operators, CDN providers
Audit rightsWhether audit rights are contractually securedYes — Art.30(2)(f) clause present

Practical note: The EBA has indicated that NCAs will request the register during inspections. Entities that maintain it in a spreadsheet will face questions. A purpose-built tool or GRC platform is advisable for larger institutions.

2.3 Concentration Risk

Art.28(4) explicitly requires financial entities to identify and manage ICT concentration risk — the risk that over-reliance on a single provider creates a systemic exposure that threatens operational continuity.

DORA Recital 64 names the risk explicitly:

"Financial entities should be aware of and manage the risk of concentration, in particular when a critical or important function is wholly or substantially dependent on a single ICT third-party service provider."

Concentration risk indicators to monitor:

Risk DimensionTrigger Threshold (Guidance)Mitigation Approach
Single-provider dependency>70% of critical workloads on one providerMulti-cloud or hybrid architecture
Single-geography dependency>80% of data processing in one countryCross-region replication
Sub-contractor concentrationKey sub-contractor supports >5 in-scope entitiesContractual disclosure + contingency
Provider criticalityProvider designated as CTPP (Art.31)Enhanced oversight, exit strategy mandatory
Intra-group concentrationSame parent group as financial entityArm's-length contract, independent oversight

The concentration risk analysis must be documented and reviewed at least annually — or immediately when a new material arrangement is entered.

2.4 Cloud Arrangements and Art.28(2)

Art.28(2) states that when financial entities use cloud computing, the arrangements must be consistent with the proportionality principle and the entity's risk profile. The EBA Guidelines on ICT and Security Risk Management (EBA/GL/2019/04) — which remain in force alongside DORA — provide operational detail on cloud risk categories.

Art.28(8) carves out a specific rule: if a critical or important function is supported by an ICT arrangement, the financial entity must ensure the provider's sub-contractors are disclosed and contractually bound by equivalent standards. This is the "chain of compliance" requirement that feeds into Art.44 on sub-outsourcing.


3. Art.29: Preliminary Due Diligence

3.1 The Due Diligence Obligation

Art.29(1) states:

"Before entering into a contractual arrangement on the use of ICT services, financial entities shall conduct a preliminary due diligence assessment of ICT third-party service providers."

This is a pre-contract obligation. You cannot sign first and due-diligence later. NCAs have been explicit: retrofitting due diligence to existing contracts is acceptable during a transition phase, but for new arrangements the sequence is mandatory.

3.2 The Due Diligence Assessment Framework

Art.29(2) sets out the minimum scope of due diligence:

Due Diligence AreaDORA Art.29 RequirementPractical Check
Security policiesVerify the provider has documented security policiesRequest ISO 27001 certificate or SOC 2 Type II report
Incident responseAssess provider's incident detection and response capabilityReview incident history; check ESA/ENISA incident database
BCM/DRPEvaluate business continuity and disaster recovery capabilitiesRequest BCP documentation; test RTOs claimed in SLA
Information security certificationsReview applicable certificationsISO 27001, SOC 2 Type II, CSA STAR, BSI C5
Sub-contractor chainIdentify and assess key sub-contractorsRequest full sub-contractor list with LEIs
Financial soundnessAssess provider's financial stabilityAnnual report review; credit rating if public
Previous supervisory actionsCheck for sanctions from financial or data regulatorsESA enforcement databases; GDPR fines registry
Data residency and sovereigntyConfirm where data is processed and storedDPA / SCC review; third-country transfer analysis
AuditabilityConfirm audit rights are availablePre-contract negotiation of Art.30(2)(f) terms

3.3 Tiered Due Diligence

A proportionality-based approach is recognised by supervisors. Not every SaaS subscription requires the same scrutiny as a core banking migration. The recommended tiering:

TierCriteriaDue Diligence Depth
Tier 1 — CriticalSupports critical or important function; substitutability >30 daysFull Art.29 assessment + on-site visit
Tier 2 — ImportantSupports business-relevant function; substitutability 7–30 daysArt.29 core + certification review
Tier 3 — StandardNon-critical; easily substitutable (<7 days)Abbreviated due diligence; vendor questionnaire
Tier 4 — CommodityOff-the-shelf; no data processing; easily replacedRegistration only; standard contract

The criticality classification from the Art.28 register drives the tier assignment.

3.4 What NCAs Look for in Due Diligence Records

Based on supervisory guidance from BaFin (DE), DNB (NL), and the ECB:

  1. Evidence of assessment before signing — timestamped records showing due diligence was completed before the contract date
  2. Risk score justification — documented rationale for the tier classification
  3. Finding tracking — due diligence gaps logged and remediated (or accepted with documented risk acceptance)
  4. Re-assessment triggers — written criteria for when due diligence must be re-run (e.g., provider acquisition, major incident, sub-contractor change)
  5. Board awareness — for Tier-1 providers, board or senior management sign-off on the risk classification

4. Art.30: Minimum Contractual Provisions

4.1 The Mandatory Clause List

Art.30(2) contains the most specific requirements of the three articles. It mandates 16 categories of content that every ICT contract must include. NCAs will review contracts against this list.

#Mandatory ProvisionKey Detail
1Full description of servicesAll services to be provided; SaaS vs IaaS vs BPO distinctions
2Locations of data processingCountries where data is processed and stored
3Provisions on data accessibilityFinancial entity can access data during and after contract
4Availability, authenticity, integrity, confidentialitySecurity obligations per CIA triad
5SLA provisionsPerformance metrics, incident response times, availability targets
6Implementation assistanceProvider cooperates with transition-in and migration projects
7Cooperation with authoritiesProvider cooperates with ECB, EBA, ESMA, national CAs on request
8Right to auditFinancial entity (and its delegates) can audit provider
9Incident reportingProvider must report material ICT incidents to financial entity
10Business continuityProvider maintains BCP; financial entity can test their DRP
11Exit rightsContract termination rights — including for CTPP risk
12Sub-outsourcing rulesSub-contractor changes require prior notification or consent
13Data returnProvider returns data in portable format on contract end
14Cooperation with successor providerHandover assistance obligation
15Monitoring and performance reviewsMechanism for ongoing performance review
16Financial entity's right to terminateSpecific termination rights for material breach, insolvency, regulatory sanction

4.2 The Audit Rights Clause (Art.30(2)(f)) in Detail

The audit rights provision deserves special attention because it is the most frequently disputed in contract negotiations with large cloud providers.

Art.30(2)(f) requires that the financial entity has the right to conduct audits — either directly or through a designated third party. The ESA Joint Guidelines (JC 2023/84) clarify:

Practical negotiation approach:

ScenarioAcceptableNot Acceptable
Hyper-scaler (AWS/Azure/GCP)SOC 2 Type II + right to request additional informationSOC 2 only, no additional rights
Mid-size SaaS providerAnnual audit right + right to appoint third-party auditorNo audit right, certification only
Tier-1 critical providerDirect on-site inspection right + annual third-party auditPooled audit only with no independent trigger

4.3 The Sub-Outsourcing Clause (Art.30(2)(k))

Art.28(8) and Art.30(2)(k) together create the sub-outsourcing compliance chain. The contract must:

  1. Require the provider to notify the financial entity of any material change to the sub-contractor chain
  2. Require the provider to ensure sub-contractors are bound by equivalent security standards
  3. Give the financial entity the right to object to or terminate the arrangement if a sub-contractor change creates unacceptable risk

This clause is critical for cloud providers who routinely use infrastructure sub-contractors (data centre operators, CDN providers, DNS operators). The financial entity's due diligence must extend to material sub-contractors — Art.29(2) due diligence applies by reference.

4.4 Exit and Data Return Clauses (Art.30(2)(k), (m), (n))

The exit provisions are among the most operationally important. DORA requires:

Exit rights must cover:

Data return requirements:

Practical note: Many SaaS providers resist data portability clauses. NCAs have been clear: for Tier-1 and Tier-2 arrangements, non-portable data is a concentration risk that must be documented and mitigated.


5. The TSP Risk Register — Operational Implementation

Combining Art.28(3) register requirements with Art.29 due diligence outputs, the operational TSP risk register should contain:

TSP Register Entry Structure:
├── Provider metadata (name, LEI, HQ country, group structure)
├── Service description (detailed functional scope)
├── Criticality classification (Tier 1/2/3/4 + rationale)
├── Data classification (personal, financial, secret, public)
├── Concentration risk flags (single-provider, geography, sub-contractor)
├── Due diligence summary
│   ├── Assessment date
│   ├── Assessment team
│   ├── Findings (open/closed)
│   └── Risk acceptance sign-off
├── Contract metadata
│   ├── Contract ID, version
│   ├── Start/end date, renewal terms
│   ├── Art.30 clause coverage checklist
│   └── Audit rights status
├── Monitoring record
│   ├── Last SLA review date
│   ├── Incidents reported by provider
│   └── Sub-contractor change notifications
└── Exit plan
    ├── Substitutability score
    ├── Exit timeline estimate
    └── Alternative providers identified

6. Python DORAThirdPartyChecker

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
import json
from datetime import date, timedelta


class CriticalityTier(str, Enum):
    TIER1_CRITICAL = "critical"
    TIER2_IMPORTANT = "important"
    TIER3_STANDARD = "standard"
    TIER4_COMMODITY = "commodity"


class ComplianceStatus(str, Enum):
    COMPLIANT = "compliant"
    GAP = "gap"
    NOT_ASSESSED = "not_assessed"


@dataclass
class Art30ContractClause:
    """Represents a single mandatory Art.30(2) contractual provision."""
    clause_id: str
    description: str
    present: bool = False
    notes: str = ""


@dataclass
class DueDiligenceRecord:
    """Art.29 due diligence assessment for a single provider."""
    assessment_date: date
    assessor: str
    tier: CriticalityTier
    security_policy_reviewed: bool = False
    incident_response_reviewed: bool = False
    bcp_drp_reviewed: bool = False
    certifications_verified: bool = False
    subcontractor_chain_mapped: bool = False
    financial_soundness_checked: bool = False
    supervisory_history_checked: bool = False
    data_residency_confirmed: bool = False
    audit_rights_confirmed: bool = False
    open_findings: list[str] = field(default_factory=list)
    risk_acceptance_by: Optional[str] = None

    @property
    def completion_score(self) -> float:
        checks = [
            self.security_policy_reviewed,
            self.incident_response_reviewed,
            self.bcp_drp_reviewed,
            self.certifications_verified,
            self.subcontractor_chain_mapped,
            self.financial_soundness_checked,
            self.supervisory_history_checked,
            self.data_residency_confirmed,
            self.audit_rights_confirmed,
        ]
        return sum(checks) / len(checks)


@dataclass
class ICTProvider:
    """A registered ICT third-party service provider (Art.28 register)."""
    provider_name: str
    lei: Optional[str]
    hq_country: str
    service_description: str
    tier: CriticalityTier
    data_categories: list[str]
    processing_locations: list[str]
    substitutability_days: int
    due_diligence: Optional[DueDiligenceRecord] = None
    contract_clauses: list[Art30ContractClause] = field(default_factory=list)
    is_ctpp_designated: bool = False


@dataclass
class DORAThirdPartyCheckerReport:
    """Compliance report for Art.28-30 obligations."""
    provider_name: str
    tier: CriticalityTier
    art28_register_status: ComplianceStatus
    art29_due_diligence_status: ComplianceStatus
    art30_contract_status: ComplianceStatus
    concentration_risk_flags: list[str]
    missing_contract_clauses: list[str]
    due_diligence_gaps: list[str]
    overall_risk_score: str
    recommendations: list[str]

    def to_markdown(self) -> str:
        lines = [
            f"## DORA Art.28-30 Compliance Report: {self.provider_name}",
            f"**Tier:** {self.tier.value} | **Overall Risk:** {self.overall_risk_score}",
            "",
            "### Status Summary",
            f"| Article | Status |",
            f"|---|---|",
            f"| Art.28 — Register | {self.art28_register_status.value} |",
            f"| Art.29 — Due Diligence | {self.art29_due_diligence_status.value} |",
            f"| Art.30 — Contract Clauses | {self.art30_contract_status.value} |",
        ]
        if self.concentration_risk_flags:
            lines += ["", "### Concentration Risk Flags"]
            lines += [f"- {f}" for f in self.concentration_risk_flags]
        if self.missing_contract_clauses:
            lines += ["", "### Missing Contract Clauses (Art.30)"]
            lines += [f"- {c}" for c in self.missing_contract_clauses]
        if self.recommendations:
            lines += ["", "### Recommendations"]
            lines += [f"{i+1}. {r}" for i, r in enumerate(self.recommendations)]
        return "\n".join(lines)


class DORAThirdPartyChecker:
    """Evaluates Art.28-30 compliance for an ICT provider arrangement."""

    ART30_MANDATORY_CLAUSES = [
        "full_service_description",
        "data_processing_locations",
        "data_accessibility",
        "security_cia_obligations",
        "sla_provisions",
        "implementation_assistance",
        "authority_cooperation",
        "audit_rights",
        "incident_reporting",
        "business_continuity",
        "exit_rights",
        "suboutsourcing_notification",
        "data_return_portable",
        "successor_provider_cooperation",
        "performance_monitoring",
        "termination_rights",
    ]

    def __init__(self, provider: ICTProvider):
        self.provider = provider

    def check_art28_register(self) -> tuple[ComplianceStatus, list[str]]:
        gaps = []
        p = self.provider
        if not p.lei:
            gaps.append("Missing LEI — required for Art.28 register")
        if not p.data_categories:
            gaps.append("Data categories not documented")
        if not p.processing_locations:
            gaps.append("Processing locations not documented")
        if p.substitutability_days == 0:
            gaps.append("Substitutability assessment not completed")
        status = ComplianceStatus.COMPLIANT if not gaps else ComplianceStatus.GAP
        return status, gaps

    def check_art29_due_diligence(self) -> tuple[ComplianceStatus, list[str]]:
        gaps = []
        dd = self.provider.due_diligence
        if not dd:
            return ComplianceStatus.NOT_ASSESSED, ["No due diligence record found — Art.29 assessment required before contract"]
        if dd.completion_score < 1.0:
            for attr, label in [
                ("security_policy_reviewed", "Security policy review"),
                ("incident_response_reviewed", "Incident response review"),
                ("bcp_drp_reviewed", "BCP/DRP review"),
                ("certifications_verified", "Certification verification"),
                ("subcontractor_chain_mapped", "Sub-contractor chain mapping"),
                ("financial_soundness_checked", "Financial soundness check"),
                ("supervisory_history_checked", "Supervisory history check"),
                ("data_residency_confirmed", "Data residency confirmation"),
                ("audit_rights_confirmed", "Audit rights confirmation"),
            ]:
                if not getattr(dd, attr):
                    gaps.append(f"{label} not completed")
        if dd.open_findings:
            gaps.append(f"{len(dd.open_findings)} open due diligence findings not remediated")
        if self.provider.tier == CriticalityTier.TIER1_CRITICAL and not dd.risk_acceptance_by:
            gaps.append("Tier-1 provider: board/senior management sign-off required")
        status = ComplianceStatus.COMPLIANT if not gaps else ComplianceStatus.GAP
        return status, gaps

    def check_art30_clauses(self) -> tuple[ComplianceStatus, list[str]]:
        present_clause_ids = {c.clause_id for c in self.provider.contract_clauses if c.present}
        missing = [c for c in self.ART30_MANDATORY_CLAUSES if c not in present_clause_ids]
        status = ComplianceStatus.COMPLIANT if not missing else ComplianceStatus.GAP
        return status, missing

    def assess_concentration_risk(self) -> list[str]:
        flags = []
        if self.provider.substitutability_days > 30:
            flags.append(f"Substitutability >30 days ({self.provider.substitutability_days}d) — concentration risk")
        if self.provider.is_ctpp_designated:
            flags.append("Provider designated as CTPP (Art.31) — enhanced oversight required")
        third_countries = [loc for loc in self.provider.processing_locations
                          if loc not in ["DE", "FR", "NL", "IE", "AT", "BE", "ES", "IT", "PL",
                                        "SE", "FI", "DK", "PT", "LU", "CZ", "HU", "RO", "EEA"]]
        if third_countries:
            flags.append(f"Third-country processing detected: {', '.join(third_countries)} — SCCs/BCRs required")
        return flags

    def generate_report(self) -> DORAThirdPartyCheckerReport:
        art28_status, art28_gaps = self.check_art28_register()
        art29_status, art29_gaps = self.check_art29_due_diligence()
        art30_status, art30_missing = self.check_art30_clauses()
        concentration_flags = self.assess_concentration_risk()

        total_gaps = len(art28_gaps) + len(art29_gaps) + len(art30_missing) + len(concentration_flags)
        if total_gaps == 0:
            risk_score = "LOW"
        elif total_gaps <= 3:
            risk_score = "MEDIUM"
        elif total_gaps <= 7:
            risk_score = "HIGH"
        else:
            risk_score = "CRITICAL"

        recommendations = []
        if art28_gaps:
            recommendations.append("Complete Art.28 register entry — obtain LEI, document data categories and processing locations")
        if art29_status != ComplianceStatus.COMPLIANT:
            recommendations.append("Complete Art.29 due diligence before or immediately after contract signing")
        if art30_missing:
            recommendations.append(f"Renegotiate contract to add {len(art30_missing)} missing Art.30(2) provisions")
        if concentration_flags:
            recommendations.append("Document concentration risk in ICT third-party risk policy with mitigation measures")

        return DORAThirdPartyCheckerReport(
            provider_name=self.provider.provider_name,
            tier=self.provider.tier,
            art28_register_status=art28_status,
            art29_due_diligence_status=art29_status,
            art30_contract_status=art30_status,
            concentration_risk_flags=concentration_flags,
            missing_contract_clauses=art30_missing,
            due_diligence_gaps=art29_gaps,
            overall_risk_score=risk_score,
            recommendations=recommendations,
        )


# Usage example
provider = ICTProvider(
    provider_name="CloudCore EU GmbH",
    lei="529900ABCDEF123456789",
    hq_country="DE",
    service_description="Core banking platform PaaS — transaction processing, account management, reporting",
    tier=CriticalityTier.TIER1_CRITICAL,
    data_categories=["personal_data", "payment_data", "financial_data"],
    processing_locations=["DE", "NL"],
    substitutability_days=45,
    due_diligence=DueDiligenceRecord(
        assessment_date=date(2025, 11, 15),
        assessor="ICT Risk Team",
        tier=CriticalityTier.TIER1_CRITICAL,
        security_policy_reviewed=True,
        incident_response_reviewed=True,
        bcp_drp_reviewed=True,
        certifications_verified=True,
        subcontractor_chain_mapped=True,
        financial_soundness_checked=True,
        supervisory_history_checked=False,
        data_residency_confirmed=True,
        audit_rights_confirmed=True,
        open_findings=["Sub-contractor list not complete — CDN provider missing"],
        risk_acceptance_by="CRO sign-off 2025-11-20",
    ),
    contract_clauses=[
        Art30ContractClause("full_service_description", "Full service description", True),
        Art30ContractClause("data_processing_locations", "Data processing locations", True),
        Art30ContractClause("data_accessibility", "Data accessibility", True),
        Art30ContractClause("security_cia_obligations", "Security CIA obligations", True),
        Art30ContractClause("sla_provisions", "SLA provisions", True),
        Art30ContractClause("implementation_assistance", "Implementation assistance", True),
        Art30ContractClause("authority_cooperation", "Authority cooperation", True),
        Art30ContractClause("audit_rights", "Audit rights", True),
        Art30ContractClause("incident_reporting", "Incident reporting", True),
        Art30ContractClause("business_continuity", "Business continuity", True),
        Art30ContractClause("exit_rights", "Exit rights", True),
        Art30ContractClause("suboutsourcing_notification", "Sub-outsourcing notification", True),
        Art30ContractClause("data_return_portable", "Data return portable", False),  # gap
        Art30ContractClause("successor_provider_cooperation", "Successor cooperation", False),  # gap
        Art30ContractClause("performance_monitoring", "Performance monitoring", True),
        Art30ContractClause("termination_rights", "Termination rights", True),
    ],
)

checker = DORAThirdPartyChecker(provider)
report = checker.generate_report()
print(report.to_markdown())

Output:

## DORA Art.28-30 Compliance Report: CloudCore EU GmbH
**Tier:** critical | **Overall Risk:** HIGH

### Status Summary
| Article | Status |
|---|---|
| Art.28 — Register | compliant |
| Art.29 — Due Diligence | gap |
| Art.30 — Contract Clauses | gap |

### Concentration Risk Flags
- Substitutability >30 days (45d) — concentration risk

### Missing Contract Clauses (Art.30)
- data_return_portable
- successor_provider_cooperation

### Recommendations
1. Complete Art.29 due diligence before or immediately after contract signing
2. Renegotiate contract to add 2 missing Art.30(2) provisions
3. Document concentration risk in ICT third-party risk policy with mitigation measures

7. DORA Art.28–30 × NIS2 Art.21(2)(d) Dual Compliance

DORA and NIS2 overlap substantially on supply chain security. For entities subject to both (e.g., a bank that also operates essential digital infrastructure), the following mapping applies:

ObligationDORA Art.28–30NIS2 Art.21(2)(d)Dual-Compliance Approach
Third-party risk policyArt.28(1) — documented strategyArt.21(2)(d) — supply chain security policySingle policy covering both; DORA lex specialis for financial entities
Provider due diligenceArt.29 — preliminary assessmentArt.21(2)(d) — supplier risk assessmentUnified vendor assessment form; DORA clauses take precedence
Contractual provisionsArt.30(2) — 16 mandatory clausesArt.21(2)(d) — security requirements in supplier contractsDORA Art.30 checklist satisfies NIS2 if security CIA clauses included
Sub-contractor chainArt.28(8), Art.44Art.21(2)(d) — indirect suppliersDORA more specific — apply DORA chain requirements
Audit rightsArt.30(2)(f)Art.21(2)(d) impliedDORA Art.30 explicit clause sufficient
Incident notification from suppliersArt.30(2)(h)Art.23 chain notificationDORA clause covers NIS2 need for financial entities

Lex specialis principle: DORA Recital 16 states that DORA is lex specialis to NIS2 for financial entities. Where both apply, DORA provisions take precedence. The practical approach: build a DORA-first contract template that also covers NIS2 Art.21(2)(d) requirements — no separate NIS2 contract template needed.


8. Common NCA Audit Failures

Based on supervisory findings from BaFin (DE), DNB (NL), AMF (FR), and ECB SSM reports on ICT outsourcing risk:

Failure 1: Incomplete or Stale Register

The Art.28 register exists but is not kept up to date. Sub-contractor changes are not reflected. Data category entries are generic ("financial data") without specificity. NCAs expect the register to be a live, accurate document — not a one-time compliance exercise.

Fix: Integrate register updates into the change management process. Any new contract, amendment, or sub-contractor change must trigger a register update within 5 business days.

Failure 2: Due Diligence Post-Dating

Internal records show due diligence was completed after the contract was signed. Even where this is a minor timing issue, NCAs treat it as a control failure because Art.29(1) is explicit: "before entering into a contractual arrangement."

Fix: Mandate that the contract signing process requires a completed due diligence record as a prerequisite. GRC tools can enforce this as a gate.

Failure 3: Missing Art.30(2)(f) Audit Rights for Cloud Providers

The most common gap: the contract with a cloud provider (AWS, Azure, GCP) states that audits are satisfied by SOC 2 Type II review and does not include any right to request additional information or conduct supplementary checks. This is insufficient under Art.30(2)(f).

Fix: Negotiate an addendum to cloud contracts that specifies the right to (a) request specific information within 30 days, and (b) appoint a third-party auditor to conduct a targeted assessment. Major cloud providers have standard DORA/EBA addenda available.

Failure 4: No Concentration Risk Documentation

The register lists providers but there is no analysis of concentration risk. NCAs specifically ask: "Which critical functions would be unavailable if provider X failed?" Without a documented analysis, this is a gap.

Fix: Add a concentration risk section to the annual ICT risk report. Map critical functions to providers; identify single points of failure; document mitigations (multi-cloud, manual fallback, alternative provider contracts).

Failure 5: Exit Plans That Are Not Operationally Tested

Exit clauses exist in the contract but there is no evidence that exit procedures have been tested or that alternative providers have been identified. Art.28(1) requires the exit strategy to be "operationally feasible."

Fix: Conduct an annual exit readiness exercise for Tier-1 providers. Document: who the alternative providers are, how long migration would take, what dependencies must be resolved. Store the output in the TSP register.

Failure 6: Inadequate Sub-Outsourcing Visibility

The financial entity does not know the full sub-contractor chain of its Tier-1 provider. Art.28(8) requires disclosure and equivalent security obligations throughout the chain.

Fix: Require annual sub-contractor disclosure as a contract obligation. Include this in the Art.30 clause template. Review sub-contractor changes when notified — escalate material changes to the risk function.

Failure 7: Generic SLAs Without DORA-Aligned Metrics

The SLA covers uptime (e.g., 99.9%) but does not address ICT incident notification timelines, RTO/RPO for specific functions, or security event escalation paths. Art.30(2)(e) requires SLA provisions — supervisors expect these to be DORA-aware.

Fix: Include in the SLA: (a) incident notification within 4 hours for major ICT incidents (Art.19 alignment), (b) RTO/RPO for each supported function by criticality tier, (c) escalation path for zero-day vulnerabilities.


9. Art.28–30 Compliance Checklist — 25 Items for NCA Audit Readiness

Art.28 — General Principles and Register (Items 1–10)

#ItemStatus
REG-01ICT third-party risk strategy documented and board-approved
REG-02Strategy integrated into overall ICT risk management framework (Art.28(7))
REG-03Register covers all ICT arrangements (incl. cloud, SaaS, managed services)
REG-04Register includes provider LEI where available
REG-05Register documents criticality tier (Tier 1/2/3/4) with rationale
REG-06Register documents data categories and processing locations
REG-07Substitutability score recorded for each provider
REG-08Register reviewed and updated at least annually (or on material change)
REG-09Concentration risk analysis completed and documented
REG-10Sub-contractor chain mapped for all Tier-1 providers

Art.29 — Due Diligence (Items 11–17)

#ItemStatus
DD-01Due diligence completed before contract signing for all new arrangements
DD-02Assessment covers all 9 Art.29(2) domains
DD-03Assessment records are dated and retained (min. 5 years)
DD-04Open findings from due diligence are tracked to closure
DD-05Tier-1 providers: board/senior management sign-off documented
DD-06Re-assessment triggers defined (acquisition, major incident, sub-contractor change)
DD-07Due diligence integrated into contract management process as a gate

Art.30 — Contractual Provisions (Items 18–25)

#ItemStatus
CON-01All 16 Art.30(2) mandatory clauses present in every ICT contract
CON-02Audit rights clause specifies right to appoint third-party auditor
CON-03SLA includes ICT incident notification timeline (≤4h for major incidents)
CON-04Exit rights cover CTPP-designation scenario
CON-05Data return clause specifies portable, industry-standard format
CON-06Sub-outsourcing clause requires prior notification of material changes
CON-07Contract template reviewed against Art.30 checklist before every new signing
CON-08Cloud provider addenda (DORA/EBA) obtained and filed with contract

10. Implementation Timeline — 16 Weeks to Art.28–30 Readiness

WeekMilestoneOwner
1–2Draft ICT third-party risk policy; map to existing frameworkCRO / ICT Risk
3–4Inventory all ICT arrangements; classify by criticality tierProcurement + ICT
5–6Build Art.28 register; obtain missing LEIs and data-category confirmationsICT Risk
7–8Complete concentration risk analysis; identify single-provider dependenciesICT Risk + Architecture
9–10Run Art.29 due diligence on all Tier-1 and Tier-2 providersVendor Management
11–12Review all Tier-1/2 contracts against Art.30(2) checklist; identify gapsLegal + Procurement
13–14Negotiate contract amendments for Art.30 gaps; obtain cloud addendaLegal
15Board presentation: policy approval, concentration risk summaryCRO → Board
16First annual register review completed; monitoring cadence establishedICT Risk

Key Takeaways

Art.28 demands more than a spreadsheet — it requires a living register that accurately reflects your ICT supply chain, including sub-contractor chains and concentration risk. The register is a regulatory document.

Art.29 is a pre-contract gate, not a post-hoc exercise. The sequence matters: assess first, sign second. Build this into your procurement workflow.

Art.30 provides the most specific compliance checklist in DORA: 16 mandatory contract clauses. Review every contract against this list. Cloud providers have DORA addenda — request them.

The next step in Chapter V is Art.31: Critical ICT Third-Party Provider (CTPP) designation. The ESAs have begun the designation process for the first wave of CTPPs. If any of your Tier-1 providers are designated, Art.32–39 oversight obligations will apply.


Covered in this series: Art.5–9 · Art.10 · Art.11 · Art.12 · Art.13 · Art.14 · Art.19 · Art.26–27 · Art.28–30 (this post) Coming next: Art.31 — Critical ICT Third-Party Provider Oversight Framework