2026-04-28·14 min read·sota.io team

NIS2 Compliance on EU-Native PaaS: The Infrastructure Checklist for the June 2026 Audit Deadline

NIS2 audits for essential entities begin on 30 June 2026 — nine weeks from now. National competent authorities (NCAs) across the EU have issued supervisory frameworks, and the first proactive supervision cycles under Art.32 are starting in Germany (BSI), the Netherlands (NCSC), and France (ANSSI).

Every major cloud provider has published a NIS2 compliance guide. AWS has one. Azure has one. GCP has one. They all cover the same things: encryption at rest, MFA, vulnerability scanning, incident response playbooks.

None of them address Art.21(2)(d) supply chain security honestly. None of them mention the CLOUD Act — the US federal law that lets American prosecutors compel disclosure of data stored anywhere in the world by a US-incorporated company.

This post covers what the AWS guide forgot to write: the infrastructure layer of NIS2 compliance, and why the jurisdiction of your PaaS provider is a compliance decision, not just a commercial one.

What NIS2 Art.21 Actually Requires at the Infrastructure Layer

NIS2 Art.21 requires essential and important entities to implement "appropriate and proportionate technical and organisational measures" to manage cybersecurity risks. Art.21(2) itemises the minimum measures. Four of them directly implicate infrastructure choice:

Art.21(2)(a) — Policies on risk analysis and information system security Your security policy must describe your infrastructure's risk profile. A policy that says "we use AWS in Frankfurt" is not complete if it does not address CLOUD Act compelled disclosure as a risk factor for EU operations data.

Art.21(2)(d) — Supply chain security This is the critical one. NIS2 explicitly requires managing "security aspects concerning the relationships between each entity and its direct suppliers or service providers." Your cloud provider is a direct supplier. The security aspects of that relationship include legal jurisdiction — specifically, whether your supplier can be compelled to hand over your data by a foreign government under a law you cannot comply with.

Art.21(2)(f) — Policies and procedures for the use of cryptography and encryption Your cryptography policy must address key management jurisdiction. If your cloud provider holds the master key and is a US company, a CLOUD Act order can compel key disclosure alongside data disclosure.

Art.21(2)(h) — Use of multi-factor authentication and access control Infrastructure access controls — including privileged access to the PaaS management layer — must meet NIS2 standards. The NIS2-auditor question: "Who has privileged access to your cloud management plane, and under what legal jurisdiction do they operate?"

The CLOUD Act Supply Chain Problem

The Clarifying Lawful Overseas Use of Data Act (18 U.S.C. § 2703), in force since 2018, allows US law enforcement to compel US-incorporated cloud providers to disclose stored data regardless of where that data is physically located. This applies to AWS (Amazon.com, Inc., Seattle, WA), Microsoft Azure (Microsoft Corporation, Redmond, WA), and Google Cloud (Google LLC, Mountain View, CA).

The Frankfurt region does not help. AWS Frankfurt, Azure West Europe, and GCP europe-west3 are all operated by US-incorporated parent entities. A US court order travels to corporate headquarters, not to a data centre.

For NIS2 Art.21(2)(d) supply chain security analysis, this creates a specific problem:

Supply Chain Risk FactorAWS/Azure/GCPEU-Native PaaS
Foreign government compelled disclosureYes — CLOUD Act appliesNo — no US parent
Data sovereignty documentationLimited (contractual only)Full EU incorporation
Art.21(2)(d) risk assessment complexityHigh (CLOUD Act → GDPR Art.44 conflict)Low (single EU jurisdiction)
Audit documentation for NCAMulti-document (DPA, SCCs, TIAs)Single-jurisdiction (EU law)
Art.21(2)(a) policy gapMust address CLOUD Act riskNo gap to address

This is not a hypothetical risk. The CLOUD Act has been used against European companies' data in US litigation. German courts have confirmed it represents a "real risk" of GDPR violation (Finanzgericht Köln, 2022). The conflict between Art.48 GDPR (prohibition on non-EU disclosure orders) and CLOUD Act compelled disclosure is unresolved at the EU level.

Your NIS2 auditor may ask: "Have you assessed the CLOUD Act risk in your supply chain security analysis under Art.21(2)(d)?" If you are running on AWS, the honest answer requires a documented risk acceptance, a Transfer Impact Assessment, and Standard Contractual Clauses — none of which eliminate the underlying legal conflict.

NIS2 Art.21 Compliance Map: Infrastructure Layer

The following table maps NIS2 Art.21(2) minimum measures to specific infrastructure decisions:

