2026-04-13·13 min read·sota.io team

EU AI Act Art.91: AI Office Inspection Powers — On-Site and Remote Developer Guide (2026)

When Art.90 information requests aren't enough, Art.91 gives the AI Office the power to come to you — physically or remotely.

Article 91 is the escalation layer in the AI Office's GPAI enforcement toolkit. An Art.90 request asks you to produce documentation. An Art.91 inspection allows inspectors to access your premises, examine your systems directly, test your model's capabilities, and gather evidence you didn't choose to provide. For GPAI model providers, understanding what Art.91 authorises — and what it doesn't — determines how you structure your infrastructure, staff your compliance team, and respond when an inspection notice arrives.

What Article 91 Actually Says

Article 91 establishes two distinct inspection modalities and the procedural framework that governs each.

Article 91(1) — On-Site Inspection Authority:

The AI Office may conduct inspections at the premises of providers of general-purpose AI models, including model weights, source code, training methodologies, evaluation results, and technical infrastructure related to the model.

The enumeration is intentional and expansive: model weights (the trained parameters), source code (the training and inference pipeline), training methodologies (data selection, fine-tuning approaches), evaluation results (capability assessments, red-team outputs), and technical infrastructure. This is not a narrow document review — it is access to the technical core of the model.

Article 91(2) — Remote Evaluation Authority:

The AI Office may conduct remote evaluations of general-purpose AI models, including capability testing and safety assessments, without requiring physical access to the provider's premises.

Remote evaluation is analytically separate from on-site inspection. It allows the AI Office to assess model capabilities — including potentially dangerous capabilities like CBRN uplift, cyberattack generation, or deception — without entering your premises. This matters: remote evaluations can be ordered at any point in an investigation, and the provider has limited ability to contest the scope of what is tested.

Article 91(3) — Procedural Requirements for On-Site Inspections:

Inspections shall be conducted with reasonable notice, except in cases where prior notification would frustrate the purpose of the inspection. Inspection notices shall state the legal basis, purpose, and scope of the inspection, the rights of the inspected party, and the consequences of obstruction.

"Reasonable notice" is not defined in the Act but has been interpreted in EU competition law to mean at least 48 hours for routine inspections, less for urgent cases. The notice must include the legal basis (Art.91(1) + Art.51-56 obligations being investigated), purpose (what the AI Office is trying to establish), and scope (which premises, which systems, which time period of data).

Article 91(4) — Inspection Warrants:

Where the provider refuses access or obstructs the inspection, the AI Office may obtain a court order authorising the inspection from a competent court in the Member State where the provider's premises are located.

This is the EU administrative law equivalent of a search warrant. The AI Office applies to a national court — not an EU court — in the Member State where the premises are located. The court reviews whether: (a) the inspection is legally authorised under the AI Act, (b) there is a reasonable basis for the investigation, and (c) the inspection scope is proportionate.

Article 91(5) — Obstruction Consequences:

A provider who refuses to submit to an on-site inspection, obstructs an inspection, or refuses to submit to a remote evaluation without legitimate justification shall be subject to the penalties provided in Article 99.

Art.99(4) sets the penalty for obstruction: up to 3% of worldwide annual turnover for the preceding year, or €15 million for undertakings where turnover is not available. For large GPAI providers — major AI labs, foundation model companies — this means penalties in the hundreds of millions.

Article 91(6) — Third-Party Premises:

Where the general-purpose AI model is developed, trained, or operated on infrastructure not belonging to the provider, inspections may extend to those third-party premises where the third party consents or where a court order has been obtained.

This is the cloud infrastructure clause. If your model is trained on AWS, Azure, or GCP — as most large GPAI models are — the AI Office can extend the inspection to those infrastructure providers. This requires either cloud provider consent or a separate court order, but the authority to request it exists.

The Inspection Sequence: How Art.91 Fits the Enforcement Chain

Understanding when Art.91 gets triggered requires understanding the full enforcement sequence:

StepArticleTriggerWhat Happens
1Art.90Investigation opensInformation request: documentation, training records, evaluation results
2Art.91(1)Documentation insufficient or suspected falsificationOn-site inspection: premises access, system review, evidence collection
2AArt.91(2)Capability concern, no premises access neededRemote evaluation: model testing, capability assessment
3Art.89Adverse measure under considerationRight to be heard: written observations, oral hearing option
4Art.93Systemic risk confirmed + urgent threatInterim measures: temporary restrictions, mandatory mitigations
5Art.99Violation established or confirmedAdministrative fine: up to 3% worldwide turnover
6Art.94Negotiated resolution preferredCommitments and settlements: binding undertakings

