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

Firebase vous fournit plusieurs outils pour gérer vos Rules, chacun d'entre eux utiles dans des cas particuliers, chacune utilisant le même backend Firebase API de gestion des règles de sécurité.

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

  • Ingère une source de règles: un ensemble de règles (généralement un fichier de code contenant Firebase Security Rules.
  • Stocke la source ingérée sous la forme d'un ensemble de règles immuable.
  • Permet de suivre 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 pour évaluer chaque requête d'une ressource sécurisée.
  • Permet d'exécuter des tests syntaxiques et sémantiques d'un ensemble de règles.

Utiliser la CLI Firebase

La CLI Firebase vous permet d'effectuer les opérations suivantes : importer des sources locales et déployer des versions. La CLI Firebase Local Emulator Suite vous permet d'effectuer des tests locaux complets des sources.

L'utilisation de la CLI vous permet de garder vos règles sous le contrôle des versions avec votre le code d'application et les règles de déploiement dans le 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 les éléments suivants : pour commencer à configurer votre projet Firebase:

Cloud Firestore

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

Realtime Database

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

Cloud Storage

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

Modifier et mettre à 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 répercutées dans la Firebase ou que vous effectuez régulièrement des mises à jour à l'aide des la console Firebase ou la CLI Firebase. Sinon, vous risquez d'écraser les mises à jour effectuées dans la console Firebase.

Tester vos mises à jour

Local Emulator Suite 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 exécute à la fois et l'évaluation sémantique des règles, dépassant ainsi les tests syntaxiques de l'API de gestion des règles de sécurité.

Si vous travaillez avec la CLI, la suite est un excellent outil pour Firebase Security Rules tests. Utilisez Local Emulator Suite pour tester vos mises à jour localement et vérifier que les Rules de votre application présentent le comportement souhaité.

Déployer vos mises à jour

Une fois que vous avez mis à jour et testé votre Rules, déployez les sources sur en production.

Pour Cloud Firestore Security Rules, associez .rules fichiers à vos fichiers par défaut et d'autres bases de données nommées en examinant et en mettant à jour fichier firebase.json.

Utilisez les commandes suivantes pour déployer de manière sélective votre Rules seul ou et les déployer dans le cadre du 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>

Realtime Database

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

Cloud Storage

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

Utiliser la console Firebase

Vous pouvez également modifier les sources Rules et les déployer en tant que versions de la console Firebase. Les tests syntaxiques sont effectués lorsque vous modifiez le fichier l'interface utilisateur de la console Firebase, et les tests sémantiques sont disponibles à l'aide de Rules Playground.

Modifier et mettre à jour vos règles

  1. Ouvrez la console Firebase et sélectionnez votre projet.
  2. Sélectionnez ensuite Realtime Database, Cloud Firestore ou Stockage dans dans le menu de navigation du produit, puis cliquez sur Règles pour éditeur Rules.
  3. Modifiez vos règles directement dans l'éditeur.

Tester vos mises à jour

En plus de tester la syntaxe dans l'interface utilisateur de l'éditeur, vous pouvez tester la sémantique Comportement de Rules, à l'aide des ressources de base de données et de stockage de votre projet directement dans la console Firebase, à l'aide de la Rules Playground. Ouvrez l'écran Rules Playground (Espace de test dédié aux règles) dans l'éditeur Rules, modifiez les paramètres, puis cliquez sur Run (Exécuter). Recherchez le message de confirmation en haut de l'éditeur.

Déployer vos mises à jour

Lorsque vous êtes satisfait de vos modifications, cliquez sur Publier.

Utiliser le SDK Admin

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

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

Lorsque vous mettez à jour des règles de manière programmatique, il est très important d'éviter d'apporter des modifications involontaires au contrôle d'accès de votre application. Écrivez votre code Admin SDK en privilégiant la sécurité, en particulier lorsque vous mettez à jour ou déployez des règles.

Autre point important à garder à l'esprit : les versions Firebase Security Rules ont une de plusieurs minutes. Lorsque vous utilisez Admin SDK pour déployer règles, assurez-vous d'éviter les conditions de concurrence dans lesquelles votre application s'appuie immédiatement pour les règles dont le déploiement n'est pas encore terminé. Si votre cas d'utilisation nécessite de mettre à jour fréquemment les règles de contrôle des accès, envisagez des solutions utilisant Cloud Firestore, qui est conçu pour réduire les conditions de concurrence malgré les mises à jour fréquentes.

Notez également les limites suivantes:

  • Les règles doivent être inférieures à 256 Kio de texte encodé au format UTF-8 lorsqu'elles sont sérialisées.
  • Un projet ne peut pas comporter plus de 2 500 ensembles de règles déployés au total. Une fois que cette limite est vous devez supprimer d'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 workflow type de gestion des règles de sécurité avec Admin SDK peut inclure les éléments suivants : trois étapes distinctes:

  1. Créer une source pour le 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 Règles de sécurité Cloud Storage et Cloud Firestore. 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 le ensemble de règles et le déployer séparément pour un contrôle plus précis de ces événements. Exemple :

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

Mettre à jour Realtime Database d'ensembles de règles

Pour mettre à jour les règles Realtime Database avec Admin SDK, 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.

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 des ensembles de règles

Pour faciliter la gestion d'ensembles de règles volumineux, le Admin SDK vous permet de répertorier toutes les règles existantes avec admin.securityRules().listRulesetMetadata. 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 très grands déploiements qui atteignent la limite de 2 500 ensembles de règles au fil du temps, vous pouvez Créez une logique pour supprimer les règles les plus anciennes selon un cycle fixe. Par exemple, pour supprimer tous les jeux 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 workflows, y compris à la gestion des Firebase Security Rules pour plusieurs bases de données Cloud Firestore dans votre projet. Toutefois, vous pouvez gérer et déployer des Firebase Security Rules à l'aide de l'API de gestion elle-même. L'API de gestion vous offre la plus grande flexibilité.

Prenez également note des limites suivantes:

  • Les règles doivent être inférieures à 256 Kio de texte encodé au format UTF-8 lorsqu'elles sont sérialisées.
  • Un projet ne peut pas comporter plus de 2 500 ensembles de règles déployés au total. Une fois que cette limite est vous devez supprimer d'anciens ensembles de règles avant d'en créer de nouveaux.

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

Les exemples de cette section utilisent le Rules Firestore, bien qu'ils s'appliquent à Cloud Storage Rules aussi.

Les exemples utilisent également cURL pour effectuer des appels d'API. Procédure de configuration et de transmission les jetons d'authentification sont omis. Vous pouvez tester cette API à l'aide de l'explorateur d'API intégré à la documentation de référence.

Voici les étapes types de création et de déploiement d'un ensemble de règles à l'aide de l'API de gestion:

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

Créer une source

Supposons que vous travaillez sur votre projet Firebase secure_commerce et que vous souhaitez pour déployer des Cloud Firestore Rules verrouillés dans une base de données de votre nommé east_store.

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

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

Créer un ensemble de règles

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

Pour le suivi, afin de 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 exemple projects/secure_commerce/rulesets/uuid123

Libérer (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 un de sortie.

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 l'exécution complète des versions Firebase Security Rules peut prendre plusieurs minutes de se propager. Lorsque vous utilisez l'API REST de gestion pour le déploiement, assurez-vous d'éviter la concurrence conditions selon lesquelles votre application s'appuie immédiatement sur des règles dont le déploiement n'est pas terminé.

Mettre à jour Realtime Database ensembles de règles avec REST

Realtime Database fournit sa propre interface REST pour gérer Rules. Voir Gestion de Firebase Realtime Database Rules via REST.

Gérer les jeux de règles avec REST

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

  • Lister, récupérer et supprimer des ensembles de règles
  • liste, obtention et suppression des versions

Pour les déploiements très volumineux qui atteignent la limite de 2 500 règles au fil du temps, vous pouvez créer une logique pour supprimer les règles les plus anciennes sur un cycle temporel fixe. Par exemple, pour supprimer tous les ensembles de règles déployés depuis plus de 30 jours, vous pouvez appeler la méthode 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.

Tester vos mises à jour avec REST

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

Ce composant de l'API permet de tester les éléments suivants:

  1. Définir un objet JSON TestSuite pour représenter un ensemble d'objets TestCase
  2. Envoyer la TestSuite
  3. L'analyse a renvoyé des objets TestResult.

Définissons un objet TestSuite avec un seul TestCase dans une testcase.json. Dans cet exemple, nous transmettons Rules le langage source intégré à 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 le client requête par rapport à laquelle l'ensemble de règles doit être testé. Vous pouvez également spécifier remplir le rapport de test, en utilisant la valeur "FULL" pour indiquer les résultats Rules expressions de langue doivent être incluses dans le rapport, y compris expressions qui ne correspondent pas à la requête.

 {
  "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 envoyer ce TestSuite pour évaluation avec projects.test .

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

Le résultat TestReport renvoyé (contenant l'état RÉUSSITE/ÉCHEC du test, les messages de débogage, les listes des expressions de règles visitées et leurs rapports d'évaluation) confirmerait avec l’état SUCCÈS que l’accès est correctement autorisé.

Gérer les autorisations pour Cloud Storage Security Rules interservices

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

Si vous décidez de désactiver ce type de sécurité multiservice:

  1. Avant de désactiver cette fonctionnalité, modifiez vos règles, supprimez toutes Les instructions qui utilisent les fonctions Rules pour accéder à Cloud Firestore. Sinon, une fois la fonctionnalité désactivée, les évaluations Rules peut entraîner l'échec de vos requêtes de stockage.

  2. Utilisez la page IAM de la console Google Cloud pour supprimer la règle Agent de service Firestore des règles" en suivant le guide Cloud révocation de rôles

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