NIS2 Art.21(2) MeasureInfrastructure RequirementEU-Native PaaS Advantage
(a) Risk analysis policiesMust include cloud jurisdiction risk assessmentNo CLOUD Act risk to document
(b) Incident handlingInfrastructure must support sub-24h NCA notification (Art.23)EU jurisdiction = no cross-border disclosure complexity
(c) Business continuityBackup infrastructure must be in auditable jurisdictionEU-incorporated backup providers available
(d) Supply chain securityDirect supplier legal jurisdiction must be assessedEU incorporation = no foreign compelled disclosure
(e) Secure network acquisitionManaged PaaS reduces network attack surface vs IaaSFully managed = vendor handles patching
(f) Cryptography policiesKey management jurisdiction must be assessedKeys held by EU-incorporated entity
(g) HR securityAdmin access to infrastructure must be documentedEU labour law applies to infrastructure admins
(h) MFA and access controlInfrastructure management plane must meet Art.21 standardsEU-incorporated management plane
(i) Asset managementCloud assets must be inventoried with jurisdictionSingle-jurisdiction simplifies inventory

The June 30 Deadline: What Auditors Will Check

Under NIS2 Art.32, NCAs conducting proactive supervision of essential entities will examine:

  1. Registration completeness (Art.24) — Is your entity registered with the correct NCA?
  2. Risk management policy (Art.21(1)) — Does it cover your supply chain, including cloud providers?
  3. Incident handling procedures (Art.21(2)(b), Art.23) — Can you notify within 24h / 72h as required?
  4. Supply chain security measures (Art.21(2)(d)) — Have you assessed and documented cloud provider jurisdiction risks?
  5. Cryptography policies (Art.21(2)(f)) — Are encryption key management responsibilities documented?
  6. Access control documentation (Art.21(2)(h)) — Is privileged access to infrastructure documented and controlled?

Art.32 proactive supervision for important entities follows a similar structure, with lighter-touch sampling rather than full audits.

The NCA question that trips up EU companies running on US cloud: "Please provide your supply chain security assessment for your primary cloud infrastructure provider, including any foreign government compelled disclosure risk."

On EU-native PaaS, this question has a short, clean answer. On AWS Frankfurt, the answer requires a Transfer Impact Assessment, SCC documentation, and a risk acceptance statement — and still cannot eliminate the underlying CLOUD Act exposure.

Python: NIS2 Infrastructure Compliance Checker

#!/usr/bin/env python3
"""
NIS2InfrastructureComplianceChecker
Assesses infrastructure choices against NIS2 Art.21(2) requirements.
Focus: supply chain security (Art.21(2)(d)) and jurisdiction analysis.
"""

from dataclasses import dataclass
from enum import Enum
from typing import Optional


class Jurisdiction(Enum):
    EU_NATIVE = "EU-incorporated, no US parent"
    US_PARENT_EU_REGION = "US-incorporated, EU region"
    NON_EU = "Non-EU incorporated"


class CloudActExposure(Enum):
    NONE = "No US parent — CLOUD Act does not apply"
    INDIRECT = "US parent — CLOUD Act applies via corporate compulsion"
    DIRECT = "US entity — CLOUD Act fully applies"


@dataclass
class InfrastructureProfile:
    provider_name: str
    jurisdiction: Jurisdiction
    cloud_act_exposure: CloudActExposure
    scc_required: bool
    tia_required: bool
    art_21_2_d_complexity: str  # "low" / "medium" / "high"
    nca_audit_documentation: list[str]


PROVIDERS = {
    "aws": InfrastructureProfile(
        provider_name="Amazon Web Services (Frankfurt)",
        jurisdiction=Jurisdiction.US_PARENT_EU_REGION,
        cloud_act_exposure=CloudActExposure.INDIRECT,
        scc_required=True,
        tia_required=True,
        art_21_2_d_complexity="high",
        nca_audit_documentation=[
            "AWS DPA + SCCs",
            "Transfer Impact Assessment (TIA) per EDPB Recommendations 01/2020",
            "CLOUD Act risk acceptance statement",
            "Art.44 GDPR transfer mechanism documentation",
            "Art.21(2)(d) supply chain risk assessment acknowledging CLOUD Act",
        ],
    ),
    "azure": InfrastructureProfile(
        provider_name="Microsoft Azure (West Europe)",
        jurisdiction=Jurisdiction.US_PARENT_EU_REGION,
        cloud_act_exposure=CloudActExposure.INDIRECT,
        scc_required=True,
        tia_required=True,
        art_21_2_d_complexity="high",
        nca_audit_documentation=[
            "Microsoft DPA + SCCs",
            "Transfer Impact Assessment",
            "CLOUD Act risk acceptance statement",
            "Art.44 GDPR transfer mechanism documentation",
            "Art.21(2)(d) supply chain risk assessment acknowledging CLOUD Act",
        ],
    ),
    "gcp": InfrastructureProfile(
        provider_name="Google Cloud Platform (europe-west3)",
        jurisdiction=Jurisdiction.US_PARENT_EU_REGION,
        cloud_act_exposure=CloudActExposure.INDIRECT,
        scc_required=True,
        tia_required=True,
        art_21_2_d_complexity="high",
        nca_audit_documentation=[
            "Google Cloud DPA + SCCs",
            "Transfer Impact Assessment",
            "CLOUD Act risk acceptance statement",
            "Art.44 GDPR transfer mechanism documentation",
            "Art.21(2)(d) supply chain risk assessment acknowledging CLOUD Act",
        ],
    ),
    "sota_io": InfrastructureProfile(
        provider_name="sota.io (EU-incorporated PaaS)",
        jurisdiction=Jurisdiction.EU_NATIVE,
        cloud_act_exposure=CloudActExposure.NONE,
        scc_required=False,
        tia_required=False,
        art_21_2_d_complexity="low",
        nca_audit_documentation=[
            "EU DPA (no SCCs required — no third-country transfer)",
            "Art.21(2)(d) supply chain assessment: single EU jurisdiction, no foreign compelled disclosure risk",
        ],
    ),
}


