Gestisci e distribuisci le regole di sicurezza Firebase

Firebase ti fornisce diversi strumenti per gestire le tue regole, ognuno utile in casi particolari e ognuno utilizzando la stessa API di gestione delle regole di sicurezza Firebase backend.

Indipendentemente dallo strumento utilizzato per invocarlo, l'API di gestione:

  • Importa un'origine regole: un insieme di regole, in genere un file di codice contenente le istruzioni delle regole di sicurezza Firebase.
  • Memorizza l'origine importata come un set di regole immutabile.
  • Tiene traccia della distribuzione di ogni set di regole in una versione . I servizi abilitati alle regole di sicurezza Firebase ricercano la versione di un progetto per valutare ogni richiesta di una risorsa protetta.
  • Fornisce la capacità di eseguire test sintattici e semantici di un set di regole.

Utilizza la CLI di Firebase

Con la CLI Firebase , puoi caricare origini locali e distribuire versioni . La suite di emulazione locale Firebase della CLI ti consente di eseguire test locali completi dei sorgenti .

L'utilizzo della CLI ti consente di mantenere le regole sotto il controllo della versione con il codice dell'applicazione e di distribuire le regole come parte del processo di distribuzione esistente.

Generare un file di configurazione

Quando configuri il tuo progetto Firebase utilizzando la CLI Firebase, crei un file di configurazione .rules nella directory del progetto. Utilizza il seguente comando per iniziare a configurare il tuo progetto Firebase:

Cloud Fire Store

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

Banca dati in tempo reale

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

Archiviazione nel cloud

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

Modifica e aggiorna le tue regole

Modifica l'origine delle regole direttamente nel file di configurazione .rules .

Assicurati che tutte le modifiche apportate nella CLI Firebase si riflettano nella console Firebase o che effettui costantemente aggiornamenti utilizzando la console Firebase o la CLI Firebase. Altrimenti, potresti sovrascrivere eventuali aggiornamenti apportati nella console Firebase.

Metti alla prova i tuoi aggiornamenti

Local Emulator Suite fornisce emulatori per tutti i prodotti abilitati per le regole di sicurezza. Il motore delle regole di sicurezza per ciascun emulatore esegue la valutazione sia sintattica che semantica delle regole, superando così i test sintattici offerti dall'API di gestione delle regole di sicurezza.

Se lavori con la CLI, la Suite è uno strumento eccellente per testare le regole di sicurezza Firebase. Utilizza Local Emulator Suite per testare i tuoi aggiornamenti localmente e verificare che le regole della tua app mostrino il comportamento desiderato.

Distribuisci i tuoi aggiornamenti

Dopo aver aggiornato e testato le tue regole, distribuisci i sorgenti in produzione.

Per le regole di sicurezza di Cloud Firestore, associa i file .rules ai database denominati predefiniti e aggiuntivi esaminando e aggiornando il file firebase.json .

Utilizza i seguenti comandi per distribuire selettivamente le tue regole da sole o distribuirle come parte del normale processo di distribuzione.

Cloud Fire Store

// 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>

Banca dati in tempo reale

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

Archiviazione nel cloud

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

Utilizza la console Firebase

Puoi anche modificare le origini delle regole e distribuirle come versioni dalla console Firebase. Il test sintattico viene eseguito durante la modifica nell'interfaccia utente della console Firebase e il test semantico è disponibile utilizzando Rules Playground.

Modifica e aggiorna le tue regole

  1. Apri la console Firebase e seleziona il tuo progetto.
  2. Quindi, seleziona Realtime Database , Cloud Firestore o Storage dalla navigazione del prodotto, quindi fai clic su Regole per accedere all'editor delle regole.
  3. Modifica le tue regole direttamente nell'editor.

Metti alla prova i tuoi aggiornamenti

Oltre a testare la sintassi nell'interfaccia utente dell'editor, puoi testare il comportamento semantico delle regole, utilizzando il database e le risorse di archiviazione del tuo progetto, direttamente nella console Firebase, utilizzando Rules Playground . Apri la schermata Rules Playground nell'editor delle regole, modifica le impostazioni e fai clic su Esegui . Cerca il messaggio di conferma nella parte superiore dell'editor.

Distribuisci i tuoi aggiornamenti

Una volta che sei sicuro che gli aggiornamenti siano quelli previsti, fai clic su Pubblica .

Utilizza l'SDK di amministrazione

Puoi utilizzare Admin SDK per i set di regole Node.js. Con questo accesso programmatico puoi:

  • Implementa strumenti personalizzati, script, dashboard e pipeline CI/CD per la gestione delle regole.
  • Gestisci le regole più facilmente su più progetti Firebase.

