Gestisci ed esegui il deployment delle regole di sicurezza Firebase

Firebase ti offre diversi strumenti per gestire i tuoi Rules, ognuno utile in casi particolari e ognuno che utilizza la stessa API di gestione delle regole di sicurezza Firebase di backend.

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

  • Importa un'origine delle regole: un insieme di regole, in genere un file di codice contenente stmtFirebase Security Rules.
  • Memorizza l'origine importata come insieme di regole immutabile.
  • Monitora il deployment di ogni insieme di regole in una release. I servizi abilitati alle regole di sicurezza di Firebase cercano la release di un progetto per valutare ogni richiesta di una risorsa protetta.
  • Fornisce la possibilità di eseguire test sintattici e semantici di un insieme di regole.

Utilizza l'interfaccia a riga di comando Firebase

Con l'interfaccia a riga di comando Firebase, puoi caricare le origini locali ed eseguire il deployment delle release. Il comando Firebase Local Emulator Suite della CLI ti consente di eseguire test locali completi delle origini.

L'utilizzo della CLI ti consente di mantenere le regole sotto controllo della versione con il codice dell'applicazione e di eseguire il deployment delle regole nell'ambito della procedura di deployment esistente.

Generare un file di configurazione

Quando configuri il progetto Firebase utilizzando l'interfaccia a riga di comando Firebase, crei un file di configurazione Firebase nella directory del progetto..rules Utilizza il seguente comando per iniziare a configurare il progetto 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

Modificare e aggiornare le regole

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

Assicurati che le modifiche apportate all'interfaccia a riga di comando Firebase vengano applicate alla console Firebase o che tu apporti aggiornamenti in modo coerente utilizzando la console Firebase o l'interfaccia a riga di comando Firebase. In caso contrario, potresti sovrascrivere eventuali aggiornamenti apportati nella console Firebase.

Testare gli aggiornamenti

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

Se utilizzi la CLI, la suite è uno strumento eccellente per i Firebase Security Rules test. Utilizza Local Emulator Suite per testare gli aggiornamenti localmente e verificare che Rules della tua app mostri il comportamento che desideri.

Esegui il deployment degli aggiornamenti

Dopo aver aggiornato e testato Rules, esegui il deployment delle origini in produzione.

Per Cloud Firestore Security Rules, associa i file .rules ai database denominati predefiniti e aggiuntivi esaminando e aggiornando il file firebase.json.

Utilizza i comandi seguenti per eseguire il deployment selettivo di Rules da solo o come parte della normale procedura di deployment.

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

Utilizzare la console Firebase

Puoi anche modificare le origini Rules e implementarle come release dalla console Firebase. I test sintattici vengono eseguiti durante la modifica nell'Firebaseinterfaccia utente della console, mentre i test semantici sono disponibili utilizzando RulesPlayground.

Modificare e aggiornare le regole

  1. Apri la console Firebase e seleziona il tuo progetto.
  2. Quindi, seleziona Realtime Database, Cloud Firestore o Archiviazione dal menu di navigazione del prodotto, poi fai clic su Regole per accedere all'editor Rules.
  3. Modifica le regole direttamente nell'editor.

Testare gli aggiornamenti

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

Esegui il deployment degli aggiornamenti

Quando gli aggiornamenti ti soddisfano, fai clic su Pubblica.

Utilizzare l'SDK Admin

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

  • Implementa strumenti, script, dashboard e pipeline CI/CD personalizzati per gestire le regole.
  • Gestisci più facilmente le regole in più progetti Firebase.

Quando aggiorni le regole in modo programmatico, è molto importante evitare di apportare modifiche indesiderate al controllo dell'accesso per la tua app. Scrivi il codice Admin SDK tenendo sempre presente la sicurezza, in particolare quando aggiorni o esegui il deployment delle regole.

Un'altra cosa importante da tenere presente è che le release Firebase Security Rules richiedono un periodo di diversi minuti per essere completamente propagate. Quando utilizzi Admin SDK per eseguire il deployment delle regole, assicurati di evitare condizioni di gara in cui la tua app si basa immediatamente su regole di cui il deployment non è ancora stato completato. Se il tuo caso d'uso richiede aggiornamenti frequenti alle regole di controllo dell'accesso, valuta le soluzioni che utilizzano Cloud Firestore, progettato per ridurre le condizioni di gara nonostante gli aggiornamenti frequenti.

Tieni inoltre presente questi limiti:

  • Le regole devono avere dimensioni inferiori a 256 KiB di testo codificato in UTF-8 durante la serializzazione.
  • Un progetto può avere al massimo 2500 set di regole di cui è stato eseguito il deployment. Una volta raggiunto questo limite, devi eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Crea e implementa 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. Creare un insieme di regole
  3. Rilascia o esegui il deployment del nuovo insieme di regole

L'SDK fornisce un metodo per combinare questi passaggi in un'unica chiamata API per le regole di sicurezza Cloud Storage e Cloud Firestore. Ad 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);

Lo stesso pattern funziona per le regole Cloud Storage con releaseFirestoreRulesetFromSource().

In alternativa, puoi creare il file delle regole come oggetto in memoria, creare il insieme di regole e implementarlo separatamente per un controllo più stretto di questi eventi. Ad esempio:

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

Aggiorna i set di regole Realtime Database

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

Per aggiornare un insieme di regole:

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

Gestire i set di regole

