Règles de sécurité pour les opérations de pipeline

Les règles d'opérations de pipeline vous permettent de faire correspondre les fonctionnalités de filtrage du moteur de règles existant. Bien que les opérations de pipeline offrent un ensemble complet de fonctionnalités, le moteur de règles est limité à la reconnaissance de filtres simples pour garantir la satisfaction et la sécurité des requêtes.

Édition et mode requis

Ce document s'applique à l'édition Enterprise de Firestore en mode natif.

Expressions de filtre acceptées

Pour qu'une requête soit limitée par vos règles, elle doit utiliser des opérateurs de comparaison standards par rapport à des constantes. Les types de filtres suivants sont reconnus par le moteur de règles :

  • Égalité et inégalité : eq, neq.
  • Comparaisons : gt, gte, lt, lte.
  • Abonnement : in, arrayContains.

Voici quelques exemples :

  • where(eq("foo", 2))
  • where(lt("foo", 2))
  • documents("/user/1", "/user/2").where(...)

Propriétés de la requête

Vous pouvez continuer à utiliser l'objet request pour valider l'authentification et le contexte de la requête, bien que certaines propriétés disponibles dans les requêtes standards ne soient pas compatibles avec les pipelines.

Propriétés compatibles

Le nouveau moteur continue de prendre en charge les propriétés suivantes :

  • request.auth : accédez à l'UID de l'utilisateur et aux données du jeton.
  • request.method : identifie l'opération (par exemple, get, list).
  • request.path : chemin d'accès de la ressource consultée.
  • request.time : code temporel côté serveur de la requête.

Propriétés non compatibles

Les propriétés request.query telles que limit, offset et orderBy ne sont pas compatibles avec les vérifications des règles Pipelines en raison de la complexité de la détermination de ces valeurs dans les requêtes multi-étapes.

Gestion et autorisations des étapes de pipeline

Il existe différentes étapes de pipeline qui correspondent à des opérations précises dans les règles de sécurité :

  • Autorisations allow list : déclenchées par les étapes collection(), collectionGroup() et database().
  • Autorisations allow get : déclenchées par l'étape documents(), qui est traitée de la même manière qu'une opération get par lot.
  • Autorisations allow create : déclenchées par les étapes insert() et upsert() lors de la création de documents.
  • Autorisations allow update : déclenchées par les étapes update() et upsert() lors de la mise à jour de documents existants.
  • Autorisations allow delete : déclenchées par les étapes delete().
  • Autorisations allow write : s'appliquent à toutes les opérations LMD (insert(), update(), upsert() et delete()).
  • Étapes de modification des champs : les règles ne s'appliquent qu'aux données stockées, et non aux valeurs dérivées. Si un pipeline inclut des étapes qui modifient des champs (par exemple, AddFields, ReplaceWith, Select), le moteur de règles cesse d'appliquer les contraintes de filtre après l'étape en question.
  • Étape des littéraux : l'étape literals() ne lit pas la base de données, mais peut entraîner des coûts. Pour éviter tout abus, elle doit être associée à une autre étape (comme collection()) qui peut être validée par des règles.

Étapes du langage de manipulation de données (LMD) et règles de sécurité

Lors de l'exécution d'étapes du langage de manipulation de données (LMD) (insert(), update(), upsert() et delete()), les règles de sécurité évaluent les autorisations différemment des requêtes de lecture :

  • Évaluation des règles par document : contrairement aux pipelines de lecture, qui nécessitent des expressions de filtre en amont pour limiter la requête au moment de la planification, les opérations LMD évaluent les règles de sécurité par rapport à chaque mutation de document individuelle.
  • Variables de règle :
    • request.resource : contient les données de document proposées pour les opérations insert(), update() et upsert().
    • resource : contient les données du document actuel stockées dans la base de données avant modification (disponible pour update(), delete() et upsert() des documents existants).

Limites du système et comportement d'exécution avec le LMD

Lorsque vous exécutez des opérations LMD avec des règles de sécurité, tenez compte des limites du système et des comportements d'exécution suivants :

La limite de 20 recherches sur get() et exists()

Les règles de sécurité Firebase autorisent un maximum de 20 recherches de documents (get() ou exists()) sur l'ensemble d'une requête.

Lorsqu'un pipeline LMD s'exécute en dehors d'une transaction explicite, les documents sont traités par lots. Étant donné que chaque lot s'exécute dans sa propre transaction et que les documents peuvent être modifiés simultanément entre les lots, les règles de sécurité et les recherches de documents sont réévaluées pour chaque lot d'écriture.

Même si vos règles de sécurité évaluent un seul document statique, par exemple, pour vérifier si un utilisateur est un administrateur :

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /posts/{postId} {
      allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
    }
  }
}

Chaque lot d'écriture de documents effectue une recherche. Par conséquent, après l'écriture de tous les documents possibles, la limite de 20 recherches pour la requête est atteinte et le pipeline échoue avec une erreur PERMISSION_DENIED. De plus, chaque recherche effectuée par lot d'écriture entraîne sa propre facturation de lecture.

Réussite partielle et PERMISSION_DENIED

Lorsqu'elles sont exécutées en dehors d'une transaction, les opérations LMD valident les écritures par lots séquentiels. Si un lot échoue (soit parce qu'un document ne remplit pas une condition de règle, soit parce que la limite de 20 recherches est dépassée), le pipeline s'arrête et renvoie une erreur PERMISSION_DENIED.

Toutefois, les lots qui ont déjà été validés ne sont pas annulés. La base de données reste dans un état partiellement mis à jour. Étant donné que le client reçoit une erreur sans liste de documents modifiés, vous devez interroger vos données pour inspecter les écritures ayant réussi.

Diagnostiquer les échecs de règles avec Cloud Audit Logs

Pour des raisons de sécurité, les erreurs PERMISSION_DENIED visibles par le client ne révèlent pas quelle condition de règle de sécurité a échoué ni si la limite de 20 recherches a été atteinte.

Pour diagnostiquer les échecs d'évaluation des règles, les administrateurs de projet peuvent inspecter Cloud Audit Logs dans la console Google Cloud (sous Firestore > Surveillance ou dans l'explorateur de journaux) pour afficher les entréesEvaluationError détaillées.