2026-04-22·14 min read·

EU AI Act Art.15: Accuracy, Robustness and Cybersecurity — Adversarial Attack Defence, Python AccuracyRobustnessManager, and Art.15 × Art.9 × Art.12 × Art.14 Integration (2026)

Article 15 of the EU AI Act is the technical reliability layer of the high-risk AI compliance chain. You can have rigorous human oversight under Art.14, complete transparency documentation under Art.13, and a functioning logging system under Art.12 — but if the AI system produces systematically inaccurate outputs, degrades under real-world variation, or is vulnerable to adversarial manipulation, the entire compliance architecture is undermined.

Art.15 creates three interlocking technical obligations: accuracy (the system must perform as declared), robustness (the system must maintain performance under errors, faults, and distribution shift), and cybersecurity (the system must resist adversarial attacks on its integrity). These are not separate requirements — they form a single engineering constraint that must be designed in from the start, not retrofitted.

The August 2, 2026 deadline applies: high-risk AI systems placed on the EU market on or after that date must meet Art.15 requirements at the point of first market placement. The obligation sits with providers, but deployers inherit specific monitoring duties when operating systems under conditions that differ from the provider's test environment.

This guide covers what each Art.15 pillar requires technically, how Art.15(4) adversarial attack categories map to a practical threat model, how to declare and track accuracy metrics for Art.11 documentation, and how Art.15 connects to your risk management system under Art.9.


What Art.15 Actually Requires: The Three-Pillar Architecture

Art.15 operates across three distinct technical dimensions, each with different engineering implications:

Art.15(1) — The baseline obligation: High-risk AI systems shall be designed and developed in such a way that they achieve an appropriate level of accuracy, robustness and cybersecurity, and perform consistently in those respects throughout their lifecycle.

Four critical implications of "appropriate level":

  1. Appropriate is context-relative, not absolute. A recruitment screening system and a medical diagnostic system will have very different appropriate accuracy levels, determined by their Annex III category and the Art.9 risk assessment.
  2. Throughout their lifecycle extends the obligation to post-deployment monitoring — Art.15 is not satisfied by a pre-deployment test set alone.
  3. Consistently prohibits accuracy that degrades silently. Systems that perform well in controlled evaluation but degrade in production are non-compliant even if initial accuracy metrics were correct.
  4. All three pillars are conjunctive — a system can be accurate but not robust, or robust but not cybersecure. All three must be maintained simultaneously.

Art.15(2) — Technical robustness scope: The technical robustness requirements include resilience to attempts by unauthorised third parties to alter their use, outputs or performance exploiting system vulnerabilities, and technical fallback plans and solutions enabling the AI system to maintain a minimum level of operation when there are errors or failures.

Art.15(2) has two distinct sub-requirements:

Art.15(3) — Accuracy metric declaration: The levels of accuracy and the relevant accuracy metrics shall be included in the instructions for use accompanying the high-risk AI system.

This creates a legally binding connection between Art.15 and Art.13: accuracy metrics must appear in the Art.13 IFU. The IFU is a lifecycle document — when metrics change due to model updates, the IFU must be updated accordingly (Art.13 × Art.11(4) substantial modification chain).

Art.15(4) — Adversarial attack catalogue: AI-specific adversarial attacks target the integrity of the model itself. Art.15 implicitly requires providers to account for the full adversarial attack surface relevant to their system type.


Art.15(4): The Adversarial Attack Catalogue as Threat Model

Art.15(4) identifies four primary attack categories that high-risk AI systems must be designed to resist. Treating these as a threat model — mapped to attack vectors, detection methods, and mitigations — is the foundation of a compliant cybersecurity architecture:

Attack CategoryMechanismDetection SignalPrimary Mitigation
Adversarial examplesImperceptible input perturbations that cause misclassificationPrediction confidence anomaly; input similarity vs output divergenceAdversarial training; input preprocessing; ensemble robustness
Data poisoningMalicious training data injection to corrupt model behaviour on trigger patternsPerformance delta between clean and deployment distribution; backdoor trigger detectionData provenance chain; anomaly detection on training sets; differential testing
Model evasionInput manipulation to cause systematically incorrect outputs without triggering anomaly detectionDecision boundary probing; output distribution shiftRobust training objectives; prediction uncertainty bounds; query rate limiting
Model inversionQuerying the model to reconstruct training data or extract sensitive parametersUnusual query pattern analysis; reconstruction loss monitoringOutput perturbation; query budget enforcement; membership inference defences

