About multitenant
A reference for developers building multitenant applications, with isolation strategies, security invariants, and implementation examples. It covers isolation tiers from shared schemas to dedicated databases, as well as RLS, access control, and migration considerations.
Key features
- 01Three tiers of tenant data isolation
- 02tenant_id propagation and PostgreSQL RLS
- 03Tenant isolation testing requirements
- 04Audit trails and field-level encryption
- 05RBAC and ABAC selection guidance
- 06Laravel and Symfony examples
Use cases
- 01Choose an isolation approach for customer segments
- 02Prevent accidental cross-tenant data access
- 03Plan migration to tenant-specific infrastructure
- 04Design access control and sensitive-field protection
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ thebeardedbearsas/ claude-craft --skill multitenantAfter installing, type/multitenantin Claude Code to confirm it loaded.
Bundled filesREFERENCE.md
Details
From the project READMEMultitenant — Quick Reference
Servir plusieurs clients (tenants) sur la même base de code avec isolation stricte et un coût d'infra contrôlé.
Trois tiers d'isolation
| Tier | Isolation | Coût | Cas d'usage |
|---|---|---|---|
| Tier 1 — Shared schema | colonne tenant_id partout, filtres SQL automatiques | Faible | Startups, free / petits clients |
| Tier 2 — Dedicated schema | un schéma PostgreSQL par tenant | Moyen | SMB, clients exigeants |
| Tier 3 — Dedicated DB | une base entière par tenant | Élevé | Enterprise, compliance stricte (HDS, FedRAMP) |
Règle de migration : commencer Tier 1, migrer un client en Tier 2/3 quand il représente > 20 % du revenu OU exige un SLA spécifique.
Cinq invariants non-négociables
tenant_idpropagé à chaque requête (AsyncLocalStorage / SecurityContext / middleware).- PostgreSQL Row-Level Security (RLS) activé sur TOUTES les tables. Filet de sécurité contre un oubli applicatif.
- Tests d'isolation obligatoires. Tenant A ne doit jamais lire/écrire les données de B — y compris via tri, requête nuée, agrégat.
- Audit trail isolé par tenant. Pas de log multi-tenant cross-référencé sans permission explicite.
- Field-level encryption sur PII / secrets sensibles (Halite PHP, Eloquent Casts, libsodium).
Pattern minimal — Shared schema + RLS
ALTER TABLE invoices ADD COLUMN tenant_id UUID NOT NULL;
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON invoices
USING (tenant_id = current_setting('app.tenant_id')::uuid);
// Symfony — middleware qui set la variable session pour RLS
$conn->executeStatement(
'SET LOCAL app.tenant_id = :tid',
['tid' => $tenantId]
);
Anti-patterns critiques
- ❌ Oublier le filtre
tenant_iddans une requête raw → fuite cross-tenant. - ❌ Cache Redis sans préfixe tenant → données de A retournées à B.
- ❌ Job worker async qui perd le
tenant_id→ impossible de retrouver le contexte. - ❌ Signed URLs / tokens sans
tenant_iddans le payload → utilisable cross-tenant. - ❌ Field encryption avec une clé unique partagée → compromission = exposition totale (préférer keys per tenant).
RBAC / ABAC
- RBAC : rôles globaux (
admin,member,viewer) suffisent pour 80 % des cas. - ABAC : passer à des policies (Casbin, Cerbos, OPA) quand les règles dépendent d'attributs (région, montant, statut).
Pour aller plus loin
Patterns détaillés par tier, migration tier 1 → tier 2 sans downtime, tests d'isolation (Pest + tenant fixtures), RBAC/ABAC, exemples Laravel + Symfony, checklists par phase : voir
@.claude/skills/multitenant/REFERENCE.md.