Art.91 sits at step 2: it is the investigation intensification step that happens when Art.90 documentation review is insufficient. The key implication for providers: if your Art.90 response is incomplete, ambiguous, or appears inconsistent with other information the AI Office has obtained, an Art.91 inspection notice is the likely next step.

On-Site Inspections: What Inspectors Can Access

The Scope of Physical Access

Art.91(1) lists five categories of accessible material. In practice, an on-site inspection can include:

Model Weights and Checkpoints

Source Code

Training Methodologies

Evaluation Results

Technical Infrastructure

What Inspectors Cannot Do

Art.91 does not grant unlimited access. Inspectors:

Remote Evaluations: The Model Testing Mechanism

Art.91(2) remote evaluations are procedurally distinct from on-site inspections in several important ways:

What Remote Evaluation Involves

A remote evaluation typically involves the AI Office submitting prompts to the model's API — either the provider's production API or a dedicated evaluation endpoint — to assess capabilities. The AI Office may:

Scope Limitations on Remote Evaluation

Remote evaluation under Art.91(2) is constrained by proportionality. The AI Office cannot use remote access to:

However, the Act does not require the AI Office to share its evaluation prompts in advance — which creates a significant asymmetry. You cannot prepare for the specific test inputs. You can only ensure the model's behaviour under adversarial prompting is consistently within the bounds you've claimed in your documentation.

Refusing Remote Evaluation

Art.91(5) covers refusal to submit to remote evaluation alongside refusal of on-site inspection. Refusing remote evaluation without "legitimate justification" triggers the same Art.99(4) penalty exposure. The qualifier "without legitimate justification" suggests some grounds for refusal exist — security concerns about the evaluation endpoint, scope disputes — but these must be raised promptly and in writing to avoid being characterised as obstruction.

Infrastructure Jurisdiction and the CLOUD Act Problem

The Art.91 + CLOUD Act Collision

The CLOUD Act (Clarifying Lawful Overseas Use of Data Act) allows US law enforcement to compel US cloud providers to produce data stored anywhere in the world, without a Mutual Legal Assistance Treaty (MLAT) request. Art.91 creates an EU-law obligation to permit inspection of your infrastructure — including cloud infrastructure. If that infrastructure is AWS, Azure, or GCP, you face a structural conflict:

Infrastructure LayerCLOUD Act RiskArt.91 ExposureConflict Risk
Model weights on US cloudHIGH — training checkpoints producible under CLOUD ActHIGH — inspection scope explicitly includes weightsHIGH
Training data on US cloudHIGH — data producible under CLOUD ActHIGH — methodology/data access in scopeHIGH
Evaluation results on US cloudMEDIUM — results documentsHIGH — explicit Art.91(1) scopeHIGH
Inference logs on US cloudHIGH — API call logsMEDIUM — in scope if relevant to investigationHIGH
Source code on US cloudMEDIUM — code repositoryHIGH — explicit Art.91(1) scopeHIGH

The Sovereignty Argument for EU-Native Infrastructure

For GPAI providers designing their compliance posture in advance of a potential Art.91 inspection, storing model weights, training checkpoints, and evaluation results on EU-sovereign infrastructure (within the EU, under EU jurisdiction only, with no contractual hooks that would permit US law enforcement access without MLAT process) eliminates the CLOUD Act collision entirely. A single legal order — EU law — governs what can be produced and to whom.

This is not merely a theoretical benefit. In an Art.91 inspection, an AI Office inspector arriving at your premises to examine your model weights expects to find those weights accessible. If you say "our weights are on AWS US-EAST-1 and we're waiting for our legal team to evaluate US government access obligations," you have created an obstruction risk — not because you're refusing, but because the infrastructure creates a practical barrier to immediate access.

EU-based infrastructure eliminates this problem at the source.

Preparing for an Art.91 Inspection

The Inspection Notice Response Protocol

When you receive an Art.91(3) inspection notice, you have a defined but limited window to:

  1. Verify legal compliance of the notice — Does it contain all required elements (legal basis, purpose, scope, rights, consequences)? A defective notice can be challenged — see the procedural defect framework below.
  2. Brief your legal team and compliance officer — The inspection must be accompanied by appropriate internal representation. Your legal team should understand the scope and identify which materials fall within it.
  3. Identify confidentiality claims — Which materials in scope contain business secrets or commercially sensitive information? Art.91 operates under confidentiality protections similar to EU competition enforcement, but you must affirmatively identify protected materials during the inspection — not after.
  4. Prepare an inventory framework — Anything inspectors take copies of should be inventoried. You have a right to a copy of all materials taken or reviewed in detail.
  5. Contact infrastructure providers — If any in-scope material is stored on third-party cloud infrastructure, notify the provider immediately. Their access protocols may affect inspection timing.

