Deel:𝕏LinkedInRedditFacebookKopieer link

Logbewaring afstemmen op zero data retention

Door Ivo Donker — samengesteld met AI-ondersteuning · 7 augustus 2026

In productieomgevingen ontstaan regelmatig tegenstrijdige ontwerpeisen zodra een organisatie LLM-API's integreert. Aan de ene kant vereist een strikte privacy-architectuur dat er geen privacygevoelige gegevens of intellectueel eigendom achterblijven op externe servers. Aan de andere kant stellen compliance-kaders en incidentprotocollen de eis dat alle verwerkte transacties aantoonbaar, traceerbaar en auditeerbaar zijn. Dit leidt tot een schijnbare tegenstelling tussen het minimaliseren van gegevensopslag en het opbouwen van een sluitend auditspoor.

Zero data retention garandeert dat de API-provider de inhoud van prompts en gegenereerde antwoorden niet permanent opslaat op diens infrastructuur. Raadpleeg zero data retention API-configuraties voor het instellen van de retentieparameters aan de zijde van de LLM-aanbieder. Audit-logging omvat het onveranderlijk vastleggen van systeemtransacties om verantwoording en juridische bewijskracht te garanderen. Zie audit-logging en compliance voor de wettelijke bewijslast en bewaringsvereisten binnen AI-applicaties. Om dit conflict op te lossen moet de architectuur een scherp onderscheid maken tussen wat de provider bewaart en wat de eigen API-gateway lokaal verwerkt. Raadpleeg api-sleutels veilig beheren om de toegangsrechten tot specifieke logbestanden af te stemmen op de autorisaties van je API-sleutels.

Dit artikel behandelt het configureren van zero data retention bij een provider zelf niet; zie zero data retention API-configuraties. Dit artikel werkt de juridische afweging achter bewaartermijnen niet uit; zie de AVG privacy checklist op gids.llmnet.nl.

Het feitelijke bereik van Zero Data Retention versus lokaal beheer

Wanneer een organisatie Zero Data Retention (ZDR) contractueel of via API-parameters activeert, heeft dit uitsluitend betrekking op de opslag van de ongestructureerde payload bij de externe provider. De provider verwijdert de daadwerkelijke tekstinvoer (prompts) en de door het model gegenereerde tekst (completions) direct uit het vluchtige geheugen zodra de HTTP-response is afgerond. ZDR voorkomt dat deze gegevens worden gebruikt voor modeltraining of persistent worden opgeslagen op schijfeenheden van de leverancier.

ZDR betekent echter niet dat de externe provider helemaal niets registreert. Uit operationeel en financieel oogpunt houden providers altijd een minimale set infrastructuurdata bij (illustratief, stand: augustus 2026):

Het misverstand dat ZDR automatisch leidt tot een volledig logvrije keten is een risico voor compliance. De verantwoordelijkheid voor het nakomen van bewaarplichten en privacyregels verschuift door ZDR volledig van de provider naar de eigen infrastructuur. Alles wat de provider niet meer opslaat, moet de eigen API-gateway op een veilige en gecontroleerde manier verwerken. Wanneer er gebruik wordt gemaakt van antwoord-caching op de eigen gateway, valt deze data onder aanvullende retentierogels. Zie caching van LLM-antwoorden om te bepalen onder welke retentiecategorie tussentijds opgeslagen modelreacties vallen.

Om te voorkomen dat de eigen gateway onbedoeld gevoelige gegevens of persoonsgegevens (PII) permanent opslaat in tijdelijke logbestanden, dient er een actieve scheiding te worden aangebracht aan de rand van het netwerk. Zie invoervalidatie en outputfiltering om schadelijke payloads en PII te filteren voordat deze de logpijplijn bereiken.

Architectuurscheiding: Observability versus Audit-logging

Om te voldoen aan zowel de eis van minimale dataopslag als de eis van aantoonbare controle, is een strikte architecturale scheiding tussen observability-signalen en audit-logs noodzakelijk. Het combineren van deze twee functies in één centrale log-database leidt tot privacyrisico's of tot onbeheersbare opslagkosten.

Observability-signalen richten zich op de operationele gezondheid van de applicatie en de runtime-prestaties van de LLM-integratie. Lees observability en logging voor het inrichten van operationele prestatiestripping en foutsporing. Deze gegevens zijn vluchtig van aard, hebben een hoge dichtheid en bevatten voornamelijk metrieken, responstijden (latency) en geaggregeerde foutpercentages. Observability-logs mogen en moeten na een korte periode automatisch worden opgeschoond.

Audit-logging dient daarentegen een juridisch en organisatorisch doel: het opleveren van onomstotelijk bewijs dat een specifieke actie op een specifiek moment door een geautoriseerde gebruiker of entiteit is uitgevoerd. Audit-logs moeten onveranderlijk (immutable) zijn, voorzien zijn van cryptografische integriteitscontroles en een lange bewaartermijn ondersteunen. In multi-tenant omgevingen moet de logstructuur daarnaast voorkomen dat gegevens van verschillende eindklanten door elkaar lopen. Bekijk multi-tenant LLM-apps om te leren hoe je logstromen per eindklant strikt van elkaar isoleert.

