Wdrażanie reguł zabezpieczeń Firebase i zarządzanie nimi

Firebase udostępnia kilka narzędzi do zarządzania Security Rules. Każde z nich jest przydatne w określonych przypadkach i korzysta z tego samego interfejsu API do zarządzania regułami zabezpieczeń Firebase.

Niezależnie od tego, którego narzędzia użyjesz do wywołania interfejsu API zarządzania:

  • pobiera źródło reguł, czyli zbiór reguł, zwykle plik kodu zawierający Firebase Security Rules instrukcje;
  • przechowuje pobrane źródło jako niezmienny zbiór reguł ;
  • śledzi wdrażanie każdego zbioru reguł w wersji ; usługi z włączonymi regułami zabezpieczeń Firebase wyszukują wersję projektu, aby ocenić każde żądanie dotyczące zabezpieczonego zasobu;
  • umożliwia przeprowadzanie testów składniowych i semantycznych zbioru reguł.

Korzystanie z interfejsu wiersza poleceń Firebase

Za pomocą interfejsu Firebase wiersza poleceń Firebase możesz przesyłać lokalne źródła i wdrażać wersje. Pakiet Firebase Local Emulator Suite Firebase Local Emulator Suite umożliwia przeprowadzanie pełnych testów lokalnych źródeł.

Korzystanie z interfejsu wiersza poleceń pozwala na przechowywanie reguł pod kontrolą wersji wraz z kodem aplikacji i wdrażanie reguł w ramach dotychczasowego procesu wdrażania.

Generowanie pliku konfiguracji

Gdy skonfigurujesz projekt Firebase za pomocą interfejsu wiersza poleceń Firebase, w katalogu projektu utworzysz plik konfiguracji .rules. Aby rozpocząć konfigurowanie projektu Firebase, użyj tego polecenia:

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

Edytowanie i aktualizowanie reguł

Edytuj źródło reguł bezpośrednio w pliku konfiguracji .rules.

Upewnij się, że wszystkie zmiany wprowadzone w interfejsie wiersza poleceń Firebase są odzwierciedlane w konsoli Firebase lub że aktualizacje są wprowadzane konsekwentnie za pomocą konsoli Firebase albo interfejsu wiersza poleceń Firebase. W przeciwnym razie możesz nadpisać wszystkie aktualizacje wprowadzone w konsoli Firebase.

Testowanie aktualizacji

Local Emulator Suite udostępnia emulatory wszystkich usług z włączonymi regułami zabezpieczeń. Silnik reguł zabezpieczeń każdego emulatora przeprowadza zarówno składniową, jak i semantyczną ocenę reguł, co wykracza poza testowanie składniowe oferowane przez interfejs API do zarządzania regułami zabezpieczeń.

Jeśli pracujesz z interfejsem wiersza poleceń, pakiet jest doskonałym narzędziem do Firebase Security Rules testowania. Użyj Local Emulator Suite, aby przetestować aktualizacje lokalnie i sprawdzić, czy Security Rules aplikacji działają zgodnie z oczekiwaniami.

Wdrażanie aktualizacji

Gdy zaktualizujesz i przetestujesz Security Rules, wdróż źródła w środowisku produkcyjnym.

W przypadku Cloud Firestore Security Rules powiąż pliki .rules z domyślną i dodatkowymi nazwanymi bazami danych, sprawdzając i aktualizując plik firebase.json.

Użyj tych poleceń, aby wdrożyć tylko Security Rules lub wdrożyć je w ramach normalnego procesu wdrażania.

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

Korzystanie z konsoli Firebase

Możesz też edytować Security Rules źródła i wdrażać je jako wersje z poziomu konsoli Firebase. Podczas edycji w Firebase interfejsie konsoli przeprowadzane jest testowanie składniowe, a testowanie semantyczne jest dostępne w Security Rules piaskownicy.

Edytowanie i aktualizowanie reguł

  1. Otwórz konsolę Firebase i wybierz projekt.
  2. W menu nawigacyjnym usługi wybierz Realtime Database, Cloud Firestore lub Storage, a następnie kliknij Rules, aby przejść do Security Rules edytora.
  3. Edytuj reguły bezpośrednio w edytorze.

Testowanie aktualizacji

Oprócz testowania składni w interfejsie edytora możesz testować semantyczne Security Rules działanie, korzystając z bazy danych projektu i zasobów pamięci masowej, bezpośrednio w Firebase konsoli, używając Security Rules piaskownicy. W edytorze Security Rules otwórz ekran Piaskownica reguł, zmień ustawienia i kliknij Uruchom. U góry edytora poszukaj komunikatu z potwierdzeniem.

Wdrażanie aktualizacji

Gdy upewnisz się, że aktualizacje są zgodne z oczekiwaniami, kliknij Opublikuj.

Korzystanie z pakietu Admin SDK

Możesz używać Admin SDK do Node.js zbiorów reguł. Dzięki temu programowemu dostępowi możesz:

  • wdrażać niestandardowe narzędzia, skrypty, panele i potoki CI/CD do zarządzania regułami;
  • łatwiej zarządzać regułami w wielu projektach Firebase.

Podczas programowego aktualizowania reguł bardzo ważne jest, aby unikać niezamierzonych zmian w kontroli dostępu do aplikacji. Podczas pisania Admin SDK kodu należy przede wszystkim pamiętać o bezpieczeństwie, zwłaszcza podczas aktualizowania lub wdrażania reguł.

Należy też pamiętać, że pełne rozpowszechnienie wersji Firebase Security Rules trwa kilka minut. Podczas wdrażania Admin SDK w celu wdrożenia reguł unikaj sytuacji, w których aplikacja natychmiast korzysta z reguł, których wdrożenie nie zostało jeszcze zakończone. Jeśli Twój przypadek użycia wymaga częstych aktualizacji reguł kontroli dostępu, rozważ rozwiązania korzystające z Cloud Firestore, które zostały zaprojektowane tak, aby ograniczać sytuacje wyścigu pomimo częstych aktualizacji.

Pamiętaj też o tych limitach:

  • Po serializacji reguły muszą mieć mniej niż 256 KiB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zbiorów reguł. Po osiągnięciu tego limitu musisz usunąć niektóre stare zbiory reguł, zanim utworzysz nowe.

Tworzenie i wdrażanie zbiorów reguł Cloud Storage lub Cloud Firestore

Typowy przepływ pracy w ramach zarządzania regułami zabezpieczeń za pomocą Admin SDK może obejmować 3 odrębne kroki:

  1. Utwórz źródło pliku reguł (opcjonalnie).
  2. Utwórz zbiór reguł.
  3. Opublikuj lub wdróż nowy zbiór reguł.

Pakiet SDK udostępnia metodę łączenia tych kroków w jedno wywołanie interfejsu API w przypadku Cloud Storage i Cloud Firestore reguł zabezpieczeń. Przykład:

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

Ten sam wzorzec działa w przypadku reguł Cloud Storage z releaseFirestoreRulesetFromSource().

Możesz też utworzyć plik reguł jako obiekt w pamięci, utworzyć zbiór reguł i wdrożyć go oddzielnie, aby mieć większą kontrolę nad tymi zdarzeniami. Przykład:

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

Aktualizowanie zbiorów regułRealtime Database

Aby zaktualizować zbiory reguł Realtime Database za pomocą Admin SDK, użyj metod getRules() i setRules() w admin.database. Możesz pobierać zbiory reguł w formacie JSON lub jako ciąg znaków z komentarzami.

Aby zaktualizować zbiór reguł:

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

Zarządzanie zbiorami reguł

Aby ułatwić zarządzanie dużymi zbiorami reguł, Admin SDK umożliwia wyświetlanie wszystkich istniejących reguł za pomocą admin.securityRules().listRulesetMetadata. Przykład:

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

W przypadku bardzo dużych wdrożeń, które z czasem osiągają limit 2500 zbiorów reguł, możesz utworzyć logikę usuwania najstarszych reguł w stałym cyklu czasowym. Aby na przykład usunąć wszystkie zbiory reguł wdrożone ponad 30 dni temu:

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

Korzystanie z interfejsu API REST

Opisane powyżej narzędzia dobrze sprawdzają się w różnych przepływach pracy, w tym w Firebase Security Rules zarządzaniu wieloma bazami danych Cloud Firestore w projekcie. Możesz jednak zarządzać Firebase Security Rules i wdrażać je za pomocą samego interfejsu API zarządzania. Interfejs API zarządzania zapewnia największą elastyczność.

Pamiętaj też o tych limitach:

  • Po serializacji reguły muszą mieć mniej niż 256 KiB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zbiorów reguł. Po osiągnięciu tego limitu musisz usunąć niektóre stare zbiory reguł, zanim utworzysz nowe.

Tworzenie i wdrażanie zbiorów reguł Cloud Firestore lub Cloud Storage za pomocą interfejsu REST

Przykłady w tej sekcji dotyczą Firestore Security Rules, ale mają też zastosowanie do Cloud Storage Security Rules.

Przykłady używają też cURL do wywoływania interfejsu API. Pominięto kroki konfigurowania i przekazywania tokenów autoryzacji. Możesz eksperymentować z tym interfejsem API za pomocą eksploratora API zintegrowanego z dokumentacją.

Typowe kroki tworzenia i wdrażania zbioru reguł za pomocą interfejsu API zarządzania:

  1. Utwórz źródła pliku reguł.
  2. Utwórz zbiór reguł.
  3. Opublikuj (wdroż) nowy zbiór reguł.

Utwórz źródło

Załóżmy, że pracujesz nad projektem Firebase secure_commerce i chcesz wdrożyć zablokowane Cloud Firestore Security Rules w bazie danych w projekcie o nazwie east_store.

Możesz zaimplementować te reguły w pliku firestore.rules.

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

Utwórz zbiór reguł

