Blog

Multi-Tenancy mit Cognito

7 min Lesezeit
aws saas multi-tenancy cognito identity

47.000 User. 3.000 Tenants. Ein Cognito User Pool. Kein einziger Tenant sieht die Daten eines anderen.

So beschreibt Trend Micro ihre Cloud One Plattform auf der re:Invent. Was mich an dem Talk fasziniert hat: nicht die Lösung, sondern der Weg dahin. Die Entscheidungen, die Trade-offs, die Stellen an denen sie bewusst Komplexität akzeptiert haben.

SaaS Identity — die Grundidee

Die erste Erkenntnis die Suresh (AWS Cognito Team) auf der Bühne erklärt: SaaS Identity ist nicht dasselbe wie User Identity. In einem Multi-Tenant-System brauchst du beides: die User-ID und die Tenant-ID. Zusammen bilden sie die SaaS Identity.

Das klingt trivial. Ist es nicht. Weil die meisten Teams die Tenant-Zuordnung als Afterthought behandeln. Der User wird authentifiziert, und irgendwo im Code hängt dann ein tenantId dran. Aber wo dieses tenantId herkommt, wie es validiert wird, und ob es überhaupt in jedem Request vorhanden ist — das sind die Fragen die entscheiden ob dein System Tenant-Isolation hat oder nur so tut als ob.

Drei Modelle

Es gibt drei fundamentale Ansätze, wie du Multi-Tenancy in SaaS umsetzen kannst. Jeder hat massive Trade-offs. Klick dich durch und schau dir die Dimensionen an:

Multi-Tenancy ModelleSilo
Dedizierte Ressourcen pro Tenant. Eigene User Pools, eigene Policies, eigene Infrastruktur.
Ein Cognito User Pool pro Tenant. Jeder Tenant hat eigene Passwort-Policy und MFA-Settings.
IsolationMaximal — dedizierte Ressourcen
Policy-FlexibilitätIndividuell pro Tenant
KosteneffizienzNiedrig — Ressourcen dupliziert
DeploymentKomplex — Rollout pro Tenant
Ressourcen-EffizienzNiedrig — Peak-Planung nötig
SkalierbarkeitLimitiert — Account-Grenzen

Silo gibt dir maximale Isolation und Policy-Kontrolle: jeder Tenant hat seine eigenen Ressourcen. Dafür zahlst du mit Deployment-Komplexität und Kosten. Jede Änderung muss über alle Tenants ausgerollt werden, und jeder Tenant braucht seine eigene Kapazitätsplanung.

Pool ist das Gegenteil: ein Set von Ressourcen für alle. Effizient, einfach zu deployen, elastisch skalierbar. Aber gemeinsame Policies, keine Tenant-spezifischen Konfigurationen, und das Noisy-Neighbor-Problem. In regulierten Branchen oft nicht akzeptabel.

Hybrid kombiniert das Beste aus beiden Welten: User-Identity zentral, Tenant-Zuordnung extern. Mehr Aufwand beim Aufbau, aber langfristig die flexibelste Option. Trend Micro hat sich genau dafür entschieden, und ich finde das für die meisten ernsthaften SaaS-Produkte richtig.

Der Silo-Ansatz klingt sicher, aber Suresh macht einen Punkt den die meisten übersehen: auch im Silo gibt es gemeinsame Elemente: Provisioning, De-Provisioning, User-Management. Du hast also nie wirklich vollständige Isolation. Die Frage ist nur, wo du die Grenze ziehst.

Fünf Cognito-Ansätze

Amazon Cognito bietet fünf konkrete Wege, Multi-Tenancy umzusetzen. Jeder mappt auf eins der drei Modelle. Klick dich durch und schau wie sich die Ansätze unterscheiden:

