NIS2 Art.21(1): Proportionality Framework — What "Appropriate" Cybersecurity Measures Actually Means for SaaS Developers (2026)
NIS2 Directive Art.21(2) mandates ten specific cybersecurity risk-management measures — from risk analysis to multi-factor authentication. But before those measures apply, Art.21(1) establishes the governing principle that determines how and at what level each measure must be implemented:
"Member States shall ensure that essential and important entities take appropriate and proportionate technical, operational and organisational measures to manage the risks posed to the security of network and information systems which those entities use for their operations or for the provision of their services."
"Appropriate and proportionate" is not a vague aspiration. The Directive specifies exactly what proportionality means — and NCA auditors starting June 2026 will test whether your security posture can be justified against it.
This guide decodes the Art.21(1) proportionality framework, shows how SaaS development teams apply it in practice, and provides a Python assessment tool for audit-ready proportionality documentation.
1. The Four-Factor Proportionality Test
Art.21(1) defines proportionality through four explicit factors. Every security measure you implement — and every gap you document as accepted risk — must be defensible against all four.
Factor 1: State of the Art
Your controls must reflect current best practice, not 2018 standards. "State of the art" in 2026 means:
- TLS 1.3 (not 1.2 as baseline — see Art.21(2)(h))
- MFA everywhere (not just admin accounts — see Art.21(2)(j))
- SBOM generation for all dependencies (CRA alignment)
- Automated vulnerability scanning in CI/CD pipeline
Audit implication: If you are still running TLS 1.2 or password-only admin access, "state of the art" will be used against you, regardless of your size or risk profile.
Factor 2: Applicable Standards and Specifications
ENISA and ETSI publish reference standards. The key ones for SaaS under NIS2:
| Standard | Scope | NIS2 Relevance |
|---|---|---|
| ETSI EN 319 401 | Electronic signature infrastructure | Art.21(2)(h) cryptography |
| ISO/IEC 27001:2022 | ISMS framework | Art.21(2)(a) risk analysis |
| NIST SP 800-53 Rev.5 | Security controls catalog | General controls mapping |
| ENISA Good Practices for NIS2 | EU-specific guidance | Direct NIS2 alignment |
| SOC 2 Type II | SaaS trust principles | Acceptable for audit evidence |
You do not need to certify against all of these. But you must demonstrate awareness and intentional selection — "we reviewed ISO 27001 and implemented equivalent controls because full certification is disproportionate to our entity size" is a valid documented position.
Factor 3: Cost of Implementation
Proportionality explicitly allows you to not implement measures where the cost exceeds the risk benefit — but this must be documented.
The formula NCAs use informally: justified cost ceiling = (likelihood × impact × asset value) × some multiplier.
If implementing HSM-backed key management costs €40,000/year and your entire annual revenue is €80,000, you can document this as disproportionate and implement software-based key management with compensating controls. If your revenue is €4M, the same argument fails.
Factor 4: Likelihood and Severity of Incidents
This is where your Art.21(2)(a) Risk Register feeds into Art.21(1). Each measure's implementation level must correspond to assessed likelihood and severity:
- Low likelihood, low severity → baseline control at minimum implementation
- High likelihood, low severity → automated detection + response, lower investment in prevention
- Low likelihood, high severity → disproportionate investment in prevention justified
- High likelihood, high severity → full control implementation + regular testing mandated
2. Entity Size Tiers and What They Mean in Practice
NIS2 distinguishes Essential Entities (EE) from Important Entities (IE), and within those, applies different expectations based on entity size. While the Directive does not create explicit "size brackets" for Art.21(1), ENISA guidance and early NCA enforcement signals indicate:
| Entity Type | Revenue/Size | Expected Proportionality Level |
|---|---|---|
| Essential Entity, large | >€250M / >250 employees | Full ISO 27001 or equivalent, formal ISMS |
| Essential Entity, medium | €50-250M / 50-250 employees | Documented ISMS, most controls certified |
| Important Entity, medium | €10-50M / 10-50 employees | Risk-based controls, documented gaps acceptable |
| Important Entity, small | <€10M / <10 employees | Lightweight ISMS, proportionality defense critical |
SaaS teams in the €1-10M ARR range (typical sota.io customers) are usually Important Entities if they serve other businesses in critical sectors. The proportionality defense is strongest here — you can implement lean security with documented reasoning.
3. Proportionality in Practice: The Three-Step Documentation Method
When an NCA auditor reviews your NIS2 compliance posture, they are not checking boxes — they are evaluating whether you have thought through your security posture systematically. Art.21(1) is satisfied by demonstrating this thought process.
Step 1: Asset-Risk Matrix
Map assets to their risk exposure. For a typical SaaS application:
Asset: Customer authentication tokens
Likelihood of breach: HIGH (credential stuffing is commodity)
Severity: HIGH (account takeover → service disruption, data breach)
→ Proportionate measure: MFA mandatory + rate limiting + breach detection
→ Investment level: HIGH — disproportionate cost defense NOT applicable
Asset: Internal deployment logs
Likelihood of breach: LOW (not externally exposed)
Severity: MEDIUM (operational data, not personal data)
→ Proportionate measure: access control + 90-day retention
→ Investment level: LOW — SOC2 log access controls sufficient
Step 2: Control Selection Justification
For each Art.21(2) sub-measure, document:
- Which implementation level you chose (minimal / standard / enhanced)
- Why that level is proportionate given your four-factor assessment
- What residual risk you accept and why
This is not bureaucratic overhead — it is your audit defense. A one-page justification per measure is sufficient for Important Entities with fewer than 50 employees.
Step 3: Gap Register
Document measures you have not implemented at the "state of the art" level, with your proportionality reasoning. An honest gap register is stronger audit evidence than a control list that cannot be demonstrated.
Gap: HSM-backed key management (Art.21(2)(h))
Current state: Software-based key management in cloud KMS
State of art: Hardware Security Module
Proportionality reasoning: Cost €35,000/year. Annual revenue €600,000.
Risk exposure: Encryption keys for data at rest. No regulatory requirement
for HSM at this entity size per ENISA guidance (2024).
Compensating controls: Cloud KMS audit logs, key rotation every 90 days,
access restricted to two operators with MFA.
Accepted residual risk: MEDIUM. Reviewed and accepted by CISO [date].
4. Python NIS2ProportionalityAssessor
This tool generates audit-ready proportionality documentation for each Art.21(2) measure.
#!/usr/bin/env python3
"""
NIS2 Art.21(1) Proportionality Assessor
Generates documented proportionality justifications for NCA audit.
"""
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
import json
from datetime import date
class RiskLevel(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class ImplementationLevel(Enum):
MINIMAL = "minimal"
STANDARD = "standard"
ENHANCED = "enhanced"
NOT_IMPLEMENTED = "not_implemented"
@dataclass
class EntityProfile:
name: str
annual_revenue_eur: float
employee_count: int
entity_type: str # "essential" or "important"
sector: str
critical_services: list[str] = field(default_factory=list)
@dataclass
class ControlAssessment:
measure_id: str # e.g. "Art.21(2)(a)"
measure_name: str
likelihood: RiskLevel
severity: RiskLevel
implementation_level: ImplementationLevel
current_state: str
state_of_art: str
implementation_cost_eur: Optional[float]
justification: str
compensating_controls: list[str] = field(default_factory=list)
review_date: Optional[date] = None
accepted_by: Optional[str] = None
def proportionality_score(self, entity: EntityProfile) -> float:
"""Score 0-1: how defensible this assessment is under Art.21(1)."""
risk_score = {
RiskLevel.LOW: 0.2,
RiskLevel.MEDIUM: 0.5,
RiskLevel.HIGH: 0.8,
RiskLevel.CRITICAL: 1.0
}
impl_score = {
ImplementationLevel.NOT_IMPLEMENTED: 0.0,
ImplementationLevel.MINIMAL: 0.3,
ImplementationLevel.STANDARD: 0.7,
ImplementationLevel.ENHANCED: 1.0
}
risk = max(risk_score[self.likelihood], risk_score[self.severity])
impl = impl_score[self.implementation_level]
# Cost factor: if cost > 5% of revenue, reduced implementation can be justified
cost_factor = 1.0
if self.implementation_cost_eur and entity.annual_revenue_eur > 0:
cost_ratio = self.implementation_cost_eur / entity.annual_revenue_eur
if cost_ratio > 0.05:
cost_factor = 0.7 # higher cost = more proportionality defense room
# Gap penalty: if high risk + not implemented = weak position
if risk >= 0.8 and impl <= 0.3:
return 0.2 # very weak — auditor will challenge
return min(1.0, (impl + (1 - risk) * cost_factor) / 2)
class NIS2ProportionalityAssessor:
def __init__(self, entity: EntityProfile):
self.entity = entity
self.assessments: list[ControlAssessment] = []
def add_assessment(self, assessment: ControlAssessment):
self.assessments.append(assessment)
def generate_report(self) -> dict:
report = {
"entity": self.entity.name,
"assessment_date": date.today().isoformat(),
"entity_type": self.entity.entity_type,
"controls": [],
"overall_posture": "",
"audit_readiness": 0.0
}
scores = []
for a in self.assessments:
score = a.proportionality_score(self.entity)
scores.append(score)
report["controls"].append({
"measure": a.measure_id,
"name": a.measure_name,
"implementation": a.implementation_level.value,
"proportionality_score": round(score, 2),
"justification": a.justification,
"gap_documented": a.implementation_level in [
ImplementationLevel.MINIMAL,
ImplementationLevel.NOT_IMPLEMENTED
]
})
avg = sum(scores) / len(scores) if scores else 0
report["audit_readiness"] = round(avg, 2)
report["overall_posture"] = (
"STRONG" if avg >= 0.75 else
"ACCEPTABLE" if avg >= 0.55 else
"WEAK — remediation required before audit"
)
return report
def export_gap_register(self) -> list[dict]:
gaps = []
for a in self.assessments:
if a.implementation_level in [
ImplementationLevel.MINIMAL,
ImplementationLevel.NOT_IMPLEMENTED
]:
gaps.append({
"measure": a.measure_id,
"gap": f"Below state-of-art: {a.current_state} vs {a.state_of_art}",
"proportionality_reasoning": a.justification,
"compensating_controls": a.compensating_controls,
"accepted_by": a.accepted_by,
"review_date": a.review_date.isoformat() if a.review_date else None
})
return gaps
# --- Example usage ---
if __name__ == "__main__":
entity = EntityProfile(
name="ExampleSaaS GmbH",
annual_revenue_eur=800_000,
employee_count=12,
entity_type="important",
sector="digital_infrastructure",
critical_services=["B2B API platform", "Data processing pipeline"]
)
assessor = NIS2ProportionalityAssessor(entity)
assessor.add_assessment(ControlAssessment(
measure_id="Art.21(2)(h)",
measure_name="Cryptography and Encryption Policy",
likelihood=RiskLevel.MEDIUM,
severity=RiskLevel.HIGH,
implementation_level=ImplementationLevel.STANDARD,
current_state="Cloud KMS (AWS/GCP), TLS 1.3, AES-256-GCM at rest",
state_of_art="HSM-backed key management + post-quantum algorithms",
implementation_cost_eur=35_000,
justification=(
"HSM cost of €35,000/year represents 4.4% of annual revenue. "
"ENISA guidance for important entities with <50 employees allows "
"cloud KMS as proportionate alternative with compensating controls."
),
compensating_controls=[
"Cloud KMS audit logging enabled",
"Key rotation every 90 days automated",
"Access restricted to 2 operators with MFA"
],
review_date=date(2026, 10, 1),
accepted_by="CISO"
))
assessor.add_assessment(ControlAssessment(
measure_id="Art.21(2)(j)",
measure_name="Multi-Factor Authentication",
likelihood=RiskLevel.HIGH,
severity=RiskLevel.HIGH,
implementation_level=ImplementationLevel.ENHANCED,
current_state="TOTP MFA on all admin + customer accounts, WebAuthn supported",
state_of_art="WebAuthn/FIDO2 phishing-resistant MFA across all access points",
implementation_cost_eur=2_000,
justification=(
"Full WebAuthn migration in progress. TOTP is state-of-practice "
"for important entities. Given HIGH likelihood of credential attacks, "
"implementation at ENHANCED level is proportionate and required."
),
review_date=date(2026, 7, 1),
accepted_by="CTO"
))
report = assessor.generate_report()
print(json.dumps(report, indent=2))
gaps = assessor.export_gap_register()
if gaps:
print("\n=== Gap Register ===")
for gap in gaps:
print(json.dumps(gap, indent=2))
5. The 20-Item Proportionality Audit Checklist
Use this before your first NCA audit or annual review:
Documentation
- Art.21(1) proportionality statement written (entity size, type, sector)
- Four-factor analysis completed for each Art.21(2) sub-measure
- Control selection rationale documented per measure
- Gap register maintained with proportionality justifications
- Gap register reviewed and signed off by responsible person (CISO/CTO/CEO)
Risk Foundation
- Risk Register exists and feeds proportionality decisions (Art.21(2)(a))
- Asset inventory current (within 90 days)
- Risk appetite statement matches entity profile
- Threat model reviewed in last 12 months
State of the Art
- ENISA good practices reviewed (current year)
- TLS 1.3 deployed on all external endpoints
- MFA enforced on all privileged access
- Vulnerability scanning automated in CI/CD
Entity Size Alignment
- Entity classification confirmed (essential/important)
- Sector confirmed and NCA identified
- Revenue/headcount documented (proportionality baseline)
- Disproportionate cost calculations on record for each gap
Ongoing
- Annual proportionality review scheduled
- Gap register review date set
- Responsible owner named for each open gap
- Board/management awareness of accepted residual risks documented
6. How Art.21(1) Links to the Rest of NIS2 Compliance
Art.21(1) is the legal architecture that makes everything else defensible. Every time a NIS2 requirement seems impossible for your team size or budget, Art.21(1) is your tool:
- Art.21(2)(a) Risk Analysis → feeds your proportionality scoring
- Art.21(2)(c) Business Continuity → RTO/RPO targets must be proportionate to criticality
- Art.21(2)(d) Supply Chain Security → vendor assessment depth proportionate to your own risk exposure
- Art.21(2)(h) Cryptography → algorithm choice and key management proportionate to data sensitivity
- Art.32/33 Audits → NCA audit intensity is itself proportionate — important entities face lighter scrutiny than essential
The teams that pass NCA audits in 2026 are not the ones with the most security tools — they are the ones with documented, coherent, proportionate security postures where every gap can be explained and every control can be justified.
Deploy Your NIS2-Compliant SaaS on EU Infrastructure
Infrastructure compliance starts at the hosting layer. sota.io provides EU-only deployment with no U.S. parent company, no CLOUD Act exposure, and encrypted storage by default — giving you a defensible infrastructure baseline for Art.21(1) documentation without the overhead of managing it yourself.
Related NIS2 Developer Guides: