Zarządzanie regułami zabezpieczeń Firebase i ich wdrażanie

Firebase udostępnia kilka narzędzi do zarządzania regułami, które są przydatne w określonych przypadkach. Każde z nich korzysta z tego samego backendu interfejsu Firebase Security Rules Management API.

Niezależnie od tego, jakie narzędzie zostanie użyte do jego wywołania, interfejs API zarządzania:

  • Pozyskuje źródło reguł, czyli zbiór reguł, zwykle plik kodu zawierający instrukcje Reguły zabezpieczeń Firebase.
  • Zapisuje źródło pozyskane jako stałą regułę.
  • Śledzi wdrożenie każdego zestawu reguł w wersji. Usługi z włączonymi regułami zabezpieczeń Firebase sprawdzają wersję projektu w celu oceny każdego żądania dotyczącego zabezpieczonego zasobu.
  • Umożliwia przeprowadzanie składniowych i semantycznych testów zestawu reguł.

Używanie interfejsu wiersza poleceń Firebase

Za pomocą interfejsu wiersza poleceń Firebase możesz przesyłać lokalne źródła i wdrażać wersje. Pakiet emulatorów lokalnych Firebase dostępny w interfejsie wiersza poleceń pozwala przeprowadzać pełne lokalne testy źródeł.

Użycie interfejsu wiersza poleceń pozwala kontrolować wersję reguł za pomocą kodu aplikacji i wdrażania reguł w ramach istniejącego procesu wdrażania.

Generowanie pliku konfiguracji

Podczas konfigurowania projektu Firebase za pomocą interfejsu wiersza poleceń Firebase tworzysz w katalogu projektu plik konfiguracji .rules. Aby rozpocząć konfigurację projektu Firebase, użyj tego polecenia:

Cloud Firestore

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

Baza danych czasu rzeczywistego

// 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 regularnie wprowadzasz aktualizacje za pomocą konsoli Firebase lub interfejsu wiersza poleceń Firebase. W przeciwnym razie możesz zastąpić aktualizacje wprowadzone w konsoli Firebase.

Testowanie aktualizacji

Pakiet emulatorów lokalnych udostępnia emulatory wszystkich usług z włączonymi regułami zabezpieczeń. Mechanizm reguł zabezpieczeń dla każdego emulatora dokonuje zarówno składniowej, jak i semantycznej oceny reguł, przekraczając tym samym testy składni dostępne w interfejsie Security Rules Management API.

Jeśli używasz interfejsu wiersza poleceń, pakiet Analytics jest doskonałym narzędziem do testowania reguł zabezpieczeń Firebase. Za pomocą Pakietu emulatorów lokalnych możesz lokalnie testować aktualizacje i upewniać się, że reguły aplikacji działają zgodnie z oczekiwaniami.

Wdrażanie aktualizacji

Po zaktualizowaniu i przetestowaniu reguł wdróż źródła w środowisku produkcyjnym.

W przypadku reguł zabezpieczeń Cloud Firestore powiąż pliki .rules z bazami danych domyślnymi i dodatkowymi nazwanymi bazami danych, sprawdzając i aktualizując plik firebase.json.

Za pomocą poniższych poleceń możesz selektywnie wdrożyć reguły 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>

Baza danych czasu rzeczywistego

// 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ć źródła reguł i wdrażać je jako wersje z poziomu konsoli Firebase. Testy składniowe są wykonywane podczas edycji w interfejsie konsoli Firebase. Testy semantyczne są dostępne w narzędziu Środowisko reguł.

Edytowanie i aktualizowanie reguł

  1. Otwórz konsolę Firebase i wybierz projekt.
  2. W menu nawigacyjnym usługi wybierz Baza danych czasu rzeczywistego, Cloud Firestore lub Przechowywanie danych, a potem kliknij Reguły, aby przejść do edytora reguł.
  3. Edytuj reguły bezpośrednio w edytorze.

Testowanie aktualizacji

Oprócz testowania składni w interfejsie edytora możesz przetestować działanie reguł semantycznych przy użyciu bazy danych i zasobów miejsca na dane projektu bezpośrednio w konsoli Firebase, korzystając z narzędzia do tworzenia reguł. W edytorze reguł otwórz ekran Eksperyment z regułami, zmień ustawienia i kliknij Uruchom. Poszukaj komunikatu z potwierdzeniem u góry edytora.

Wdrażanie aktualizacji

Jeśli zmiany są zgodne z Twoimi oczekiwaniami, kliknij Opublikuj.

Korzystanie z pakietu Admin SDK

W przypadku reguł Node.js możesz użyć pakietu Admin SDK. Program ten umożliwia:

  • Wdrażanie niestandardowych narzędzi, skryptów, paneli i potoków CI/CD do zarządzania regułami.
  • Łatwiejsze zarządzanie regułami w wielu projektach Firebase.

Przy programowym aktualizowaniu reguł należy unikać wprowadzania niezamierzonych zmian w kontroli dostępu aplikacji. Przy tworzeniu kodu pakietu Admin SDK pamiętaj o najważniejszym bezpieczeństwie, zwłaszcza przy aktualizowaniu i wdrażaniu reguł.

Inną ważną rzeczą, o której warto pamiętać, jest fakt, że pełne rozpowszechnienie wersji reguł zabezpieczeń Firebase zajmuje kilka minut. Podczas wdrażania reguł za pomocą pakietu Admin SDK unikaj warunków wyścigu, w których aplikacja natychmiast zależy od reguł, których wdrożenie nie zostało jeszcze ukończone. Jeśli Twój przypadek użycia wymaga częstych aktualizacji reguł kontroli dostępu, rozważ zastosowanie rozwiązania Cloud Firestore, które ma na celu ograniczenie wyścigów pomimo częstych aktualizacji.

Pamiętaj też o tych ograniczeniach:

  • W przypadku serializacji reguły nie mogą mieć więcej niż 256 KB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć łącznie maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu tego limitu musisz usunąć stare zestawy reguł, zanim utworzysz nowe.

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

Typowy przepływ pracy związany z zarządzaniem regułami zabezpieczeń za pomocą pakietu Admin SDK może składać się z 3 osobnych kroków:

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

Pakiet SDK udostępnia metodę łączenia tych kroków w jedno wywołanie interfejsu API dla reguł zabezpieczeń Cloud Storage i Cloud Firestore. 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 zasadą releaseFirestoreRulesetFromSource().

Możesz też utworzyć plik reguł jako obiekt w pamięci, utworzyć zestaw reguł i wdrożyć go oddzielnie, aby mieć ściślejszą 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 zestawów reguł Bazy danych czasu rzeczywistego

Aby zaktualizować zestawy reguł Bazy danych czasu rzeczywistego za pomocą pakietu Admin SDK, użyj metod getRules() i setRules() klasy admin.database. Zbiory reguł możesz pobrać w formacie JSON lub w postaci ciągu z komentarzami.

Aby zaktualizować zestaw reguł:

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

Zarządzaj zestawami reguł

Aby ułatwić zarządzanie dużymi zbiorami reguł, pakiet Admin SDK umożliwia wyświetlanie listy 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 w dłuższym czasie osiągają limit 2500 zestawów reguł, możesz utworzyć logikę usuwania najstarszych reguł w ustalonym cyklu czasowym. Aby na przykład usunąć wszystkie zbiory reguł wdrożone na okres dłuższy niż 30 dni:

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

Używanie interfejsu API REST

Opisane powyżej narzędzia dobrze sprawdzają się w różnych przepływach pracy, m.in. do zarządzania regułami zabezpieczeń Firebase dla wielu baz danych Cloud Firestore w projekcie, ale warto też zarządzać regułami zabezpieczeń Firebase i wdrażać je za pomocą interfejsu API do zarządzania. Interfejs API do zarządzania zapewnia największą elastyczność.

Pamiętaj też o tych ograniczeniach:

  • W przypadku serializacji reguły nie mogą mieć więcej niż 256 KB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć łącznie maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu tego limitu musisz usunąć stare zestawy reguł, zanim utworzysz nowe.

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

W przykładach w tej sekcji używane są reguły Firestore, ale mają one zastosowanie również do reguł Cloud Storage.

W przykładach cURL jest również używany do wywołań interfejsu API. Etapy konfigurowania i przekazywania tokenów uwierzytelniania są pomijane. Możesz eksperymentować z tym interfejsem API za pomocą narzędzia API Explorer zintegrowanego z dokumentacją referencyjną.

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

  1. Tworzenie źródeł plików reguł
  2. Tworzenie zestawu reguł
  3. Opublikuj (wdróż) nowy zestaw reguł.

Utwórz źródło

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

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

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

