Tenant-isolatie in de praktijk: één gateway, vele klanten
In een moderne software-as-a-service architectuur waarin tientallen of honderden zakelijke klanten (tenants) gebruikmaken van gedeelde AI-functionaliteiten, is traditionele relationele database-isolatie niet langer voldoende. Zodra verzoeken via een gezamenlijke runtime-proxy of applicatiegateway naar externe foundational models stromen, ontstaat er een nieuw spectrum aan operationele, financiële en beveiligingsrisico's. Een enkele overactieve klant kan de gedeelde upstream token-quota uitputten, gevoelige documentfragmenten kunnen onbedoeld in gedeelde tussenopslagen belanden, en foutieve prompts kunnen globale rate-limiters blokkeren.
Een robuuste LLM-gateway fungeert als het centrale controlepunt waarin routing, authenticatie, kostenbewaking en scheiding samenkomen. Het doel van tenant-isolatie is om elke aangesloten organisatie de illusie en garanties van een volledig eigen, private AI-infrastructuur te bieden, terwijl de onderliggende resources efficiënt en centraal worden beheerd. Voor wie het bredere theoretische raamwerk en de initiële datamodellering wil bestuderen, biedt het overzicht voor multi-tenant LLM-applicaties bouwen een stevig fundament voor data-architecturen.
De vier dimensies van isolatie bij modelverkeer
Traditionele API-gateways richten zich voornamelijk op URI-paden, HTTP-statussen en eenvoudige compute-quota. Bij Large Language Models grijpt isolatie echter dieper in op het dynamische runtime-gedrag en de niet-deterministische aard van generatieve systemen. Een waterdichte architectuur dwingt isolatie af langs vier afzonderlijke dimensies:
Ten eerste is er de data- en context-isolatie. Prompts, systeeminstructies, RAG-documentfragmenten, tool-aanroepen en gegenereerde antwoorden van tenant A mogen onder geen enkel beding vermengd raken met de werkgeheugens, caches of contexten van tenant B. Dit geldt niet alleen tijdens de netwerktransmissie, maar juist in geaggregeerde systemen zoals semantische caches en vector-indexen.
Ten tweede vereist de runtime capaciteits- en doorvoerisolatie, ook wel de preventie van het noisy neighbor-syndroom genoemd. Wanneer één klant een ongeplande batchverwerking van tienduizenden documenten start, mag de resulterende piekbelasting geen verhoogde wachttijden of HTTP 429-fouten opleveren voor interactieve gebruikers van andere organisaties.
Ten derde is er financiële en budgettaire isolatie. LLM-aanroepen brengen variabele, reële marginale kosten met zich mee per gegenereerd en verwerkt token. De gateway moet het verbruik real-time meten, direct toerekenen aan de juiste kostenplaats, en de toegang automatisch blokkeren zodra een vooraf gedefinieerd budgetplafond wordt bereikt.
Ten vierde moeten we rekening houden met cryptografische en compliance-scheiding. Gereguleerde klanten eisen vaak dat verzoeken uitsluitend worden verwerkt via speciale contractuele endpoints met gegarandeerde nul-retentie of via eigen provider-accounts (Bring Your Own Key). De gateway moet deze beleidsregels dynamisch en foutloos afdwingen.
Data- en cache-isolatie: het risico van semantische lekken
Het implementeren van een centrale response-cache is een van de meest effectieve methoden om latency en API-kosten te reduceren. Wanneer een gateway echter gebruikmaakt van een semantische cache (waarbij vragen met een vergelijkbare vectorrepresentatie hetzelfde antwoord terugkrijgen), ontstaat een aanzienlijk risico op datalekken tussen organisaties.
Stel dat een HR-medewerker van Bedrijf A vraagt: "Wat is de vertrekregeling voor directieleden in ons 2026-beleid?". Als het gegenereerde antwoord met specifieke bedrijfsgeheimen wordt opgeslagen in een globale vectorcache zonder strikte scheiding, kan een soortgelijke vraag van een medewerker van Bedrijf B per ongeluk ditzelfde gecachte antwoord terugkrijgen. Dit type cross-tenant datavervuiling omzeilt alle traditionele autorisatielagen binnen de applicatielogica.
De enige veilige aanpak is het toepassen van harde cryptografische of logische scheiding binnen de cache-sleutels en vectorruimtes. Een cache-sleutel mag nooit uitsluitend bestaan uit de hash van de prompt of de embedding-vector, maar moet altijd zijn samengesteld uit meerdere verplichte metadata-elementen:
| Component | Sleutel- / Indexopbouw | Isolatiemechanisme | Faalmodus bij ontbreken |
|---|---|---|---|
| Exacte HTTP Cache | sha256(tenant_id + ":" + env + ":" + prompt) |
Prefix-gebaseerde Redis namespaces | Volledig antwoord met bedrijfsdata lekt naar andere klant |
| Semantische Cache | Vectorindex gefilterd op metadata tenant_id == X |
Geïsoleerde vectorpartities of metadata pre-filtering | Gedeeltelijke contextuele data lekt via similarity match |
| RAG Context Store | Row-Level Security (RLS) in relationele/vector database | PostgreSQL RLS-policies per database-rol | Ophalen van niet-geautoriseerde documentsecties |
| Audit Logs | Gecodeerd met tenant-specifieke KMS-sleutel | Envelop-encryptie per klantorganisatie | Centrale beheerder kan vertrouwelijke payloads inzien |
Naast de opslag moet ook de validatie van gegenereerde teksten per tenant kunnen verschillen. Organisaties hanteren uiteenlopende standaarden voor betrouwbaarheid en bronvermelding. Wie geautomatiseerde controles wil inrichten om hallucinaties en feitelijke onjuistheden per tenant-verzoek te toetsen, vindt gedetailleerde protocollen in de gids over AI-antwoorden factchecken om verificatielagen in te richten.
Noisy neighbors: tweelaags rate limiting en doorvoerbeheer
Externe LLM-leveranciers hanteren harde operationele limieten op twee parameters: verzoeken per minuut (Requests Per Minute, RPM) en tokens per minuut (Tokens Per Minute, TPM). Wanneer een centrale gateway alle uitgaande verbindingen over één provider-account bundelt, delen alle tenants in feite dezelfde upstream capaciteitspool. Zonder actieve begrenzing kan een enkele tenant binnen enkele seconden het volledige TPM-quotum verbruiken door een groot document in parallelle chunks te analyseren.
Om dit effectief tegen te gaan, gebruikt men een tweelaagse rate-limiting-architectuur op basis van het token-bucket-algoritme:
- Laag 1: Lokale Tenant Bucket (Ingress). Elk inkomend verzoek van een specifieke tenant wordt eerst getoetst aan de gecontracteerde SLA van die specifieke klant (bijvoorbeeld maximaal 100 verzoeken en 50.000 tokens per minuut). Overschrijdt de tenant deze drempel, dan geeft de gateway onmiddellijk een lokale HTTP 429-status terug met een duidelijke
Retry-Afterheader, zonder de upstream provider te belasten. - Laag 2: Globale Provider Bucket (Egress). Verzoeken die de tenant-check passeren, komen in een centrale prioriteitswachtrij die de totale uitgaande capaciteit naar OpenAI, Anthropic of Google bewaakt. Dreigt de globale provider-limiet te worden overschreden, dan buffert de gateway laag-prioritaire achtergrondtaken ten gunste van interactieve gebruikerssessies.
Deze scheiding zorgt ervoor dat operationele pieken van één afzonderlijke klant lokaal worden geïsoleerd en gedempt, waardoor de algehele stabiliteit van het platform voor alle overige klanten gegarandeerd blijft.
Authenticatiemodellen: Pooled Gateway Keys versus BYOK
Bij het ontwerpen van een multi-tenant gateway moet een fundamentele architectuurkeuze worden gemaakt ten aanzien van upstream API-sleutels: beheren we centrale sleutels (Pooled Keys) of ondersteunen we Bring Your Own Key (BYOK)? Beide scenario's stellen verschillende eisen aan de gateway.
In het Pooled Keys model bezit de SaaS-organisatie de contracten met de LLM-providers. De gateway bewaart deze master-sleutels in een centrale geheime kluis (zoals HashiCorp Vault of AWS Secrets Manager). Inkomende verzoeken worden geauthenticeerd via interne tenant-tokens, waarna de gateway de benodigde provider-credentials dynamisch injecteert. Voor operationele richtlijnen rondom geautomatiseerde rotatie, auditing en veilige omgang met deze centrale geheimen, raadpleegt men het dossier over API-sleutels voor LLM's veilig beheren.
In het Bring Your Own Key (BYOK) model leveren enterprise-klanten hun eigen API-sleutel van bijvoorbeeld OpenAI of Microsoft Azure aan. Dit stelt de klant in staat om gebruik te maken van eigen enterprise-kortingen, op maat gemaakte dataverwerkingsovereenkomsten of private netwerkverbindingen. De gateway moet deze klantsleutels veilig versleutelen met een unieke Key Encryption Key (KEK) per tenant. Tijdens runtime ontsleutelt de gateway de sleutel uitsluitend in het vluchtige geheugen van het verwerkende proces.
Implementatievoorbeeld: Multi-tenant Gateway Middleware
Onderstaand TypeScript-voorbeeld toont een robuuste Express-middleware voor een LLM-gateway. De code demonstreert tenant-authenticatie, isolatie van doorvoerlimieten via Redis, validatie van modeltoegang, budgetcontrole en conditionele sleutelinjectie.
import { Request, Response, NextFunction } from 'express';
import Redis from 'ioredis';
interface TenantProfile {
id: string;
allowedModels: string[];
rpmLimit: number;
monthlyBudgetEur: number;
currentSpendEur: number;
customApiKey?: string;
enforceZDR: boolean;
}
const redis = new Redis(process.env.REDIS_URL || 'redis://127.0.0.1:6379');
export async function tenantGatewayMiddleware(
req: Request,
res: Response,
next: NextFunction
): Promise<void> {
const tenantId = req.header('X-Tenant-ID');
const apiKey = req.header('X-Gateway-Key');
const requestedModel = req.body?.model;
// 1. Verplichte header-validatie
if (!tenantId || !apiKey || typeof tenantId !== 'string') {
res.status(401).json({
error: {
code: 'unauthorized',
message: 'Geldige X-Tenant-ID en X-Gateway-Key headers zijn verplicht.'
}
});
return;
}
try {
// 2. Ophalen en valideren van tenant-profiel uit beveiligde cache
const rawProfile = await redis.get(`tenant:profile:${tenantId}`);
if (!rawProfile) {
res.status(403).json({
error: {
code: 'tenant_forbidden',
message: 'Tenant is niet geactiveerd op deze gateway.'
}
});
return;
}
const tenant: TenantProfile = JSON.parse(rawProfile);
// 3. Toegangscontrole op modelniveau
if (!tenant.allowedModels.includes(requestedModel)) {
res.status(403).json({
error: {
code: 'model_not_allowed',
message: `Model '${requestedModel}' is niet vrijgegeven voor uw organisatie.`
}
});
return;
}
// 4. Strikte lokale RPM rate-limiting via Redis sliding window
const currentMinute = Math.floor(Date.now() / 60000);
const rateLimitKey = `tenant:ratelimit:${tenantId}:${currentMinute}`;
const requestCount = await redis.incr(rateLimitKey);
if (requestCount === 1) {
await redis.expire(rateLimitKey, 65); // Houd sleutel iets langer vast dan 1 minuut
}
if (requestCount > tenant.rpmLimit) {
res.setHeader('Retry-After', '60');
res.status(429).json({
error: {
code: 'rate_limit_exceeded',
message: 'Verzoeklimiet per minuut voor deze tenant is overschreden.'
}
});
return;
}
// 5. Harde budgetcontrole
if (tenant.currentSpendEur >= tenant.monthlyBudgetEur) {
res.status(402).json({
error: {
code: 'budget_depleted',
message: 'Het maandelijkse AI-budget voor deze organisatie is bereikt.'
}
});
return;
}
// 6. Request verrijken met tenant-specifieke runtime-context
req.tenantContext = {
tenantId: tenant.id,
upstreamApiKey: tenant.customApiKey || process.env.CENTRAL_PROVIDER_KEY!,
enforceZDR: tenant.enforceZDR,
spendTrackingKey: `tenant:spend:${tenant.id}`
};
next();
} catch (error) {
// Interne gatewayfout veilig afhandelen zonder stacktrace te lekken
res.status(500).json({
error: {
code: 'gateway_internal_error',
message: 'Er is een interne fout opgetreden bij het verwerken van het tenant-beleid.'
}
});
}
}
Nauwkeurige kostenallocatie en budgettaire kill switches
Een cruciaal operationeel onderdeel van multi-tenancy is de financiële administratie. Omdat taalmodellen factureren op basis van tokenaantallen — met vaak aanzienlijke prijsverschillen tussen prompt-tokens, gegenereerde output-tokens en gecachte contexten — volstaat een simpele verzoektelling niet.
De gateway moet bij elke voltooide aanroep de werkelijke verbruiksstatistieken uit de upstream respons extraheren. Bij gestreamde responses (Server-Sent Events) sturen moderne providers de definitieve usage-statistieken mee in het laatste data-chunk. De gateway onderschept deze stream, berekent de exacte kostprijs aan de hand van een interne prijsmatrix, en werkt het cumulatieve verbruik van de tenant asynchroon bij in een gedistribueerde database.
Voor een diepgaande beschouwing over hoe deze micro-transacties moeten worden gelogd, berekend en verwerkt in SaaS-abonnementsmodellen, biedt het artikel over API-kosten per eindgebruiker toerekenen in een SaaS-product praktische formules en databasepatronen.
Naast meting moet de gateway voorzien in een geautomatiseerde kill switch. Wanneer een klant een maandelijks budget van bijvoorbeeld 500 euro instelt, mag een runaway loop in een AI-agent er niet voor zorgen dat er binnen een uur duizenden euro's aan tokens worden geconsumeerd. De gateway blokkeert zodra de drempel wordt bereikt direct alle nieuwe niet-essentiële aanroepen met een HTTP 402 (Payment Required) foutmelding.
Compliance, routering en zero data retention
Binnen een zakelijk klantenbestand bestaan vaak grote verschillen in complianceniveau. Een marketingbureau accepteert wellicht dat data via reguliere cloud-endpoints loopt, terwijl een advocatenkantoor of financiële instelling strikte contractuele garanties eist. De meest voorkomende eis hierbij is Zero Data Retention (ZDR), waarbij de LLM-aanbieder garandeert dat prompts en antwoorden op geen enkele manier worden opgeslagen op schijf, niet worden gelogd voor debugging, en niet worden hergebruikt voor modeltraining.
De centrale gateway fungeert hierbij als beleidshandhaver. Wanneer in het profiel van een tenant de eigenschap enforceZDR actief is, zal de gateway verzoeken uitsluitend routeren naar goedgekeurde endpoints die onder deze specifieke overeenkomsten vallen. Om te zien welke provider-headers, encryptie-eisen en contractuele vinkjes hiervoor nodig zijn, leest men de technische documentatie over zero-data-retention configureren bij LLM-API's.
Architectuurkeuze: Zelfbouw gateway versus aggregator
Wanneer een organisatie start met het centraliseren van AI-verkeer over meerdere klanten, rijst al snel de vraag of men een eigen gateway moet bouwen of gebruik moet maken van een commerciële API-aggregator. Beide benaderingen kennen duidelijke voor- en nadelen die moeten worden afgewogen tegen de beschikbare engineeringcapaciteit en de complexiteit van de organisatie.
| Criterium | Zelfbouw Gateway (Custom Proxy) | Beheerde Aggregator Dienst |
|---|---|---|
| Data-soevereiniteit | Volledige controle: draait binnen eigen VPC / cloud-omgeving | Derde partij verwerkt mogelijk metadata en logs |
| Fijnmazige Tenant-isolatie | Volledig programmeerbaar tot op custom header-niveau | Afhankelijk van de features en RBAC van de aanbieder |
| Onderhoudslast | Hoog: team moet rate limiting, retries en updates zelf beheren | Laag: kant-en-klaar dashboard, SLA en integraties |
| BYOK-ondersteuning | Flexibel aan te sluiten op eigen HSM / Key Vault | Sleutels moeten worden toevertrouwd aan het aggregatorplatform |
Voor een uitgebreide analyse van de markt, protocollen en functionaliteiten van kant-en-klare routeringsdiensten verwijzen we naar het achtergrondartikel over de kracht van een LLM API-aggregator om de juiste keuze te maken tussen kopen en bouwen.
Operationele audit- en scheidingschecklist
Het beveiligen van een multi-tenant gateway is geen eenmalige configuratiestap, maar een continu operationeel proces. Voordat een gateway-architectuur in productie wordt genomen, dienen de volgende controles structureel te worden uitgevoerd en geautomatiseerd in CI/CD-pijplijnen:
- Geheugen-levenscyclus: Zorg ervoor dat buffers, request-strings en intermediate JSON-objecten direct na het voltooien van het HTTP-verzoek worden vrijgegeven door de runtime garbage collector om cross-request contextvervuiling in applicatieservers te voorkomen.
- Pseudonimisering in centrale logs: Sla in applicatiewijde logs (zoals Datadog, Grafana of CloudWatch) nooit ongecodeerde prompts of responses op. Gebruik uitsluitend gehashte tenant-ID's en anonieme correlatie-ID's.
- Geautomatiseerde isolatietests: Voer continue regressietests uit waarbij twee virtuele tenants gelijktijdig vergelijkbare prompts sturen, en verifieer dat er geen data overvloeit in semantische caches of downstream foutrapportages.
- Circuit breakers per tenant: Configureer foutdetectie zodanig dat wanneer de upstream provider faalt op prompts van een specifieke tenant (bijvoorbeeld door overschrijding van contextlengte of content policy filters), de circuit breaker uitsluitend die specifieke tenant pauzeert en niet de gehele gateway.
Door data-isolatie, dynamische rate limiting, kostenbewaking en strikte authenticatie te verenigen in één centrale gateway-laag, ontstaat een robuust en schaalbaar fundament. Hiermee kunnen honderden klanten veilig en voorspelbaar worden bediend zonder in te leveren op betrouwbaarheid, privacy of financiële controle.


