Gérer et déployer les règles de sécurité Firebase

Firebase vous propose plusieurs outils pour gérer vos règles, chacun utile dans des cas particuliers, et chacun utilisant la même API de gestion des règles de sécurité Firebase backend.

Quel que soit l'outil utilisé pour l'invoquer, l'API de gestion :

  • Ingère une source de règles : un ensemble de règles, généralement un fichier de code contenant des instructions de règles de sécurité Firebase.
  • Stocke la source ingérée sous la forme d’un ensemble de règles immuables.
  • Suit le déploiement de chaque ensemble de règles dans une version . Les services compatibles avec les règles de sécurité Firebase recherchent la version d'un projet afin d'évaluer chaque demande de ressource sécurisée.
  • Fournit la possibilité d’exécuter des tests syntaxiques et sémantiques d’un ensemble de règles.

Utiliser la CLI Firebase

Avec la CLI Firebase , vous pouvez télécharger des sources locales et déployer des versions . La suite d'émulateurs locaux Firebase de la CLI vous permet d'effectuer des tests locaux complets des sources .

L'utilisation de la CLI vous permet de conserver vos règles sous contrôle de version avec votre code d'application et de déployer des règles dans le cadre de votre processus de déploiement existant.

Générer un fichier de configuration

Lorsque vous configurez votre projet Firebase à l'aide de la CLI Firebase, vous créez un fichier de configuration .rules dans le répertoire de votre projet. Utilisez la commande suivante pour commencer à configurer votre projet Firebase :

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Base de données en temps réel

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Stockage en ligne

// Set up Storage in your project directory, creates a .rules file
firebase init storage

Modifiez et mettez à jour vos règles

Modifiez votre source de règles directement dans le fichier de configuration .rules .

Assurez-vous que toutes les modifications que vous apportez dans la CLI Firebase sont reflétées dans la console Firebase ou que vous effectuez systématiquement des mises à jour à l'aide de la console Firebase ou de la CLI Firebase. Sinon, vous risquez d'écraser toutes les mises à jour effectuées dans la console Firebase.

Testez vos mises à jour

La suite d'émulateurs locaux fournit des émulateurs pour tous les produits compatibles avec les règles de sécurité. Le moteur de règles de sécurité de chaque émulateur effectue une évaluation syntaxique et sémantique des règles, dépassant ainsi les tests syntaxiques proposés par l'API de gestion des règles de sécurité.

Si vous travaillez avec la CLI, la Suite est un excellent outil pour tester les règles de sécurité Firebase. Utilisez Local Emulator Suite pour tester vos mises à jour localement et confirmer que les règles de votre application présentent le comportement souhaité.

Déployez vos mises à jour

Une fois que vous avez mis à jour et testé vos règles, déployez les sources en production.

Pour les règles de sécurité Cloud Firestore, associez les fichiers .rules à vos bases de données nommées par défaut et supplémentaires en examinant et en mettant à jour votre fichier firebase.json .

Utilisez les commandes suivantes pour déployer sélectivement vos règles seules ou les déployer dans le cadre de votre processus de déploiement normal.

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

Base de données en temps réel

// Deploy your .rules file
firebase deploy --only database

Stockage en ligne

// Deploy your .rules file
firebase deploy --only storage

Utiliser la console Firebase

Vous pouvez également modifier les sources de règles et les déployer en tant que versions à partir de la console Firebase. Les tests syntaxiques sont effectués au fur et à mesure que vous modifiez dans l'interface utilisateur de la console Firebase, et les tests sémantiques sont disponibles à l'aide de Rules Playground.

Modifiez et mettez à jour vos règles

  1. Ouvrez la console Firebase et sélectionnez votre projet.
  2. Ensuite, sélectionnez Realtime Database , Cloud Firestore ou Storage dans la navigation du produit, puis cliquez sur Rules pour accéder à l'éditeur de règles.
  3. Modifiez vos règles directement dans l'éditeur.

Testez vos mises à jour

En plus de tester la syntaxe dans l'interface utilisateur de l'éditeur, vous pouvez tester le comportement des règles sémantiques, en utilisant la base de données et les ressources de stockage de votre projet, directement dans la console Firebase, à l'aide de Rules Playground . Ouvrez l'écran Rules Playground dans l'éditeur de règles, modifiez les paramètres et cliquez sur Exécuter . Recherchez le message de confirmation en haut de l'éditeur.

Déployez vos mises à jour

Une fois que vous êtes convaincu que vos mises à jour correspondent à vos attentes, cliquez sur Publier .

Utiliser le SDK d'administration

Vous pouvez utiliser le SDK Admin pour les ensembles de règles Node.js. Avec cet accès programmatique, vous pouvez :

  • Implémentez des outils personnalisés, des scripts, des tableaux de bord et des pipelines CI/CD pour gérer les règles.
  • Gérez plus facilement les règles sur plusieurs projets Firebase.