Tworzenie zestawu reguł

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

Aby na potrzeby śledzenia powiązać go 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ź weryfikacji i nazwę zestawu reguł, na przykład projects/secure_commerce/rulesets/uuid123.

Tworzenie (wdrażanie) zestawu reguł

Jeśli zestaw reguł jest prawidłowy, ostatnim krokiem jest wdrożenie nowego zestawu 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 zastosowanie reguł zabezpieczeń Firebase może potrwać kilka minut. Podczas wdrażania interfejsu API typu REST do zarządzania unikaj warunków wyścigu, w których aplikacja natychmiast bazuje na regułach, których wdrożenie nie zostało jeszcze ukończone.

Aktualizowanie zestawów reguł Bazy danych czasu rzeczywistego za pomocą REST

Baza danych czasu rzeczywistego udostępnia własny interfejs REST do zarządzania regułami. Przeczytaj sekcję Zarządzanie regułami Bazy danych czasu rzeczywistego Firebase za pomocą REST.

Zarządzanie zestawami reguł za pomocą 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świetlać, pobierać i usuwać reguły;
  • wyświetlanie, pobieranie i usuwanie wersji reguł

W przypadku bardzo dużych wdrożeń, które w dłuższym czasie osiągają limit 2500 zestawów reguł, możesz utworzyć logikę usuwania najstarszych reguł w ustalonym cyklu czasowym. Aby na przykład usunąć wszystkie zbiory reguł wdrożone dłużej niż 30 dni, możesz wywołać metodę projects.rulesets.list, przeanalizować listę JSON obiektów Ruleset w kluczach createTime, a następnie wywołać project.rulesets.delete w odpowiednich zestawach reguł do ruleset_id.

Testowanie aktualizacji za pomocą REST

Interfejs zarządzania API umożliwia uruchamianie testów składniowych i semantycznych zasobów Cloud Firestore i Cloud Storage w projektach produkcyjnych.

Testowanie za pomocą tego komponentu interfejsu API obejmuje:

  1. Definiowanie obiektu JSON TestSuite tak, aby reprezentował zbiór obiektów TestCase
  2. Przesyłam: TestSuite
  3. Analizowanie zwróciło TestResult obiektów

Zdefiniujmy w pliku testcase.json obiekt TestSuite z pojedynczym elementem TestCase. W tym przykładzie wraz z ładunkiem REST przekazujemy źródło języka reguł razem z pakietem testowym, aby uruchomić je na tych regułach. Określamy oczekiwania dotyczące oceny reguł i żądanie klienta, pod kątem którego ma zostać przetestowany zestaw reguł. Możesz też określić stopień ukończenia raportu testowego, używając wartości „FULL”, by wskazać wyniki dla wszystkich wyrażeń językowych związanych z regułami, w tym wyrażeń, które nie zostały dopasowane 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 obiekt 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ócona wartość TestReport (zawierająca stan SUKCESU/NIEPOWODZENIEM, listy komunikatów debugowania, listy odwiedzonych wyrażeń reguł i raporty oceny) potwierdza, że dostęp jest dozwolony.

Zarządzanie uprawnieniami do reguł zabezpieczeń Cloud Storage dotyczących wielu usług

Jeśli utworzysz reguły zabezpieczeń Cloud Storage korzystające z zawartości dokumentów Cloud Firestore do oceny warunków bezpieczeństwa, w konsoli Firebase lub w interfejsie wiersza poleceń Firebase pojawi się prośba o włączenie uprawnień do połączenia tych 2 usług.

Jeśli zdecydujesz się wyłączyć takie zabezpieczenia obejmujące wiele usług:

  1. Przed wyłączeniem funkcji zmodyfikuj reguły, usuwając wszystkie instrukcje, które używają funkcji reguł w celu uzyskania dostępu do Cloud Firestore. W przeciwnym razie po wyłączeniu tej funkcji oceny reguł będą kończyć się niepowodzeniem żądań miejsca na dane.

  2. Na stronie Uprawnienia w konsoli Google Cloud możesz usunąć rolę „Agent usługi Firestore Reguły Firebase” zgodnie z przewodnikiem Cloud na temat anulowania ról.

Gdy następnym razem zapiszesz reguły obejmujące różne usługi z poziomu interfejsu wiersza poleceń Firebase lub konsoli Firebase, pojawi się prośba o ponowne włączenie tej funkcji.