Per aiutarti a gestire insiemi di regole di grandi dimensioni, Admin SDK ti consente di elencare tutte le regole esistenti con admin.securityRules().listRulesetMetadata. Ad 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 le implementazioni di grandi dimensioni che raggiungono il limite di 2500 set di regole nel tempo, puoi creare una logica per eliminare le regole meno recenti in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole di cui è stato eseguito il deployment 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.`);

Utilizzo dell'API REST

Gli strumenti descritti sopra sono adatti a vari flussi di lavoro, inclusa la gestione di Firebase Security Rules per più database Firebase Security Rules nel progetto, ma ti consigliamo di gestire ed eseguire il deployment di Firebase Security Rules utilizzando l'API di gestione stessa.Cloud Firestore L'API di gestione offre la massima flessibilità.

Tieni inoltre presente questi limiti:

  • Le regole devono avere dimensioni inferiori a 256 KiB di testo codificato in UTF-8 durante la serializzazione.
  • Un progetto può avere al massimo 2500 set di regole di cui è stato eseguito il deployment. Una volta raggiunto questo limite, devi eliminare alcuni vecchi set di regole prima di crearne di nuovi.

Creare ed eseguire il deployment di set di regole Cloud Firestore o Cloud Storage con REST

Gli esempi in questa sezione utilizzano Firestore Rules, anche se si applicano anche a Cloud Storage Rules.

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

I passaggi tipici per creare e implementare un insieme di regole utilizzando l'API di gestione sono:

  1. Creare origini file delle regole
  2. Creare un insieme di regole
  3. Rilascia (esegui il deployment) del nuovo insieme di regole.

Crea un'origine

Supponiamo che tu stia lavorando al tuo progetto Firebase secure_commerce e voglia eseguire il deployment di Cloud Firestore Rules bloccato in un database del 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;
    }
  }
}

Creare un insieme di regole

Ora genera un'impronta codificata in base64 per questo file. Puoi quindi utilizzare il codice sorgente in questo file per compilare il payload necessario per creare un insieme di regole con la chiamata REST projects.rulesets.create. Qui, utilizza il comando cat per inserire i contenuti di firestore.rules nel payload REST.

Per il monitoraggio, per associarlo al tuo 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 il nome del set di regole, ad esempio projects/secure_commerce/rulesets/uuid123.

Rilasciare (implementare) un insieme di regole

Se il set di regole è valido, il passaggio finale consiste nel eseguire il deployment del nuovo set di regole in una release rinominata.

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 release di Firebase Security Rules richiedono diversi minuti per essere propagate completamente. Quando utilizzi l'API REST di gestione per il deployment, assicurati di evitare condizioni di gara in cui l'app si basa immediatamente su regole di cui il deployment non è ancora completato.

Aggiornare i set di regole Realtime Database con REST

Realtime Database fornisce la propria interfaccia REST per la gestione di Rules. Consulta Gestire Firebase Realtime Database Rules tramite REST.

Gestire i set di regole con REST

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

  • elenca, recupera ed elimina i set di regole
  • elenca, recupera ed elimina le release delle regole

Per le implementazioni di grandi dimensioni che raggiungono il limite di 2500 set di regole nel tempo, puoi creare una logica per eliminare le regole meno recenti in un ciclo di tempo fisso. Ad esempio, per eliminare tutti i set di regole di cui è stato eseguito il deployment per più di 30 giorni, puoi chiamare il metodo projects.rulesets.list, analizzare l'elenco JSON degli oggetti Ruleset in base alle relative chiavi createTime e poi chiamare project.rulesets.delete sui set di regole corrispondenti per ruleset_id.

Testare gli aggiornamenti con REST

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

I test con questo componente dell'API consistono in:

  1. Definizione di un oggetto JSON TestSuite per rappresentare un insieme di oggetti TestCase
  2. Invio del TestSuite
  3. Analisi degli oggetti TestResult restituiti

Definiamo un oggetto TestSuite con un singolo TestCase in un file testcase.json. In questo esempio, trasmettiamo la fonte di lingua Rules in linea con il payload REST, insieme alla suite di test da eseguire su queste regole. Specifichiamo un'aspettativa di valutazione delle regole e la richiesta del cliente rispetto alla quale deve essere testato il set di regole. Puoi anche specificare il grado di completezza del report del test utilizzando il valore "FULL" per indicare che i risultati per tutte le espressioni in lingua Rules devono essere inclusi nel report, incluse 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 questo 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'

L'oggetto TestReport restituito (contenente lo stato SUCCESS/FAILURE del test, elenchi di messaggi di debug, elenchi di espressioni delle regole visitate e relativi report di valutazione) conferma con lo stato SUCCESS che l'accesso è consentito correttamente.

Gestire le autorizzazioni per Cloud Storage Security Rules tra servizi

Se crei Cloud Storage Security Rules che utilizzano i contenuti dei documenti Cloud Firestore per valutare le condizioni di sicurezza, nella console Firebase o nell'interfaccia a riga di comando Firebase ti verrà chiesto di attivare le autorizzazioni per collegare i due prodotti.

Se decidi di disattivare questa sicurezza tra servizi:

  1. Innanzitutto, prima di disattivare la funzionalità, modifica le regole rimuovendo tutte le istruzioni che utilizzano le funzioni Rules per accedere a Cloud Firestore. In caso contrario, dopo la disattivazione della funzionalità, le valutazioni di Rules causeranno il fallimento delle richieste di archiviazione.

  2. Utilizza la pagina IAM della console Google Cloud per eliminare il ruolo "Agente di servizio Firestore per le regole Firebase" seguendo la guida di Cloud per la revoca dei ruoli.

Ti verrà chiesto di riattivare la funzionalità la prossima volta che salvi le regole tra servizi dall'interfaccia a riga di comando Firebase o dalla console Firebase.