Challenging Inspection Scope

You can contest an Art.91 inspection before the General Court if:

However, challenging an inspection does not automatically suspend it unless you obtain an interim injunction from the General Court simultaneously. The standard for obtaining such an injunction is high: you must demonstrate that the harm from the inspection proceeding is irreparable and that you have a prima facie case on the merits.

Python Implementation: Inspection Readiness Tooling

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


class InspectionModality(Enum):
    ON_SITE = "on_site"
    REMOTE_EVALUATION = "remote_evaluation"
    HYBRID = "hybrid"


class InspectionReadinessLevel(Enum):
    READY = "ready"
    PARTIAL = "partial"
    NOT_READY = "not_ready"


@dataclass
class Art91InspectionNotice:
    """Parses and validates an Art.91 inspection notice for procedural compliance."""

    received_date: datetime
    inspection_modality: InspectionModality
    stated_legal_basis: str
    stated_purpose: str
    stated_scope: list[str]
    inspection_date: datetime
    inspector_names: list[str]

    # Required procedural elements per Art.91(3)
    REQUIRED_ELEMENTS = [
        "legal_basis",
        "purpose",
        "scope",
        "rights_statement",
        "obstruction_consequences",
    ]

    def has_minimum_notice(self) -> bool:
        """48h minimum notice for routine inspections (EU competition law standard)."""
        notice_period = self.inspection_date - self.received_date
        return notice_period >= timedelta(hours=48)

    def check_procedural_validity(self) -> dict:
        """Verify notice contains all Art.91(3) required elements."""
        results = {}
        results["has_legal_basis"] = bool(self.stated_legal_basis)
        results["has_purpose"] = bool(self.stated_purpose)
        results["has_scope"] = len(self.stated_scope) > 0
        results["minimum_notice"] = self.has_minimum_notice()
        results["all_valid"] = all(results.values())
        return results

    def generate_challenge_grounds(self) -> list[str]:
        """Identify procedural defects that could support a challenge."""
        grounds = []
        validity = self.check_procedural_validity()
        if not validity["has_legal_basis"]:
            grounds.append("Missing legal basis — Art.91(3) requires explicit citation")
        if not validity["has_purpose"]:
            grounds.append("Missing purpose statement — required under Art.91(3)")
        if not validity["has_scope"]:
            grounds.append("Scope not specified — cannot assess proportionality")
        if not validity["minimum_notice"]:
            grounds.append(
                f"Insufficient notice: {(self.inspection_date - self.received_date).total_seconds()/3600:.1f}h "
                f"(minimum 48h for routine inspection)"
            )
        return grounds


@dataclass
class Art91InspectionMaterial:
    """Tracks materials within Art.91 inspection scope with confidentiality flags."""

    material_id: str
    category: str  # weights, source_code, methodology, evaluation, infrastructure
    description: str
    storage_location: str  # EU sovereign, US cloud, etc.
    contains_business_secrets: bool = False
    contains_personal_data: bool = False
    cloud_act_risk: str = "LOW"  # LOW, MEDIUM, HIGH

    def compute_integrity_hash(self, content: bytes) -> str:
        """SHA-256 hash for chain-of-custody integrity verification."""
        return hashlib.sha256(content).hexdigest()

    def get_cloud_act_exposure(self) -> dict:
        """Assess CLOUD Act conflict risk for this material."""
        us_cloud_providers = ["aws", "azure", "gcp", "google", "amazon", "microsoft"]
        is_us_cloud = any(p in self.storage_location.lower() for p in us_cloud_providers)
        return {
            "material_id": self.material_id,
            "on_us_cloud": is_us_cloud,
            "cloud_act_risk": self.cloud_act_risk if is_us_cloud else "NONE",
            "recommendation": (
                "Migrate to EU-sovereign storage before inspection"
                if is_us_cloud and self.cloud_act_risk in ["HIGH", "MEDIUM"]
                else "No action required"
            ),
        }