class NIS2InfrastructureComplianceChecker:
    def __init__(self, provider_key: str, entity_type: str = "essential"):
        self.profile = PROVIDERS.get(provider_key)
        if not self.profile:
            raise ValueError(f"Unknown provider: {provider_key}. Available: {list(PROVIDERS.keys())}")
        self.entity_type = entity_type
        self.findings: list[dict] = []

    def assess_art_21_2_d(self) -> dict:
        """Assess Art.21(2)(d) supply chain security compliance."""
        if self.profile.cloud_act_exposure == CloudActExposure.NONE:
            return {
                "article": "Art.21(2)(d)",
                "status": "CLEAN",
                "finding": "No CLOUD Act exposure. EU-native provider = no foreign compelled disclosure risk.",
                "action_required": None,
            }
        return {
            "article": "Art.21(2)(d)",
            "status": "RISK_ACCEPTED_REQUIRED",
            "finding": f"CLOUD Act exposure via {self.profile.provider_name}. "
                       "US prosecutors can compel data disclosure regardless of EU data centre location.",
            "action_required": [
                "Complete Transfer Impact Assessment per EDPB Recommendations 01/2020",
                "Document CLOUD Act risk in Art.21(2)(d) supply chain security assessment",
                "Execute Standard Contractual Clauses (SCCs) with additional safeguards",
                "Obtain legal opinion on CLOUD Act vs GDPR Art.48 conflict for your data types",
                "Prepare NCA-ready risk acceptance statement with Board sign-off",
            ],
        }

    def assess_cryptography(self) -> dict:
        """Assess Art.21(2)(f) cryptography and key management."""
        if self.profile.cloud_act_exposure == CloudActExposure.NONE:
            return {
                "article": "Art.21(2)(f)",
                "status": "CLEAN",
                "finding": "Key management under EU jurisdiction. No foreign compelled key disclosure risk.",
                "action_required": None,
            }
        return {
            "article": "Art.21(2)(f)",
            "status": "DOCUMENT_REQUIRED",
            "finding": "Encryption keys held by US-incorporated entity. "
                       "CLOUD Act compelled disclosure extends to encryption keys.",
            "action_required": [
                "Implement BYOK (Bring Your Own Key) where available",
                "Document key management jurisdiction in cryptography policy",
                "Assess HSM options for key isolation from provider management plane",
            ],
        }

    def assess_incident_handling(self) -> dict:
        """Assess Art.21(2)(b) + Art.23 incident handling infrastructure."""
        if self.profile.jurisdiction == Jurisdiction.EU_NATIVE:
            return {
                "article": "Art.21(2)(b) + Art.23",
                "status": "CLEAN",
                "finding": "Incident handling infrastructure under EU jurisdiction. "
                           "Art.23 24h early warning and 72h notification timelines achievable without cross-border complexity.",
                "action_required": None,
            }
        return {
            "article": "Art.21(2)(b) + Art.23",
            "status": "DOCUMENT_REQUIRED",
            "finding": "Incident data may cross to US parent during investigation. "
                       "Document data flow in incident response playbook.",
            "action_required": [
                "Map incident data flows to identify cross-border transfers",
                "Document CLOUD Act risk in incident response playbook",
                "Ensure Art.23 72h NCA notification does not require US parent approval",
            ],
        }

    def generate_report(self) -> str:
        assessments = [
            self.assess_art_21_2_d(),
            self.assess_cryptography(),
            self.assess_incident_handling(),
        ]

        lines = [
            f"NIS2 Infrastructure Compliance Report",
            f"Provider: {self.profile.provider_name}",
            f"Entity type: {self.entity_type}",
            f"Jurisdiction: {self.profile.jurisdiction.value}",
            f"CLOUD Act exposure: {self.profile.cloud_act_exposure.value}",
            f"Art.21(2)(d) complexity: {self.profile.art_21_2_d_complexity}",
            f"",
            f"{'='*60}",
        ]

        for a in assessments:
            lines.append(f"\n{a['article']} — {a['status']}")
            lines.append(f"  Finding: {a['finding']}")
            if a["action_required"]:
                lines.append("  Actions required:")
                for action in a["action_required"]:
                    lines.append(f"    • {action}")

        lines.append(f"\n{'='*60}")
        lines.append(f"NCA Audit Documentation Required:")
        for doc in self.profile.nca_audit_documentation:
            lines.append(f"  • {doc}")

        clean_count = sum(1 for a in assessments if a["status"] == "CLEAN")
        lines.append(f"\nSummary: {clean_count}/{len(assessments)} assessments clean")
        if self.profile.cloud_act_exposure == CloudActExposure.NONE:
            lines.append("Infrastructure is NIS2 Art.21(2)(d) clean. No CLOUD Act supply chain risk.")
        else:
            lines.append("CLOUD Act risk requires documented risk acceptance before NCA audit.")

        return "\n".join(lines)