The attack catalogue is not exhaustive — Art.15(4) establishes a minimum threat model, not an upper bound. Providers operating in higher-risk Annex III categories (biometric identification, law enforcement, critical infrastructure) face additional attack surface from model extraction and membership inference attacks that fall outside the four named categories.

Threat Model Mapping to Art.9: The Art.15(4) attack catalogue must be integrated with the Art.9 risk management system. Each attack category is a potential harm pathway: data poisoning in a recruitment system could produce systematically discriminatory outputs; adversarial examples in a medical diagnostic system could produce false negatives; model inversion in a law enforcement system could expose training data from criminal records. The Art.9 risk register must include each applicable attack vector with probability, severity, and mitigation measures.


Accuracy Metric Declaration: The Art.15 × Art.13 IFU Obligation

Art.15(3) requires accuracy metric declaration in the IFU. This is more specific than it appears — "relevant accuracy metrics" implies that the provider must choose metrics appropriate for the system's use case, not just report the metric that is most favourable.

Metric selection principles:

For classification systems, overall accuracy (correct predictions / total predictions) is often misleading in imbalanced datasets. A system that classifies 99% of loan applications as "standard risk" is 99% accurate when 99% of applicants are standard risk — but provides no discriminative value. Relevant metrics for high-risk classification systems include:

System TypeAppropriate Metric SetWhy Not Just Accuracy
Medical diagnosisSensitivity (recall), specificity, F1, AUC-ROCFalse negatives more costly than false positives
Biometric IDFalse accept rate, false reject rate, EERBinary accuracy hides biometric-specific failure modes
Credit scoringPrecision-recall at operating threshold, demographic parityOverall accuracy masks disparate impact
Recruitment screeningPrecision at k, disparate impact ratio, false rejection rateRanking metrics more relevant than classification accuracy
Safety monitoringRecall at specified FPR, detection latencyMissing a true positive is a safety failure

Lifecycle accuracy tracking: Because Art.15 requires consistent performance throughout the system's lifecycle, accuracy metrics must be tracked continuously in production, not just at pre-deployment validation. The Art.12 logging system is the natural mechanism: accuracy measurements collected from production interactions form the Art.12 log corpus, and anomaly detection on logged metrics provides early warning of accuracy degradation.

Metric declaration in the IFU: The Art.13(3)(d) IFU element — performance specifications including accuracy — must specify:

  1. The metric names and definitions
  2. The test set characteristics (size, distribution, time period)
  3. The threshold below which the provider considers the system non-performant
  4. The monitoring cadence for production accuracy verification

Robustness: The Fault Tolerance Engineering Requirement

Art.15(2) requires that high-risk AI systems maintain a minimum level of operation when errors or failures occur. This is a fault tolerance design requirement, not a best-practice recommendation. Three fault categories must be planned for:

1. Component-level failures: What happens when a dependency of the AI system is unavailable — model inference server, feature computation pipeline, input validation layer? The fallback plan must specify what the system does in each failure mode. Acceptable fallbacks include: reject all inputs with explicit error, route to human decision-maker, use cached last-known-good output with staleness disclosure. Unacceptable fallbacks: silently produce outputs from a degraded model without disclosure, or fail to the last output without staleness check.

2. Distribution shift: Real-world input distributions drift from training distributions over time. A recruitment model trained on 2024 applicant data and deployed in 2026 may face a distribution where key features (skills, job titles, education patterns) have shifted. Robustness under distribution shift requires: ongoing monitoring for input distribution deviation from training baseline, accuracy calibration under detected shift, and escalation to human review when shift magnitude exceeds a defined threshold.

3. Adversarial robustness: Distinct from cybersecurity attacks (Art.15(4)), natural adversarial examples arise from legitimate inputs that happen to fall near decision boundaries. High-risk systems must be calibrated to flag low-confidence predictions for additional review, not silently classify them at full confidence.

Minimum operational state definition: Art.15(2)'s "minimum level of operation" requirement implies that providers must define this minimum contractually and technically before deployment. A useful definition pattern:

Minimum operational state: System may reject inputs and route to human 
fallback when: (a) component failure detected, (b) input distribution 
shift > θ from training baseline, (c) prediction confidence < τ for 
all ensemble members. In fallback state: all rejections logged under 
Art.12; deployer notified per Art.13 IFU; human decision pathway activated 
per Art.14(4)(e).

This definition creates the link between Art.15 fault tolerance, Art.12 logging, Art.13 disclosure, and Art.14 human oversight — the compliance chain is structurally connected at the fault boundary.