De drie bewaarstromen: Analyse volgens het productiepatroon

Een robuuste log-architectuur verdeelt alle uitgaande en inkomende telemetrie in drie gescheiden stromen. Elke stroom kent een eigen faalmodus, detectie-mechanisme, mitigatiestrategie en kostenprofiel.

Stroom 1: Operationele logstroom (Observability & Diagnostics)

De operationele logstroom verzamelt telemetrische data om te controleren of de LLM-koppeling correct functioneert, wat de gemiddelde responstijd is en waar eventuele latency-pieken ontstaan.

Stroom 2: Audit- en Compliance-logstroom (Verantwoording)

De audit-logstroom legt vast wie op welk moment welke categorie LLM-verwerking heeft geïnitieerd en wat de wettelijke of contractuele grondslag daarvan was.

Stroom 3: Security- en Incidentrespons-logstroom (Forensisch & Anomaliedetectie)

De security-logstroom legt gedetailleerde interactiepatronen vast om beveiligingsincidenten, zoals misbruik van API-sleutels, datalekkage of geavanceerde prompt-injectie-aanvallen, te kunnen analyseren en reconstrueren.

Pseudonimisering en Versleuteling als Brug

Om het conflict tussen "niets bewaren" en "aantoonbaar beweren" op te lossen, vormen versleuteling en pseudonimisering de technische brug. Door gegevens op de eigen API-gateway te transformeren vóór opslag, wordt voldaan aan de vereisten van gegevensminimalisatie zonder dat de bewijskracht van het auditspoor verloren gaat.

De onderstaande twee technieken vormen het fundament van deze brug:

  1. Salted HMAC Hashing voor Audit-Traceerbaarheid: Door de invoertekst te hashen met een geheime sleutel (HMAC-SHA256) ontstaat een unieke vingerafdruk. Indien een gebruiker later claimt dat een specifiek verzoek niet door hem is ingediend, kan de organisatie de invoer opnieuw hashen en vergelijken met de hash in het WORM-auditlog. De originele tekst kan echter nooit uit de hash worden teruggewonnen.
  2. Envelope Encryption voor Forensische Opslag: De payload wordt direct bij ontvangst versleuteld met een unieke symmetrische datasleutel (AES-GCM-256). Deze datasleutel wordt vervolgens versleuteld met een hoofdsleutel uit een Key Management Service (KMS). Alleen bij een formeel beveiligingsincident wordt de sleutel vrijgegeven om de specifieke transactie te ontsleutelen voor forensisch onderzoek.

Implementatie: Foutbestendige Log-Classificatie en Audit-Writer

De onderstaande provider-onafhankelijke pseudocode demonstreert een foutbestendige implementatie van een log-processor op een API-gateway. De code splitst inkomende LLM-transacties op in de drie gedefinieerde stromen, past hashing en versleuteling toe, en bevat expliciete afhandeling voor netwerk-timeouts en verwerkingsfouten. Wanneer een secundaire logstream faalt, blijft de primaire LLM-stroom operationeel, terwijl de fout wordt opgevangen zonder dataverlies in het audit-spoor.

// Provider-onafhankelijke pseudocode voor geclassificeerde audit-logging
import { computeHMAC, encryptPayload, sendToWORM, sendToAPM } from "gateway-crypto-lib";

interface LLMTransaction {
    transactionId: string;
    userId: string;
    tenantId: string;
    promptText: string;
    completionText: string;
    promptTokens: number;
    completionTokens: number;
    durationMs: number;
    statusCode: number;
}

