Isolation par organisation¶
Une portée d'organisation ne doit pas dépendre de la discipline de chaque
requête. mic.tenancy associe le contexte au flux courant et expose une vue
relationnelle qui refuse les opérations non bornées.
from mic.tenancy import TenantScopedRelationalStore, tenant_context
projects = TenantScopedRelationalStore(
raw_store,
tenant_field="organization_id",
)
with tenant_context(organization_id):
rows = projects.find(Project, query)
Garanties de la vue sécurisée¶
TenantScopedRelationalStore protège insert, get, find, count et
delete :
- sans
tenant_context, l'opération lèveTenantLeak; - les lectures et comptages reçoivent toujours le filtre de l'organisation ;
- un filtre fourni par l'appelant sur le champ d'organisation est refusé ;
- une insertion dont l'organisation diffère du contexte est refusée ;
getetdeletene voient jamais une ligne d'une autre organisation.
Le contexte repose sur ContextVar : il suit le flux asynchrone courant et est
restauré à la sortie du bloc. Le transport HTTP, gRPC ou worker reste
responsable d'ouvrir le contexte depuis une identité déjà authentifiée.
Rendre le contournement inaccessible¶
La garantie vaut pour la vue injectée. Si un repository reçoit aussi le stockage
brut, il peut contourner cette frontière. La composition doit donc construire
le stockage brut au démarrage et ne transmettre aux modules multi-organisation que
TenantScopedRelationalStore.
Pour une donnée très sensible, complétez cette barrière applicative avec une politique de sécurité au niveau de la base, par exemple PostgreSQL Row-Level Security. MIC ne crée ni n'administre cette politique et ne remplace pas les tests d'isolation exécutés sur le dialecte réel.
Limites intentionnelles¶
- le champ vaut
organization_idpar défaut et reste configurable ; - les opérations propres au moteur passent par une porte SQL qui doit appliquer explicitement la même portée ;
- MIC ne choisit ni la stratégie de partitionnement, ni la hiérarchie des organisations, ni les règles d'administration inter-organisation.
Voir aussi la sortie SQL explicite.