Cybersecurity-by-Design: The Art.15 Engineering Requirement

Art.15's cybersecurity pillar goes beyond network security and access controls. AI systems have an expanded attack surface compared to traditional software because the model itself — its weights, training data, and decision boundaries — is a target. A compliant cybersecurity architecture must address three layers:

Layer 1 — Infrastructure security (traditional): Standard secure software development practices apply: input validation, authentication and authorisation for model API endpoints, encrypted communications, dependency vulnerability management, secrets management. These are necessary but not sufficient for Art.15 compliance.

Layer 2 — Model security (AI-specific): The model weights, architecture, and hyperparameters are intellectual property and potential sources of sensitive information (especially models trained on personal data under GDPR). Model security requirements include:

Layer 3 — Training pipeline security (supply chain): Data poisoning attacks target the training pipeline, not the deployed model. Training pipeline security requires:


Python AccuracyRobustnessManager Implementation

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


class RobustnessStatus(Enum):
    NOMINAL = "nominal"
    DEGRADED = "degraded"
    FALLBACK = "fallback"
    FAILED = "failed"


class AttackVector(Enum):
    ADVERSARIAL_EXAMPLE = "adversarial_example"
    DATA_POISONING = "data_poisoning"
    MODEL_EVASION = "model_evasion"
    MODEL_INVERSION = "model_inversion"
    DISTRIBUTION_SHIFT = "distribution_shift"


@dataclass
class AccuracyMeasurement:
    timestamp: datetime
    metric_name: str
    value: float
    sample_size: int
    deployment_environment: str
    distribution_shift_score: float = 0.0


@dataclass
class ThreatEvent:
    timestamp: datetime
    attack_vector: AttackVector
    confidence: float
    input_id: str
    action_taken: str
    escalated_to_human: bool


@dataclass
class RobustnessConfig:
    accuracy_threshold: float
    distribution_shift_threshold: float
    confidence_threshold: float
    min_sample_for_accuracy_check: int = 100
    accuracy_check_window_hours: int = 24
    max_query_rate_per_minute: int = 1000