Lors de la mise à jour des règles par programmation, il est très important d’éviter d’apporter des modifications involontaires au contrôle d’accès de votre application. Écrivez votre code SDK Admin en pensant avant tout à la sécurité, en particulier lors de la mise à jour ou du déploiement de règles.

Une autre chose importante à garder à l'esprit est que les versions des règles de sécurité Firebase mettent plusieurs minutes à se propager complètement. Lorsque vous utilisez le SDK Admin pour déployer des règles, veillez à éviter les conditions de concurrence dans lesquelles votre application s'appuie immédiatement sur des règles dont le déploiement n'est pas encore terminé. Si votre cas d'utilisation nécessite des mises à jour fréquentes des règles de contrôle d'accès, envisagez des solutions utilisant Cloud Firestore, conçu pour réduire les conditions de concurrence malgré des mises à jour fréquentes.

Notez également ces limites :

  • Les règles doivent être inférieures à 256 Ko de texte codé en UTF-8 une fois sérialisées.
  • Un projet peut avoir au maximum 2 500 ensembles de règles déployés au total. Une fois cette limite atteinte, vous devez supprimer certains anciens ensembles de règles avant d'en créer de nouveaux.

Créer et déployer des ensembles de règles Cloud Storage ou Cloud Firestore

Un flux de travail typique pour la gestion des règles de sécurité avec le SDK Admin peut inclure trois étapes distinctes :

  1. Créer une source de fichier de règles (facultatif)
  2. Créer un ensemble de règles
  3. Publier ou déployer le nouvel ensemble de règles

Le SDK fournit une méthode permettant de combiner ces étapes en un seul appel d'API pour les règles de sécurité Cloud Storage et Cloud Firestore. Par exemple:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

Ce même modèle fonctionne pour les règles Cloud Storage avec releaseFirestoreRulesetFromSource() .

Vous pouvez également créer le fichier de règles en tant qu'objet en mémoire, créer l'ensemble de règles et déployer l'ensemble de règles séparément pour un contrôle plus étroit de ces événements. Par exemple:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

Mettre à jour les ensembles de règles de la base de données en temps réel

Pour mettre à jour les ensembles de règles Realtime Database avec le SDK Admin, utilisez les méthodes getRules() et setRules() de admin.database . Vous pouvez récupérer des ensembles de règles au format JSON ou sous forme de chaîne avec des commentaires inclus.

Pour mettre à jour un ensemble de règles :

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

Gérer les ensembles de règles

Pour vous aider à gérer de grands ensembles de règles, le SDK Admin vous permet de répertorier toutes les règles existantes avec admin.securityRules().listRulesetMetadata . Par exemple:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

Pour les déploiements de très grande envergure qui atteignent la limite de 2 500 ensembles de règles au fil du temps, vous pouvez créer une logique pour supprimer les règles les plus anciennes selon un cycle de temps fixe. Par exemple, pour supprimer tous les ensembles de règles déployés depuis plus de 30 jours :

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

Utiliser l'API REST

Les outils décrits ci-dessus sont bien adaptés à divers flux de travail, y compris la gestion des règles de sécurité Firebase pour plusieurs bases de données Cloud Firestore dans votre projet, mais vous souhaiterez peut-être gérer et déployer les règles de sécurité Firebase à l'aide de l'API de gestion elle-même. L'API de gestion vous offre la plus grande flexibilité.

Notez également ces limites :

  • Les règles doivent être inférieures à 256 Ko de texte codé en UTF-8 une fois sérialisées.
  • Un projet peut avoir au maximum 2 500 ensembles de règles déployés au total. Une fois cette limite atteinte, vous devez supprimer certains anciens ensembles de règles avant d'en créer de nouveaux.

Créez et déployez des ensembles de règles Cloud Firestore ou Cloud Storage avec REST

Les exemples de cette section utilisent les règles Firestore, bien qu'ils s'appliquent également aux règles de stockage cloud.

Les exemples utilisent également cURL pour effectuer des appels API. Les étapes de configuration et de transmission des jetons d'authentification sont omises. Vous pouvez expérimenter cette API à l'aide de l'API Explorer intégré à la documentation de référence.

Les étapes typiques de création et de déploiement d'un ensemble de règles à l'aide de l'API de gestion sont :

  1. Créer des sources de fichiers de règles
  2. Créer un ensemble de règles
  3. Libérez (déployez) le nouvel ensemble de règles.

Créer une source

Supposons que vous travaillez sur votre projet Firebase secure_commerce et que vous souhaitez déployer des règles Cloud Firestore verrouillées dans une base de données de votre projet nommée east_store .

Vous pouvez implémenter ces règles dans un fichier firestore.rules .

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Créer un ensemble de règles

