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

Firebase vous fournit 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.

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

  • Ingère une source Règles: un ensemble de règles, généralement un fichier de code contenant des instructions Firebase Règles de sécurité.
  • Magasins ingérés comme source un ensemble de règles immuables.
  • Pistes de chaque déploiement ruleset dans un communiqué. 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 capacité d'exécuter des tests syntaxiques et sémantiques d'un ensemble de règles.

Utiliser l'interface de ligne de commande Firebase

Avec l' Firebase CLI , vous pouvez télécharger des sources locales et des communiqués de déploiement. L'émulateur local Suite CLI Firebase vous permet d' effectuer des essais complets des sources locales.

L'utilisation de la CLI vous permet de garder 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 en utilisant la CLI Firebase, vous créez un .rules fichier de configuration dans votre répertoire de 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

Modifier et mettre à jour vos règles

Modifier votre source de règles directement dans le .rules fichier de configuration. 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 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é pour chaque émulateur effectue à la fois 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 l' émulateur local Suite pour tester vos mises à jour localement et confirmer que les règles de votre application présentent le comportement que vous voulez.

Déployez vos mises à jour

Une fois que vous avez mis à jour et testé vos règles, déployez les sources en production. Utilisez les commandes suivantes pour déployer de manière sélective vos règles seules ou les déployer dans le cadre de votre processus de déploiement normal.

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

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 des règles sources et de les déployer en versions de la console Firebase. Le test est effectué comme Syntactic vous modifier dans l'interface utilisateur console Firebase, et le test Symantic est disponible à l' aide du Playground Règles.

Modifier et mettre à jour vos règles

  1. Ouvrez la console Firebase et sélectionnez votre projet.
  2. Ensuite, sélectionnez Base de données en temps réel, Nuage Firestore ou Stockage de la navigation du produit, puis cliquez sur Règles pour accéder à l'éditeur 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 de projet et les ressources de stockage, directement dans la console Firebase, en utilisant le Playground Règles . Ouvrez le règlement écran Aire de jeu dans l'éditeur Règles, modifier 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 satisfait que vos mises à jour sont ce que vous attendez, cliquez sur Publier.

Utiliser le SDK d'administration

Vous pouvez utiliser le SDK Admin pour rulesets 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 gardant la sécurité à l'esprit, 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 prennent plusieurs minutes pour 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 repose 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, qui est conçue pour réduire les conditions de concurrence malgré les mises à jour fréquentes.

Notez également ces limites :

  • Les règles doivent être inférieures à 256 Kio de texte encodé en UTF-8 lorsqu'elles sont sérialisées.
  • Un projet peut avoir au plus 2500 ensembles de règles déployés au total. Une fois cette limite atteinte, vous devez supprimer certains anciens jeux 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 le SDK Admin peut comprendre 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 pour combiner ces étapes en un seul appel d'API pour les règles de sécurité Cloud Storage et Cloud Firestore. Par example:

    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 example:

    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 en temps réel la base de données rulesets avec le SDK Admin, utilisez les getRules() et setRules() méthodes 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 aider à gérer les grands ensembles de règles, le Admin SDK vous permet de lister toutes les règles existantes avec admin.securityRules().listRulesetMetadata . Par example:

    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 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 rulesets déployés pendant 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, mais vous souhaiterez peut-être gérer et déployer des 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é.

Sachez que les versions des règles de sécurité Firebase prennent plusieurs minutes pour 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 repose immédiatement sur des règles dont le déploiement n'est pas encore terminé.

Notez également ces limites :

  • Les règles doivent être inférieures à 256 Kio de texte encodé en UTF-8 lorsqu'elles sont sérialisées.
  • Un projet peut avoir au plus 2500 ensembles de règles déployés au total. Une fois cette limite atteinte, vous devez supprimer certains anciens jeux 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 avec REST

Les exemples de cette section utilisent des règles de stockage, bien qu'elles s'appliquent également aux règles Cloud Firestore.

Les exemples utilisent également cURL pour effectuer des appels d'API. Les étapes de configuration et de transmission des jetons d'authentification sont omises. Vous pouvez expérimenter avec cette API en utilisant l'API explorateur 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 un fichier de règles sources
  2. Créer un ensemble de règles
  3. Publier (déployer) le nouvel ensemble de règles

Supposons que vous travaillez sur votre secure_commerce projet Firebase et que vous souhaitez déployer verrouillés règles Cloud Storage. Vous pouvez mettre en œuvre ces règles dans un storage.rules fichier.

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

Maintenant, générez une empreinte encodée en base64 pour ce fichier. Vous pouvez ensuite utiliser la source dans ce fichier pour remplir la charge utile nécessaire pour créer un ensemble de règles avec le projects.rulesets.create appel REST. Ici, nous utilisons le cat commande pour insérer le contenu de storage.rules dans la charge utile REST.

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

L'API renvoie une réponse de validation et un nom de ruleset, par exemple des projects/secure_commerce/rulesets/uuid123 . 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/prod/v23   "  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

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

La base de données en temps réel fournit sa propre interface REST pour la gestion des règles. Voir Gestion Firebase en temps réel les règles de base de données via REST .

Gérer les ensembles de règles avec REST

Pour aider à gérer les 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 :

  • liste, obtenir et supprimer rulesets
  • liste, obtenir, et les règles de suppression des rejets

Pour les très grands déploiements qui atteignent la limite de l'ensemble de règles 2500 au fil du temps, vous pouvez créer une logique pour supprimer les règles les plus anciennes sur un cycle de temps fixe. Par exemple, pour supprimer tous rulesets déployés pendant plus de 30 jours, vous pouvez appeler la projects.rulesets.list méthode, analyser la liste JSON des Ruleset objets sur leurs createTime clés, puis appelez project.rulesets.delete sur les rulesets par correspondants 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 TestSuite objet JSON pour représenter un ensemble de TestCase objets
  2. Présentation de la TestSuite
  3. Retour Parsing TestResult objets

Définissons un TestSuite objet avec un seul TestCase dans un testcase.json fichier. 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'achèvement du rapport de test, en utilisant la valeur « FULL » pour indiquer les résultats de toutes les expressions du langage Rules qui 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"}}}
            }
          ]
      }
    ]
  }
}

On peut alors soumettre cette TestSuite pour évalution avec la projects.test méthode.

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

Le retour TestReport (contenant Test de réussite / état des défauts, des listes de messages de débogage, les listes d'expressions Règles visitées et leurs rapports d'évaluation) confirmerait avec le statut RÉUSSITE que l' accès est bien permis.