class AccuracyRobustnessManager:
    """Art.15 compliance manager: accuracy monitoring, robustness enforcement,
    and adversarial threat detection for high-risk AI systems."""

    def __init__(self, system_id: str, config: RobustnessConfig):
        self.system_id = system_id
        self.config = config
        self.status = RobustnessStatus.NOMINAL
        self.accuracy_history: list[AccuracyMeasurement] = []
        self.threat_events: list[ThreatEvent] = []
        self._query_timestamps: list[datetime] = []

    def record_accuracy(
        self,
        metric_name: str,
        value: float,
        sample_size: int,
        environment: str,
        distribution_shift_score: float = 0.0,
    ) -> dict:
        """Record production accuracy measurement. Triggers fallback if below threshold."""
        measurement = AccuracyMeasurement(
            timestamp=datetime.now(),
            metric_name=metric_name,
            value=value,
            sample_size=sample_size,
            deployment_environment=environment,
            distribution_shift_score=distribution_shift_score,
        )
        self.accuracy_history.append(measurement)

        result = {
            "system_id": self.system_id,
            "measurement": measurement,
            "status": self.status.value,
            "art15_compliant": True,
            "actions": [],
        }

        if sample_size < self.config.min_sample_for_accuracy_check:
            result["actions"].append("insufficient_sample_size_deferred")
            return result

        if value < self.config.accuracy_threshold:
            self._transition_to_degraded(result, value)

        if distribution_shift_score > self.config.distribution_shift_threshold:
            result["actions"].append("distribution_shift_detected")
            result["actions"].append("route_to_human_review")
            result["art15_compliant"] = False

        return result

    def _transition_to_degraded(self, result: dict, value: float) -> None:
        """Transition system to degraded state per Art.15(2) fallback requirement."""
        self.status = RobustnessStatus.DEGRADED
        result["status"] = RobustnessStatus.DEGRADED.value
        result["art15_compliant"] = False
        result["actions"].extend([
            f"accuracy_below_threshold_{value:.3f}_vs_{self.config.accuracy_threshold:.3f}",
            "activate_minimum_operational_state",
            "log_art12_accuracy_degradation",
            "notify_deployer_per_art13_ifu",
            "escalate_to_human_oversight_art14",
        ])

    def check_adversarial_signal(
        self,
        input_id: str,
        prediction_confidence: float,
        input_perturbation_score: float,
        query_rate_per_minute: int,
    ) -> dict:
        """Detect adversarial attack signals across Art.15(4) categories."""
        signals = []
        attack_vector = None

        if input_perturbation_score > 0.8 and prediction_confidence < 0.3:
            attack_vector = AttackVector.ADVERSARIAL_EXAMPLE
            signals.append("high_perturbation_low_confidence_adversarial_example")

        if query_rate_per_minute > self.config.max_query_rate_per_minute:
            attack_vector = attack_vector or AttackVector.MODEL_INVERSION
            signals.append(f"query_rate_{query_rate_per_minute}_exceeds_limit_{self.config.max_query_rate_per_minute}")

        if prediction_confidence < self.config.confidence_threshold and input_perturbation_score < 0.1:
            attack_vector = attack_vector or AttackVector.MODEL_EVASION
            signals.append("low_confidence_natural_evasion_or_distribution_edge")

        result = {
            "input_id": input_id,
            "adversarial_signals": signals,
            "attack_vector": attack_vector.value if attack_vector else None,
            "escalate_to_human": len(signals) > 0,
            "block_output": attack_vector in (AttackVector.ADVERSARIAL_EXAMPLE, AttackVector.MODEL_INVERSION),
        }

        if attack_vector:
            threat_event = ThreatEvent(
                timestamp=datetime.now(),
                attack_vector=attack_vector,
                confidence=prediction_confidence,
                input_id=input_id,
                action_taken="output_blocked" if result["block_output"] else "escalated",
                escalated_to_human=result["escalate_to_human"],
            )
            self.threat_events.append(threat_event)

        return result

    def get_accuracy_trend(self, window_hours: int = 24) -> dict:
        """Compute accuracy trend over rolling window for Art.12 log export."""
        cutoff = datetime.now() - timedelta(hours=window_hours)
        recent = [m for m in self.accuracy_history if m.timestamp >= cutoff]

        if len(recent) < 2:
            return {"trend": "insufficient_data", "measurements": len(recent)}

        values = [m.value for m in recent]
        return {
            "window_hours": window_hours,
            "measurements": len(recent),
            "mean": statistics.mean(values),
            "min": min(values),
            "max": max(values),
            "trend_direction": "declining" if values[-1] < values[0] else "stable_or_improving",
            "below_threshold_count": sum(1 for v in values if v < self.config.accuracy_threshold),
            "art15_status": self.status.value,
        }

    def generate_ifu_accuracy_section(self, metric_name: str, baseline_value: float) -> dict:
        """Generate Art.13 IFU accuracy section as required by Art.15(3)."""
        return {
            "art_reference": "Art.15(3) + Art.13(3)(d)",
            "metric_name": metric_name,
            "baseline_value": baseline_value,
            "threshold": self.config.accuracy_threshold,
            "monitoring_cadence_hours": self.config.accuracy_check_window_hours,
            "fallback_trigger": f"accuracy < {self.config.accuracy_threshold} OR distribution_shift > {self.config.distribution_shift_threshold}",
            "minimum_operational_state": "reject inputs and route to human decision per Art.14(4)(e)",
            "lifecycle_update_trigger": "metric value changes by >5pp due to model update (Art.11(4) substantial modification)",
        }

Art.15 × Art.9 Integration: Robustness in the Risk Management System

Art.15 requirements do not exist in isolation — they are a subset of the Art.9 risk management system. The Art.9 risk register must explicitly include Art.15 failure modes as risk entries:

Art.15 Failure ModeArt.9 Risk CategoryProbability FactorsSeverity FactorsRequired Mitigation
Accuracy below thresholdTechnical failureTraining set representativeness, distribution shift rateAnnex III category (medical vs recruitment)Monitoring, minimum operational state
Adversarial example attackExternal threatSystem API exposure, incentive to attackConsequence of misclassificationAdversarial training, input preprocessing
Data poisoning of training setSupply chain riskTraining data source diversity, access controlsNumber of decisions affected before detectionData provenance chain, differential testing
Distribution shiftEnvironmental changeMarket/regulatory/social dynamicsMagnitude of distributional changeOngoing monitoring, recalibration procedure
Model inversionPrivacy breachAPI access model, query logging gapsPersonal data reconstruction riskQuery rate limiting, output perturbation

Risk register integration pattern: Each row in the Art.9 risk register for Art.15 failure modes must include: (1) the specific mitigation measures implemented; (2) the residual risk after mitigation; (3) the logging mechanism under Art.12 that provides detection; (4) the escalation path to human oversight under Art.14. This creates the compliance chain linkage at the risk management level.