@dataclass
class Art91InspectionRegistry:
    """
    Central registry of all materials potentially within Art.91 inspection scope.
    Pre-populating this registry is the core of inspection readiness.
    """

    provider_name: str
    model_name: str
    materials: list[Art91InspectionMaterial] = field(default_factory=list)
    last_updated: datetime = field(default_factory=datetime.utcnow)

    def add_material(self, material: Art91InspectionMaterial) -> None:
        self.materials.append(material)

    def get_cloud_act_conflicts(self) -> list[dict]:
        """Return all materials with CLOUD Act conflict risk."""
        return [
            m.get_cloud_act_exposure()
            for m in self.materials
            if m.get_cloud_act_exposure()["cloud_act_risk"] in ["HIGH", "MEDIUM"]
        ]

    def get_readiness_assessment(self) -> dict:
        """Overall inspection readiness assessment."""
        total = len(self.materials)
        if total == 0:
            return {"level": InspectionReadinessLevel.NOT_READY, "reason": "No materials registered"}

        cloud_conflicts = self.get_cloud_act_conflicts()
        business_secret_materials = [m for m in self.materials if m.contains_business_secrets]

        return {
            "level": (
                InspectionReadinessLevel.READY
                if len(cloud_conflicts) == 0
                else InspectionReadinessLevel.PARTIAL
            ),
            "total_materials_registered": total,
            "cloud_act_conflict_count": len(cloud_conflicts),
            "business_secret_count": len(business_secret_materials),
            "recommendation": (
                "Migrate US-cloud materials to EU-sovereign storage to eliminate CLOUD Act conflicts"
                if cloud_conflicts
                else "Infrastructure jurisdiction clear — no CLOUD Act conflicts detected"
            ),
        }


def check_art91_inspection_readiness(registry: Art91InspectionRegistry) -> dict:
    """
    Master inspection readiness check. Run this quarterly and before any anticipated
    AI Office engagement to ensure Art.91 compliance posture is current.
    """
    assessment = registry.get_readiness_assessment()
    cloud_conflicts = registry.get_cloud_act_conflicts()

    report = {
        "provider": registry.provider_name,
        "model": registry.model_name,
        "assessment_date": datetime.utcnow().isoformat(),
        "readiness_level": assessment["level"].value,
        "materials_registered": assessment["total_materials_registered"],
        "cloud_act_conflicts": cloud_conflicts,
        "business_secret_items": assessment["business_secret_count"],
        "recommendation": assessment["recommendation"],
        "next_review": (datetime.utcnow() + timedelta(days=90)).isoformat(),
    }

    return report

The 30-Item Art.91 Inspection Readiness Checklist

Phase 1: Before Any Investigation Opens (Ongoing)

Phase 2: On Receipt of Art.91 Notice

Phase 3: During and After Inspection

Art.91 in the Art.89–94 Enforcement Context

Article 91 does not operate in isolation. It is one step in a six-article enforcement sequence:

ArticlePowerTrigger
Art.89Right to be heardBefore any adverse measure
Art.90Information requestsInvestigation opening, documentation gathering
Art.91Inspection powersDocumentation insufficient, capability concern, suspected falsification
Art.92Interview powersSpecific individual knowledge needed; interviews are voluntary in some contexts
Art.93Interim measuresSystemic risk confirmed + urgent threat to EU safety or society
Art.94Commitments and settlementsNegotiated resolution to avoid full penalty procedure

For GPAI providers, the practical path from Art.90 to Art.91 often happens when:

  1. An Art.90 information request reveals gaps or inconsistencies
  2. The AI Office receives a "qualified alert" from the Scientific Panel under Art.90(1)(b) about your model's capabilities
  3. Third-party red-teaming published externally contradicts your internal evaluation results
  4. Another GPAI provider's inspection revealed industry-wide practices the AI Office wants to verify

Understanding this sequence means you can monitor your investigation posture at each step — and ensure that an Art.90 response is complete enough that Art.91 escalation becomes unlikely.

Infrastructure Choices That Minimise Art.91 Risk

The single most effective Art.91 risk reduction strategy is keeping all materials in the inspection scope under a single legal order — EU law. When model weights, training data documentation, evaluation results, and source code are all stored on EU-sovereign infrastructure:

This is not primarily a compliance argument — it is a risk management argument. An Art.91 inspection on EU-only infrastructure is a bounded, manageable process. The same inspection when model weights are distributed across US commercial cloud infrastructure becomes a legal complexity exercise at exactly the wrong moment.


See Also


This guide is part of the EU AI Act Chapter VII enforcement series: Art.89 (Right to Be Heard) → Art.90 (Information Requests) → Art.91 (Inspection Powers) → Art.92 (Interview Powers) → Art.93 (Interim Measures) → Art.94 (Commitments and Settlements).