Quando si aggiornano le regole a livello di codice, è molto importante evitare di apportare modifiche involontarie al controllo dell'accesso per la tua app. Scrivi il codice dell'SDK Admin pensando soprattutto alla sicurezza, soprattutto durante l'aggiornamento o la distribuzione delle regole.

Un'altra cosa importante da tenere a mente è che le versioni delle regole di sicurezza Firebase richiedono diversi minuti per propagarsi completamente. Quando utilizzi l'SDK Admin per distribuire le regole, assicurati di evitare race conditions in cui la tua app si basa immediatamente su regole la cui distribuzione non è ancora stata completata. Se il tuo caso d'uso richiede aggiornamenti frequenti alle regole di controllo degli accessi, prendi in considerazione le soluzioni che utilizzano Cloud Firestore, progettato per ridurre le condizioni di competizione nonostante gli aggiornamenti frequenti.

Tieni inoltre presenti questi limiti:

  • Le regole devono essere inferiori a 256 KiB di testo codificato UTF-8 quando vengono serializzate.
  • Un progetto può avere al massimo 2500 set di regole distribuiti in totale. Una volta raggiunto questo limite, è necessario eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Crea e distribuisci set di regole Cloud Storage o Cloud Firestore

Un tipico flusso di lavoro per la gestione delle regole di sicurezza con Admin SDK potrebbe includere tre passaggi distinti:

  1. Creare un'origine file di regole (facoltativo)
  2. Crea un set di regole
  3. Rilascia o distribuisci il nuovo set di regole

L'SDK fornisce un metodo per combinare questi passaggi in un'unica chiamata API per le regole di sicurezza di Cloud Storage e Cloud Firestore. Per esempio:

    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);

Questo stesso modello funziona per le regole Cloud Storage con releaseFirestoreRulesetFromSource() .

In alternativa, puoi creare il file delle regole come oggetto in memoria, creare il set di regole e distribuirlo separatamente per un controllo più attento di questi eventi. Per esempio:

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

Aggiorna le regole del Realtime Database

Per aggiornare le serie di regole di Realtime Database con Admin SDK, utilizzare i metodi getRules() e setRules() di admin.database . Puoi recuperare i set di regole in formato JSON o come stringa con commenti inclusi.

Per aggiornare un set di regole:

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

Gestisci set di regole

Per facilitare la gestione di set di regole di grandi dimensioni, Admin SDK ti consente di elencare tutte le regole esistenti con admin.securityRules().listRulesetMetadata . Per esempio:

    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;
      }
    }