Art.15 × Art.11 × Art.12 × Art.14 Integration Matrix

RequirementArt.15 ConnectionImplementation Link
Art.11(1)(e) — Test, validation, and training dataArt.15 accuracy metrics derive from test sets documented in Art.11 Technical FileAccuracy test set specification in Technical File must match IFU-declared metrics
Art.11(4) — Substantial modificationsModel updates that change accuracy metrics are substantial modificationsArt.15(3) metric change → Art.11(4) substantial modification → Art.13 IFU update chain
Art.12(1) — Automatic loggingProduction accuracy measurements are Art.12 log eventsAccuracy degradation log entries: timestamp, metric name, value, threshold, action taken
Art.12(2)(d) — Reference dataTest set characteristics referenced for accuracy contextArt.12 log entries include distribution shift score vs reference baseline
Art.14(4)(e) — Interrupt or stopArt.15 fallback state activates Art.14(4)(e) stop mechanismMinimum operational state activation triggers Art.14 human oversight escalation
Art.14(5) — Real influenceFor Annex III systems, accuracy degradation must trigger real human reviewAccuracy threshold breach → human review queue, not auto-fallback to previous output

Technical Documentation Requirements: Art.15 in the Art.11 Technical File

The Art.11 Technical File for a high-risk AI system must include Art.15-specific documentation:

Section: Accuracy and Robustness Specifications

  1. Primary accuracy metric: name, definition, mathematical formula
  2. Secondary metrics: if applicable (sensitivity, specificity, demographic parity)
  3. Test set description: size, composition, sampling methodology, time period
  4. Baseline accuracy value: the value declared in the Art.13 IFU
  5. Minimum operational threshold: below which the system activates fallback
  6. Distribution shift monitoring methodology: how shift is measured and at what cadence
  7. Lifecycle monitoring plan: how accuracy is tracked post-deployment

Section: Cybersecurity Architecture

  1. Threat model covering Art.15(4) attack categories applicable to the system
  2. Mitigations for each applicable attack vector
  3. Query rate limiting configuration
  4. Model access controls (authentication, authorisation, audit logging)
  5. Training pipeline integrity controls (data provenance, code signing)
  6. Fallback state definition and activation conditions

Section: Fault Tolerance Design

  1. Component dependency map and failure mode analysis
  2. Minimum operational state definition (per Art.15(2))
  3. Fallback activation conditions and escalation paths
  4. Recovery procedure and restoration criteria

Art.15 Implementation Checklist (Provider and Deployer)

Provider obligations (pre-market placement):

Deployer obligations (operational phase):


Common Failure Modes in Art.15 Implementation

1. Test set leakage into monitoring benchmarks: Using the same test set for pre-deployment validation and post-deployment monitoring produces over-optimistic accuracy measurements. Deployers monitoring a model against its training benchmark may miss real-world performance degradation. Compliant monitoring requires held-out production data, not benchmark re-use.

2. Single-metric IFU declaration: Declaring only overall accuracy in the Art.13 IFU satisfies the literal obligation but not the substantive one for high-risk systems. A medical imaging system that is 95% accurate overall may be 60% accurate for the specific patient demographic most likely to use it. "Relevant" accuracy metrics under Art.15(3) means metrics that capture performance for the deployment population, not the average.

3. Adversarial threat model limited to Art.15(4) categories: Art.15(4) names four attack categories as examples, not an exhaustive list. Providers who limit their threat model to the four named categories may miss model extraction, membership inference, and prompt injection attacks relevant to their system type. The threat model must cover the full attack surface of the specific system architecture.

4. Fallback state that silently degrades: A fallback plan that routes to "use last known good output" without disclosing the fallback activation to the deployer or the downstream decision-maker violates Art.15(2)'s minimum operational state requirement and Art.13's disclosure obligations simultaneously. All fallback activations must be logged and disclosed.

5. Accuracy monitoring without distribution shift context: Accuracy measurements without distribution shift assessment are systematically misleading. A model maintaining 92% accuracy on a distribution that has shifted 40% from training may be performing very differently on the actual decision population than the metric suggests. Art.15 compliance requires accuracy + shift context, not accuracy alone.

6. Treating cybersecurity as a deployment-phase concern: Art.15's cybersecurity requirement is a design-phase obligation — "designed and developed" in Art.15(1) places the requirement at the provider level, before market placement. Providers who implement security controls only as deployment configuration rather than as architectural design decisions cannot claim Art.15 compliance for the cybersecurity pillar.


See Also