Maintenant, générez une empreinte digitale codée en base64 pour ce fichier. Vous pouvez ensuite utiliser la source de ce fichier pour remplir la charge utile nécessaire à la création d'un ensemble de règles avec l'appel projects.rulesets.create . Ici, utilisez la commande cat pour insérer le contenu de firestore.rules dans la charge utile REST.

Pour le suivi, pour l'associer à votre base de données east_store , définissez attachment_point sur east_store .

curl -X POST -d '{
  "source": {
    {
      "files": [
        {
          "content": "' $(cat storage.rules) '",
          "name": "firestore.rules",
          "fingerprint": <sha fingerprint>
        },
      "attachment_point": "firestore.googleapis.com/databases/east_store"
      ]
    }
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

L'API renvoie une réponse de validation et un nom d'ensemble de règles, par projects/secure_commerce/rulesets/uuid123 .

Publier (déployer) un ensemble de règles

Si l'ensemble de règles est valide, la dernière étape consiste à déployer le nouvel ensemble de règles dans une version nommée.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

Sachez que les versions des règles de sécurité Firebase mettent plusieurs minutes à se propager complètement. Lorsque vous utilisez l'API REST de gestion pour le déploiement, veillez à éviter les conditions de concurrence dans lesquelles votre application s'appuie immédiatement sur des règles dont le déploiement n'est pas encore terminé.

Mettre à jour les ensembles de règles de base de données en temps réel avec REST

Realtime Database fournit sa propre interface REST pour gérer les règles. Consultez Gestion des règles de base de données en temps réel Firebase via REST .

Gérer les ensembles de règles avec REST

Pour faciliter la gestion des déploiements de règles à grande échelle, en plus d'une méthode REST pour créer des ensembles de règles et des versions, l'API de gestion fournit des méthodes pour :

  • lister, obtenir et supprimer des ensembles de règles
  • répertorier, obtenir et supprimer des versions de règles

Pour les déploiements de très grande envergure qui atteignent la limite de 2 500 ensembles de règles au fil du temps, vous pouvez créer une logique pour supprimer les règles les plus anciennes selon un cycle de temps fixe. Par exemple, pour supprimer tous les ensembles de règles déployés pendant plus de 30 jours, vous pouvez appeler la projects.rulesets.list , analyser la liste JSON des objets Ruleset sur leurs clés createTime , puis appeler project.rulesets.delete sur les ensembles de règles correspondants par ruleset_id .

Testez vos mises à jour avec REST

Enfin, l'API de gestion vous permet d'exécuter des tests syntaxiques et sémantiques sur les ressources Cloud Firestore et Cloud Storage dans vos projets de production.

Les tests avec ce composant de l'API consistent à :

  1. Définition d'un objet TestSuite JSON pour représenter un ensemble d'objets TestCase
  2. Soumission de la TestSuite
  3. L'analyse des objets TestResult renvoyés

Définissons un objet TestSuite avec un seul TestCase dans un fichier testcase.json . Dans cet exemple, nous transmettons la source du langage Rules en ligne avec la charge utile REST, ainsi que la suite de tests à exécuter sur ces règles. Nous spécifions une attente d'évaluation des règles et la demande du client par rapport à laquelle l'ensemble de règles doit être testé. Vous pouvez également spécifier le degré d'exhaustivité du rapport de test, en utilisant la valeur « COMPLET » pour indiquer que les résultats de toutes les expressions du langage de règles doivent être incluses dans le rapport, y compris les expressions qui ne correspondent pas à la demande.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

Nous pouvons ensuite soumettre cette TestSuite pour évaluation avec la projects.test .

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

Le TestReport renvoyé (contenant le statut SUCCESS/FAILURE du test, les listes de messages de débogage, les listes des expressions de règles visitées et leurs rapports d'évaluation) confirmerait avec le statut SUCCESS que l'accès est correctement autorisé.

Gérer les autorisations pour les règles de sécurité Cloud Storage interservices

Si vous créez des règles de sécurité Cloud Storage qui utilisent le contenu du document Cloud Firestore pour évaluer les conditions de sécurité , vous serez invité dans la console Firebase ou la CLI Firebase pour activer les autorisations permettant de connecter les deux produits.

Si vous décidez de désactiver cette sécurité interservices :

  1. Tout d'abord, avant de désactiver la fonctionnalité, modifiez vos règles, en supprimant toutes les instructions qui utilisent les fonctions de règles pour accéder à Cloud Firestore. Sinon, une fois la fonctionnalité désactivée, les évaluations des règles entraîneront l'échec de vos demandes de stockage.

  2. Utilisez la page IAM de Google Cloud Console pour supprimer le rôle « Firebase Rules Firestore Service Agent » en suivant le guide Cloud pour la révocation des rôles .

Vous serez invité à réactiver la fonctionnalité la prochaine fois que vous enregistrerez des règles interservices à partir de la CLI Firebase ou de la console Firebase.