L'autorisation dans les projections
Où placer le contrôle d'accès quand la lecture passe par un read model : ce qui doit être projeté, ce qui doit rester lu à la source, et la fenêtre pendant laquelle une révocation n'est pas encore vraie.
Par Elias Varen7 min de lectureMembres
Du côté écriture d'un système CQRS, l'autorisation a un endroit naturel. Le handler de commande charge l'aggregate, connaît l'acteur, décide. Du côté lecture, il n'y a ni aggregate ni invariant, seulement une table dénormalisée, construite par un processus qui n'a jamais eu de session, et une requête qui la lit. Si personne n'a décidé qui a le droit de lire cette table, la réponse par défaut est « quiconque atteint l'endpoint ».
Un read model n'hérite donc pas de l'autorisation de ses événements. Chaque projection est une nouvelle surface de lecture, et la règle d'accès doit y être reconstruite explicitement, avec une contrainte que le côté écriture ignore, puisqu'elle arrive en retard.
La colonne de tenant se perd en route
Le premier mode de défaillance est le plus bête. Une projection agrège, par exemple « chiffre d'affaires par mois » ou « dossiers en attente par étape ». En regroupant, quelqu'un écrit la clé de la table comme (month) au lieu de (tenant_id, month). Le premier tenant qui émet un événement crée la ligne, les autres l'incrémentent, et le tableau de bord de chaque client affiche la somme de tous.
Aucun contrôle d'accès ne rattrape cela, parce que la donnée est mélangée avant d'être lue.
CREATE TABLE monthly_revenue_v3 (
tenant_id uuid NOT NULL,
month date NOT NULL,
amount bigint NOT NULL,
PRIMARY KEY (tenant_id, month)
);Le tenant est le premier élément de la clé primaire de toute table de lecture, sans exception, et il vient des métadonnées de l'événement, posées par l'infrastructure à l'écriture, jamais du payload. Un test de schéma vérifie que chaque table de projection porte la colonne en tête de clé, de la même manière qu'on vérifie les politiques dans Row-level security PostgreSQL.
La lecture suit la même règle que les repositories d'écriture, avec aucune méthode de requête sans tenant dans sa signature.
Le dossier complet : Autorisation, du contrôle d'accès au multi-tenant
À lire ensuite
Toute la rubrique SécuritéSécurité
BOLA : le bug numéro un et son test
Pourquoi l'autorisation au niveau de l'objet échappe aux revues et aux scanners, et comment une matrice de tests à deux tenants, branchée sur le routeur, la rend impossible à oublier.
7 minLecture libre
Sécurité
Row-level security PostgreSQL : garde-fou ou piège
Ce que la row-level security filtre vraiment, les rôles et les objets qui passent au travers, ce qu'elle coûte au planificateur, et le critère pour en faire un second filet plutôt que votre seule isolation.
7 minLecture libre
Sécurité
RBAC, ABAC, ReBAC : le coût de chacun
Ce que chaque modèle d'autorisation coûte en modélisation, en requêtes de liste et en migration, et la question qui permet de choisir : savez-vous traduire votre règle en filtre SQL ?
7 minMembres