Per distribuzioni di grandi dimensioni che raggiungono nel tempo il limite di 2500 set di regole, è possibile creare una logica per eliminare le regole più vecchie in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole distribuiti per più di 30 giorni:

    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.`);

Utilizza l'API REST

Gli strumenti sopra descritti sono adatti a vari flussi di lavoro, inclusa la gestione delle regole di sicurezza Firebase per più database Cloud Firestore nel tuo progetto, ma potresti voler gestire e distribuire le regole di sicurezza Firebase utilizzando l'API di gestione stessa. L'API di gestione ti offre la massima flessibilità.

Tieni inoltre presenti questi limiti:

  • Le regole devono essere inferiori a 256 KiB di testo codificato UTF-8 quando vengono serializzate.
  • Un progetto può avere al massimo 2500 set di regole distribuiti in totale. Una volta raggiunto questo limite, è necessario eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Crea e distribuisci set di regole Cloud Firestore o Cloud Storage con REST

Gli esempi in questa sezione utilizzano le regole di Firestore, sebbene si applichino anche alle regole di Cloud Storage.

Gli esempi utilizzano anche cURL per effettuare chiamate API. I passaggi per impostare e passare i token di autenticazione vengono omessi. Puoi sperimentare questa API utilizzando API Explorer integrato con la documentazione di riferimento.

I passaggi tipici per la creazione e la distribuzione di un set di regole utilizzando l'API di gestione sono:

  1. Creare origini file di regole
  2. Crea un set di regole
  3. Rilascia (distribuisci) il nuovo set di regole.

Crea una fonte

Supponiamo che tu stia lavorando al tuo progetto Firebase secure_commerce e desideri distribuire le regole Cloud Firestore bloccate a un database nel tuo progetto denominato east_store .

Puoi implementare queste regole in un file firestore.rules .

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

Crea un set di regole

Ora genera un'impronta digitale con codifica base64 per questo file. Puoi quindi utilizzare l'origine in questo file per popolare il payload necessario per creare un set di regole con la chiamata REST projects.rulesets.create . Qui, usa il comando cat per inserire il contenuto di firestore.rules nel payload REST.

Per il monitoraggio, per associarlo al database east_store , imposta attachment_point su 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 restituisce una risposta di convalida e un nome di set di regole, ad esempio projects/secure_commerce/rulesets/uuid123 .

Rilascia (distribuisci) un set di regole

Se il set di regole è valido, il passaggio finale consiste nel distribuire il nuovo set di regole in una versione denominata.

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'

Tieni presente che le versioni delle regole di sicurezza Firebase richiedono diversi minuti per propagarsi completamente. Quando utilizzi l'API REST di gestione per la distribuzione, assicurati di evitare condizioni di competizione in cui la tua app si basa immediatamente su regole la cui distribuzione non è ancora completata.

Aggiorna le regole del Realtime Database con REST

Realtime Database fornisce la propria interfaccia REST per la gestione delle regole. Consulta Gestione delle regole del database Firebase Realtime tramite REST .

Gestisci i set di regole con REST

Per facilitare la gestione di distribuzioni di regole di grandi dimensioni, oltre a un metodo REST per la creazione di set di regole e versioni, l'API di gestione fornisce metodi per:

  • elencare, ottenere ed eliminare i set di regole
  • elencare, ottenere ed eliminare le versioni delle regole

Per distribuzioni di grandi dimensioni che raggiungono nel tempo il limite di 2500 set di regole, è possibile creare una logica per eliminare le regole più vecchie in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole distribuiti per più di 30 giorni, puoi chiamare il metodo projects.rulesets.list , analizzare l'elenco JSON degli oggetti Ruleset sulle relative chiavi createTime , quindi chiamare project.rulesets.delete sui set di regole corrispondenti tramite ruleset_id .

Metti alla prova i tuoi aggiornamenti con REST

Infine, l'API di gestione ti consente di eseguire test sintattici e semantici sulle risorse Cloud Firestore e Cloud Storage nei tuoi progetti di produzione.

Il test con questo componente dell'API consiste in:

  1. Definizione di un oggetto JSON TestSuite per rappresentare un insieme di oggetti TestCase
  2. Invio della TestSuite
  3. L'analisi ha restituito oggetti TestResult

Definiamo un oggetto TestSuite con un singolo TestCase in un file testcase.json . In questo esempio, passiamo l'origine del linguaggio Rules in linea con il payload REST, insieme alla suite di test da eseguire su tali regole. Specifichiamo un'aspettativa di valutazione delle regole e la richiesta del cliente rispetto alla quale il set di regole deve essere testato. È inoltre possibile specificare il livello di completezza del report di test, utilizzando il valore "FULL" per indicare i risultati per tutte le espressioni del linguaggio delle regole che devono essere incluse nel report, comprese le espressioni che non corrispondono alla richiesta.

 {
  "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"}}}
            }
          ]
      }
    ]
  }
}

Possiamo quindi inviare questa TestSuite per la valutazione con il metodo projects.test .

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

Il TestReport restituito (contenente lo stato SUCCESS/FAILURE del test, elenchi di messaggi di debug, elenchi di espressioni di regole visitate e i relativi rapporti di valutazione) confermerebbe con lo stato SUCCESS che l'accesso è correttamente consentito.

Gestisci le autorizzazioni per le regole di sicurezza Cloud Storage tra servizi

Se crei regole di sicurezza di Cloud Storage che utilizzano i contenuti dei documenti Cloud Firestore per valutare le condizioni di sicurezza , ti verrà richiesto nella console Firebase o nella CLI di Firebase di abilitare le autorizzazioni per connettere i due prodotti.

Se decidi di disabilitare tale sicurezza tra servizi:

  1. Innanzitutto, prima di disabilitare la funzionalità, modifica le tue regole, rimuovendo tutte le istruzioni che utilizzano le funzioni delle regole per accedere a Cloud Firestore. In caso contrario, una volta disabilitata la funzionalità, le valutazioni delle regole causeranno il fallimento delle richieste di archiviazione.

  2. Utilizza la pagina IAM in Google Cloud Console per eliminare il ruolo "Firebase Rules Firestore Service Agent" seguendo la guida Cloud per la revoca dei ruoli .

Ti verrà richiesto di riattivare la funzionalità la prossima volta che salvi le regole tra servizi dalla CLI Firebase o dalla console Firebase.