async function processLLMLogs(transaction: LLMTransaction, config: GatewayConfig): Promise<void> {
    const TIMEOUT_MS = 1500;
    
    // 1. STROOM 1: Operationele Telemetrie (Gestript van payload)
    const operationalRecord = {
        transactionId: transaction.transactionId,
        tenantId: transaction.tenantId,
        promptTokens: transaction.promptTokens,
        completionTokens: transaction.completionTokens,
        durationMs: transaction.durationMs,
        statusCode: transaction.statusCode,
        timestamp: new Date().toISOString()
    };

    // Fast-fire operationele log (non-blocking)
    sendToAPM(operationalRecord).catch(err => {
        console.error("APM Logging waarschuwing: opslag mislukt", err.message);
    });

    // 2. STROOM 2: Audit-log (Gehasht & Uniek)
    const promptHash = computeHMAC(transaction.promptText, config.hmacSecret);
    const completionHash = computeHMAC(transaction.completionText, config.hmacSecret);

    const auditRecord = {
        transactionId: transaction.transactionId,
        userIdHash: computeHMAC(transaction.userId, config.hmacSecret),
        tenantId: transaction.tenantId,
        promptHash: promptHash,
        completionHash: completionHash,
        tokenCountTotal: transaction.promptTokens + transaction.completionTokens,
        timestamp: new Date().toISOString()
    };

    // Asynchrone schrijfactie naar WORM met timeout-beveiliging
    try {
        await Promise.race([
            sendToWORM(auditRecord),
            new Promise((_, reject) => 
                setTimeout(() => reject(new Error("WORM Storage Timeout")), TIMEOUT_MS)
            )
        ]);
    } catch (error) {
        // FOUTPAD: Audit-mislukking mag de API-response niet blokkeren, 
        // maar moet worden omgeleid naar een lokale nood-queue op schijf.
        console.error("CRITICAL: Audit-log kon niet naar WORM worden geschreven:", error.message);
        await emergencyDiskQueue.enqueue({
            type: "AUDIT_FAILURE_BACKUP",
            record: auditRecord,
            failedAt: new Date().toISOString(),
            reason: error.message
        });
    }

    // 3. STROOM 3: Security-log (Versleutelde Payload)
    if (config.securityLoggingEnabled) {
        try {
            const encryptedBody = await encryptPayload(
                JSON.stringify({
                    prompt: transaction.promptText,
                    completion: transaction.completionText
                }),
                config.kmsPublicKey
            );

            await sendToSecurityVault({
                transactionId: transaction.transactionId,
                encryptedData: encryptedBody,
                expiresAt: Date.now() + (90 * 24 * 60 * 60 * 1000) // 90 dagen TTL
            });
        } catch (secError) {
            console.error("SECURITY_LOG_ERROR: Encrypted payload backup mislukt", secError.message);
            // Vallen niet stil: veiligheidslog-fouten genereren een alert in de SIEM-pijplijn
            emitSIEMAlert("SECURITY_LOG_DISRUPTION", { transactionId: transaction.transactionId });
        }
    }
}

Retentie-matrix: Gecombineerd bewaarschema

De onderstaande tabel geeft het gecombineerde retentie-overzicht weer dat voldoet aan zowel de voorwaarden van Zero Data Retention bij de provider als de interne en wettelijke compliance-eisen op de eigen infrastructuur.

Logstroom Inhoud & Payload Bewaartermijn Opslagklasse Toegangsregime ZDR-Compatibiliteit
Operationeel Metadata, statuscodes, latency, token-aantallen. Geen tekst. 14 - 30 dagen Standaard Index / APM Storage DevOps & SRE Teams Volledig compatibel (bevat geen prompt-data)
Audit / Compliance Hashes van prompt/completion, time-stamps, gehashte User-ID. 1 - 7 jaar WORM Object Storage (S3 Lock Mode) Compliance & External Auditors Volledig compatibel (onomkeerbare hashes)
Security / Forensisch Geëncrypteerde volledige payload (AES-256-GCM via KMS). 90 - 180 dagen Encrypted Cold Storage / Vault Security Officer + 4-Eyes Protocol Compatibel mits opslag buiten provider om gaat
Provider-zijde (ZDR) Uitsluitend geaggregeerde facturatiemetingen en IP-telemetrie. Conform provider-SLA (meestal 0-30 dagen) Provider Cloud Platform Provider SRE & Billing Systems Standaard ZDR-garantie bij provider

Implementatie-checklist voor Productie-omgevingen

Volg dit stappenplan om de logbewaring op de eigen API-gateway af te stemmen op de ZDR-instellingen van de externe LLM-aanbieder:

  1. Verifieer de ZDR-status bij de provider: Controleer contractueel en via de API-headers of Zero Data Retention actief is voor de specifieke endpoint-sleutels.
  2. Configureer Payload Stripping op de Gateway: Zorg dat de API-gateway standaard alle prompt- en completion-velden verwijdert uit de primaire applicatielogs voordat deze naar log-aggregators worden verzonden.
  3. Richt de Asynchrone Audit-Pijplijn in: Implementeer een gescheiden, asynchrone message-broker die audit-records bouwt op basis van HMAC-hashing.
  4. Schakel WORM-beveiliging in: Activeer S3 Object Lock of een vergelijkbare onveranderlijke opslagmethode voor het audit-bucket en stel de bewaartermijn in conform de uitkomsten van de DPIA.
  5. Implementeer Envelope Encryption voor Incidentrespons: Indien het risicoprofiel forensische reconstructie vereist, richt dan geautomatiseerde asymmetrische versleuteling in voor tijdelijke security-logs.
  6. Valideer Foutpaden en Nood-queues: Test of het systeem bij uitval van de audit-database correct terugvalt op een beveiligde lokale nood-queue zonder dat de API-aanroep naar de eindgebruiker blokkeert.
  7. Voer Periodieke Hashing-Audits uit: Controleer kwartaalwijs of de gehashte gegevens in het audit-log nog consistent kunnen worden geverifieerd met de brongegevens uit de primaire databases.