Cognito Multi-TenancyPOOL
Custom AttributePOOL
Tenant-ID als Custom Attribute im User-Profil. Wird beim Onboarding gesetzt.
User Pools
1 (geteilt)
Tenant-Zuordnung
custom:tenant_id
User : Tenant
1 : 1
Tenant-Kontext: custom:tenant_id aus dem JWT Token
Einfachste Implementierung. Ein User Pool reicht.
User fest an einen Tenant gebunden. Kein Multi-Tenant pro User.

Custom Attribute ist der einfachste Weg: custom:tenant_id ins User-Profil. Funktioniert, solange ein User nur zu einem Tenant gehört. Für B2C mit klarer Tenant-Zuordnung oft ausreichend.

Gruppen erlauben N:M-Beziehungen, ein User in mehreren Tenants. Das Problem: die Group-IDs landen im JWT Token. Bei 50 Gruppen kein Thema. Bei 1.000? Token-Größe wird zum Limit. Genau das hat Trend Micro ausgeschlossen.

App Client pro Tenant ist ein interessanter Mittelweg: separate OAuth-Flows pro Tenant, aber ein User Pool. Gut für unterschiedliche Redirect-URIs oder Client-Konfigurationen.

User Pool per Tenant ist der Silo-Ansatz. Volle Kontrolle, eigene Passwort-Policies, eigene MFA-Settings. Aber: jeder Login braucht ein Mapping (“Welcher User Pool gehört zu diesem Tenant?”), und du rollst Änderungen über N User Pools aus.

Externe Zuordnung ist Trend Micros Wahl: User-Identity in Cognito, Tenant-Membership in DynamoDB. Kein Token-Limit, beliebig viele Tenants pro User, maximale Flexibilität. Der Preis: du baust dein eigenes Token-Management.

Jeff Pascoe (Trend Micro) erzählt, dass manche Kunden mehr als 1.000 Accounts wollten, mit einzelnen Usern die Zugang zu allen brauchten. Das schließt den Gruppen-Ansatz sofort aus. Wenn du solche Anforderungen vorhersehen kannst, spar dir den Umweg.

Trend Micros Architektur

Trend Micro hat die vielleicht interessanteste Architektur-Entscheidung des Talks getroffen: Custom Token Exchange. Der Flow:

  1. User authentifiziert sich bei Cognito → Cognito Token
  2. User ruft den Account Service auf → Liste der verfügbaren Tenants
  3. User wählt einen Tenant → CloudOne Token (eigenes Token mit Tenant-Kontext und Rolle)
  4. Alle API-Calls verwenden das CloudOne Token → Services sind vom Auth-Mechanismus isoliert
// 1. Cognito Token validieren
const cognitoUser = await validateCognitoToken(req.headers.authorization);

// 2. Tenant-Membership aus DynamoDB laden
const memberships = await dynamodb.query({
  KeyConditionExpression: 'userId = :uid',
  ExpressionAttributeValues: { ':uid': cognitoUser.sub },
}).promise();

// 3. CloudOne Token mit Tenant-Kontext ausstellen
const cloudOneToken = signToken({
  sub: cognitoUser.sub,
  accountId: selectedAccount.id,
  role: selectedAccount.role,
  // Kein PII — bewusst weggelassen
});

Warum eigene Tokens? Drei Gründe:

Tenant-Switching ohne Re-Authentication. Mit dem Cognito Token kann der User jederzeit ein neues CloudOne Token für einen anderen Tenant holen. Kein Logout, kein erneutes MFA. Das war ein konkreter Schmerzpunkt mit dem alten System.

PII-Isolation. Das CloudOne Token enthält bewusst keine personenbezogenen Daten. Services sehen User-ID, Tenant-ID und Rolle, aber nicht den Namen oder die E-Mail. Cognito-Token mit PII bleibt auf die Core Identity Services beschränkt.

Entkopplung vom Identity Provider. Während der Migration haben User sich über das alte System oder Cognito eingeloggt. Egal welcher Provider, der Output war derselbe CloudOne Token. Services mussten nichts ändern.