# Example usage
if __name__ == "__main__":
    print("=== AWS Frankfurt ===")
    checker_aws = NIS2InfrastructureComplianceChecker("aws", "essential")
    print(checker_aws.generate_report())

    print("\n\n=== sota.io (EU-native) ===")
    checker_sota = NIS2InfrastructureComplianceChecker("sota_io", "essential")
    print(checker_sota.generate_report())

The 20-Item NIS2 Infrastructure Compliance Checklist (June 2026)

Use this checklist to prepare for NCA proactive supervision under Art.32. Items marked [CLOUD ACT] require additional documentation if you use a US-incorporated cloud provider.

Registration and Classification (Art.24)

Risk Management Policy (Art.21(1))

Supply Chain Security (Art.21(2)(d))

Cryptography and Key Management (Art.21(2)(f))

Incident Handling and Notification (Art.21(2)(b), Art.23)

Access Control and MFA (Art.21(2)(h))

Items with [CLOUD ACT] require no action on EU-native infrastructure — the supply chain risk does not exist when the provider has no US parent company.

What This Means for the June 30 Deadline

If you are running on AWS, Azure, or GCP: You have nine weeks to complete documentation that cannot eliminate the underlying legal tension — only describe and accept it. A completed TIA, signed SCCs, a Board-approved risk acceptance statement, and a supply chain security policy that names CLOUD Act as a residual risk is the best available outcome. Plan at least three to four weeks for this documentation work if starting now.

If you are migrating to EU-native infrastructure before June 30: Nine weeks is enough time for most containerised applications. A typical migration path:

  1. Week 1–2: Infrastructure audit — identify what runs where
  2. Week 3–4: Container migration — Docker-based applications deploy with Dockerfile and environment variables
  3. Week 5–6: Database migration — pg_dump / pg_restore for PostgreSQL, equivalent for MySQL
  4. Week 7–8: DNS cutover and validation
  5. Week 9: Final NCA documentation review

If you are already on EU-native managed PaaS: Your Art.21(2)(d) checklist items resolve without documentation complexity. The June 30 deadline becomes a documentation exercise, not a legal risk management problem.

The Compliance Layer Your Cloud Guide Forgot

AWS publishes "NIS2 on AWS." It covers encryption, logging, IAM, and incident response. It is a good guide for AWS-specific controls.

It does not mention that AWS is incorporated in Seattle and that 18 U.S.C. § 2703 gives US prosecutors a legal mechanism to compel data disclosure regardless of which region you choose. It does not mention that NIS2 Art.21(2)(d) supply chain security specifically requires you to assess this risk. It does not mention that your NCA may ask you to document it.

The infrastructure checklist your cloud provider forgot to write starts with this question: What jurisdiction governs your cloud provider's legal obligations, and can a foreign government compel disclosure of your operational data?

On EU-native managed PaaS, the answer is clean. On US-parent cloud infrastructure, the answer requires work — and the work does not change the underlying risk, only your documentation of it.


NIS2 Directive 2022/2555. Art.21 security measures, Art.23 incident reporting, Art.24 registration, Art.32 proactive supervision. NCA audit preparation: BSI (Germany), ANSSI (France), NCSC-NL (Netherlands). CLOUD Act: 18 U.S.C. § 2703. EDPB Recommendations 01/2020 on TIAs. June 30, 2026 supervision deadline for essential entities.

Deploy on EU-native managed PaaS without CLOUD Act supply chain risk: sota.io