ParserRowPolicyNames accepte trois formes de regroupement (et non un produit cartésien complet) :
- Plusieurs noms, une cible —
pol1, pol2 ON table1crée chaque nom indiqué sur cette seule table (oudb.*). - Un nom, plusieurs cibles —
pol1 ON table1, table2crée le même nom court sur chacune des cibles indiquées. - Paires mixtes —
p1 ON t1, p2 ON t2crée chaque nom uniquement sur la cible qui lui est associée.
ON de plusieurs tables dans un même groupe : p1, p2 ON t1, t2 est rejetée. Après un groupe comportant plusieurs noms, vous ne pouvez pas non plus ajouter, dans la même instruction, un autre groupe name ON target séparé par des virgules.
La clause facultative ON CLUSTER s’applique à l’ensemble de l’instruction (un seul nom de cluster). ClickHouse n’accepte pas de clause ON CLUSTER différente pour chaque nom de politique regroupé dans une seule création — exécutez des instructions CREATE ROW POLICY distinctes lorsque des politiques doivent être créées sur différents clusters.
CREATE ROW POLICY requiert le privilège CREATE ROW POLICY sur la table sur laquelle la politique est créée. OR REPLACE supprime une politique existante portant le même nom, y compris les rôles auxquels elle s’applique ; il requiert donc en plus le privilège DROP ROW POLICY sur cette table. Le privilège DROP ROW POLICY est requis que la politique existe déjà ou non, de sorte que l’instruction ne peut pas servir à découvrir quelles politiques existent.
Plusieurs noms et tables
Valide :Clause USING
Définit une condition de filtrage pour une table. Un utilisateur ne peut voir que les lignes pour lesquelles la condition est vraie (c’est-à-dire qu’elle renvoie une valeur non nulle). Cela revient à ajouter une conditionWHERE supplémentaire à chaque requête que l’utilisateur exécute sur la table.
Par exemple, la politique suivante restreint analyst_role aux lignes provenant de l’UE :
SELECT * FROM db.orders renvoie les mêmes lignes que le ferait SELECT * FROM db.orders WHERE region = 'EU'.
Clause TO
Dans la sectionTO, vous pouvez indiquer une liste d’utilisateurs et de rôles auxquels cette politique doit s’appliquer. Par exemple, CREATE ROW POLICY ... TO accountant, john@localhost.
Le mot-clé ALL désigne tous les utilisateurs ClickHouse, y compris l’utilisateur courant. Le mot-clé ALL EXCEPT permet d’exclure certains utilisateurs de la liste de tous les utilisateurs, par exemple, CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost
Les rôles indiqués dans la section TO, y compris ceux après ALL EXCEPT, sont comparés aux rôles activés de l’utilisateur courant (system.enabled_roles), et non à tous les rôles accordés à l’utilisateur. Par conséquent, SET ROLE peut modifier les politiques qui s’appliquent.
Clause AS
Il est possible d’avoir plusieurs politiques activées sur la même table pour un même utilisateur en même temps. Il faut donc un moyen de combiner les conditions de plusieurs politiques. Par défaut, les politiques sont combinées à l’aide de l’opérateur booléenOR. Par exemple, les politiques suivantes :
peter de voir les lignes où b=1 ou c=2.
La clause AS indique comment les politiques doivent être combinées avec d’autres politiques. Les politiques peuvent être permissives ou restrictives. Par défaut, les politiques sont permissives, ce qui signifie qu’elles sont combinées à l’aide de l’opérateur booléen OR.
Une politique peut aussi être définie comme restrictive. Les politiques restrictives sont combinées à l’aide de l’opérateur booléen AND.
Voici la formule générale :
access_control_improvements.users_without_row_policies_can_read_rows est activé par défaut. Un utilisateur auquel aucune condition ne s’applique voit donc toutes les lignes, et access_control_improvements.throw_on_unmatched_row_policies, désactivé par défaut, lève à la place une exception lorsque la table comporte des conditions et qu’aucune d’entre elles ne s’applique.
Par exemple, les politiques suivantes :
peter de voir des lignes uniquement si b=1 AND c=2.
Les politiques au niveau de la base de données sont combinées avec celles de la table.
Par exemple, les politiques suivantes :
peter de voir les lignes de table1 uniquement si b=1 AND c=2, bien que
pour toute autre table de mydb, seule la politique b=1 s’appliquerait à l’utilisateur.
Tables qui lisent les données d’autres tables
Une politique de ligne filtre les lignes au point où les données sont effectivement lues. Une tableAlias renvoie les lignes de sa table cible comme si elles lui appartenaient. Les politiques de ligne de la table cible s’appliquent donc aussi aux lectures effectuées via l’alias, conjointement avec celles de l’alias lui-même, selon un AND logique. Une table Merge applique les politiques des tables qu’elle lit. Il existe toutefois une exception : lorsqu’une table correspondante lit des données à distance, comme une table Distributed, le serveur distant traite la requête avant que la politique ne soit appliquée, car celle-ci intervient au-dessus de l’opération de lecture de la table, et non au point où les données sont lues. Une telle requête peut échouer si elle agrège les données sans sélectionner les colonnes utilisées par la politique. Elle peut aussi renvoyer moins de lignes que la politique ne l’autorise si le serveur distant applique un ORDER BY ... LIMIT à des lignes que la politique aurait masquées. Définissez plutôt la politique sur les tables locales sous-jacentes de chaque serveur distant.
Ce comportement ne s’applique pas à toutes les tables qui lisent les données d’une autre table. Une table Buffer et une vue matérialisée qui lisent les données par l’intermédiaire de leur table de destination ou de leur table cible n’héritent pas des politiques de ligne de cette table : la politique est définie à partir du schéma de la table cible et, dans le cas d’une vue avec SQL SECURITY DEFINER, elle est évaluée pour un autre utilisateur que celui qui effectue la lecture. Dans ces cas, définissez la politique sur la table que les utilisateurs interrogent réellement.
Tables Distributed et tables s’appuyant sur des serveurs distants
Une politique de ligne filtre les lignes là où les données de la table sont effectivement lues. Une table qui délègue la lecture à des serveurs distants, telle qu’une table Distributed ou un wrapper qui s’appuie sur une telle table (par exemple, une vue matérialisée avec une cibleDistributed), ne transmet que le texte de la requête aux serveurs distants et ne peut pas appliquer le filtre de la politique à la lecture distante. Pour éviter que le filtre soit ignoré silencieusement, les requêtes vers une telle table effectuées par les utilisateurs auxquels la politique s’applique sont rejetées avec une erreur ILLEGAL_PREWHERE.
Définissez plutôt la politique sur les tables locales sous-jacentes de chaque serveur distant ; elle y est appliquée lorsque la requête transmise les lit :
Tables Join
Une table Join est une table de hachage préconstruite qu’unJOIN ou un joinGet lit telle quelle ; ses lignes ne peuvent donc pas y être filtrées. Une politique définie sur une telle table, y compris une politique ON db.* portant sur l’ensemble de la base de données, filtre un simple SELECT sur la table, mais tant qu’elle s’applique, les requêtes JOIN et joinGet sur cette table échouent avec l’erreur ACCESS_DENIED.
Clause ON CLUSTER
Permet de créer des politiques sur un cluster, voir DDL distribué. C’est également une méthode pratique pour créer la politique sur les tables locales de chaque serveur du cluster.Exemples
CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost
CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira
CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin
CREATE ROW POLICY filter4 ON mydb.* USING 1 TO admin