Vor Cognito: WAF + Lambda Proxy

Ein Detail das leicht untergeht: Trend Micro hat einen Lambda Proxy und AWS WAF vor Cognito geschaltet. Das ist ungewöhnlich, die meisten Teams sprechen direkt mit Cognito.

Der Grund: DDoS-Schutz auf die Auth-Endpoints und die Möglichkeit, Cognito-Verhalten zu erweitern. Zum Beispiel: zusätzliche Validierung von User-Attributen, die Cognito nativ nicht unterstützt.

Dazu kommen vier Lambda Triggers:

Die regionale Unabhängigkeit ist bemerkenswert: jede AWS-Region operiert eigenständig. Ein User mit CloudOne Token kann in seiner Region arbeiten ohne Cross-Region-Dependencies. Die einzige Ausnahme: der Cognito JWKs Endpoint für die Token-Validierung. Den könnten sie auch in einen regionalen S3 Bucket cachen, haben sie aber bisher nicht gebraucht.

Die harten Entscheidungen

Der ehrlichste Teil des Talks: wo es wehgetan hat.

Single Password Policy. Ein User Pool = eine Passwort-Policy für alle. Das alte System ließ Tenant-Admins eigene Policies setzen: Passwort-Länge, Rotation, Komplexität. Das mussten sie aufgeben. Für die meisten Kunden kein Problem. Für die paar mit Custom Policies: schwierige Gespräche.

Migration über 9 Monate. Jeder User musste eine neue Identity anlegen, weil das neue System verifizierte E-Mail-Adressen als User-ID verwendet. Cognito’s Migration Trigger funktioniert nicht mit MFA-Seeds. Also: kein automatischer Import für User mit MFA. Das betrifft die meisten Enterprise-User. Jeff sagt selbst: “Some of our customers were pretty unhappy with us.”

SAML Federation. Ihr Multi-Tenancy-Modell (ein User Pool, externe Tenant-Zuordnung) hat nicht gut mit Cognito’s nativem SAML-Support funktioniert. Das Problem: ein federated Identity Provider in einem User Pool kann User-Identities über das gesamte System assertieren. Sie konnten nicht zulassen, dass ein Kunden-IdP beliebige Identities im System behauptet. Lösung: eigener SAML-Support, bei dem jeder Tenant separat definiert, welchen Identity Providern er vertraut.

Fünf Fragen vor der Entscheidung

Wie wechseln User zwischen Tenants? Wenn User in mehreren Tenants sind, brauchst du Token Exchange oder ein ähnliches Pattern. Gruppen-basierte Ansätze stoßen bei vielen Tenants pro User an Token-Größen-Limits.

Brauchen Tenants eigene Policies? Wenn ja, kommst du um den Silo-Ansatz (User Pool per Tenant) oder Custom-Logik im Hybrid-Ansatz nicht herum. Wenn nicht, spart dir ein einzelner User Pool massiv Komplexität.

Migrierst du ein bestehendes System? Cognito’s User Migration Trigger ist großartig, solange deine User kein MFA haben. Mit MFA brauchst du eine Brücke, und die kostet Zeit.

Brauchst du Identity Federation? SAML und OIDC in einem Multi-Tenant-Setup ist ein eigener Talk. Wenn deine Enterprise-Kunden ihren eigenen IdP mitbringen wollen, plan dafür Architektur-Aufwand ein.

Wie groß wird es? Trend Micro hat sich bewusst gegen Limits entschieden: kein Limit auf Tenants pro User, kein Limit auf User pro Tenant. Das hat die Architektur komplexer gemacht, aber sie können jede Anforderung abbilden. Wenn du weißt, dass deine Limits moderat bleiben, reicht ein einfacherer Ansatz.

Cognito kann für die meisten Projekte out-of-the-box genug. Trend Micro brauchte mehr und hat 9 Monate dafür bezahlt. Wisse vorher, in welcher Kategorie du bist.