Teraz wygeneruj odcisk palca zakodowany w standardzie base64 dla tego pliku. Następnie możesz użyć źródła w tym pliku, aby wypełnić ładunek potrzebny do utworzenia zbioru reguł za pomocą wywołania REST projects.rulesets.create. Użyj polecenia cat, aby wstawić zawartość pliku firestore.rules do ładunku REST.

Aby śledzić i powiązać ten zbiór z bazą danych east_store, ustaw attachment_point na 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'

Interfejs API zwraca odpowiedź weryfikacyjną i nazwę zbioru reguł, np. projects/secure_commerce/rulesets/uuid123.

Opublikuj (wdroż) zbiór reguł

Jeśli zbiór reguł jest prawidłowy, ostatnim krokiem jest wdrożenie nowego zbioru reguł w nazwanej wersji.

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'

Pamiętaj, że pełne rozpowszechnienie wersji Firebase Security Rules trwa kilka minut. Podczas wdrażania za pomocą interfejsu API REST zarządzania unikaj sytuacji, w których aplikacja natychmiast korzysta z reguł, których wdrożenie nie zostało jeszcze zakończone.

Aktualizowanie zbiorów reguł za pomocą interfejsu RESTRealtime Database

Realtime Database udostępnia własny interfejs REST do zarządzania Security Rules. Zobacz Zarządzanie Firebase Realtime Database Security Rules za pomocą interfejsu REST.

Zarządzanie zbiorami reguł za pomocą interfejsu REST

Aby ułatwić zarządzanie wdrożeniami dużych reguł, oprócz metody REST do tworzenia zbiorów reguł i wersji interfejs API zarządzania udostępnia metody:

  • wyświetlania, pobierania i usuwania zbiorów reguł
  • wyświetlania, pobierania i usuwania wersji reguł.

W przypadku bardzo dużych wdrożeń, które z czasem osiągają limit 2500 zbiorów reguł, możesz utworzyć logikę usuwania najstarszych reguł w stałym cyklu czasowym. Aby na przykład usunąć wszystkie zbiory reguł wdrożone ponad 30 dni temu, możesz wywołać metodę projects.rulesets.list, przeanalizować listę JSON obiektów Ruleset na podstawie kluczy createTime, a następnie wywołać metodę project.rulesets.delete w odpowiednich zbiorach reguł według ruleset_id.

Testowanie aktualizacji za pomocą interfejsu REST

Interfejs API zarządzania umożliwia też przeprowadzanie testów składniowych i semantycznych na Cloud Firestore i Cloud Storage zasobach w projektach produkcyjnych.

Testowanie za pomocą tego komponentu interfejsu API obejmuje:

  1. zdefiniowanie obiektu JSON TestSuite reprezentującego zbiór obiektów TestCase;
  2. przesłanie TestSuite;
  3. przeanalizowanie zwróconych obiektów TestResult.

Zdefiniujmy obiekt TestSuite z jednym TestCase w pliku testcase.json. W tym przykładzie przekazujemy Security Rules źródło języka w tekście wbudowanym w ładunek REST wraz z pakietem testów, który ma być uruchomiony na tych regułach. Określamy oczekiwanie na ocenę reguł oraz żądanie klienta, na podstawie którego ma być testowany zbiór reguł. Możesz też określić, jak szczegółowy ma być raport z testu, używając wartości „FULL”, aby wskazać, że w raporcie mają się znaleźć wyniki wszystkich Security Rules wyrażeń języka reguł zabezpieczeń, w tym wyrażeń, które nie pasowały do żądania.

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

Następnie możemy przesłać ten TestSuite do oceny za pomocą metody projects.test.

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

Zwrócony TestReport (zawierający stan SUKCES/NIEPOWODZENIE testu, listy komunikatów debugowania, listy odwiedzonych wyrażeń reguł i ich raportów oceny) potwierdzi stan SUKCES, że dostęp jest prawidłowo dozwolony.

Zarządzanie uprawnieniami do usług międzyusługowych Cloud Storage Security Rules

Jeśli utworzysz Cloud Storage Security Rules, które używają treści dokumentów Cloud Firestore do oceny warunków bezpieczeństwa, w konsoli Firebase lub interfejsie wiersza poleceń Firebase pojawi się prośba o włączenie uprawnień do łączenia tych 2 usług.

Jeśli zdecydujesz się wyłączyć takie zabezpieczenia obowiązujące w różnych usługach:

  1. Najpierw, zanim wyłączysz tę funkcję, edytuj reguły, usuwając wszystkie instrukcje, które używają funkcji Security Rules do uzyskiwania dostępu do Cloud Firestore. W przeciwnym razie po wyłączeniu tej funkcji Security Rules oceny spowodują niepowodzenie żądań Storage.

  2. Aby usunąć rolę „Agent usługi reguł zabezpieczeń Firebase w Firestore”, otwórz stronę Uprawnienia w konsoli Google Cloud i postępuj zgodnie z instrukcjami w przewodniku Cloud dotyczącym odbierania ról.

Przy następnym zapisaniu reguł obowiązujących w różnych usługach za pomocą interfejsu wiersza poleceń Firebase lub konsoli Firebase pojawi się prośba o ponowne włączenie tej funkcji.