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

Firebase udostępnia różne narzędzia do zarządzania regułami, z których każde może być przydatne w określonych przypadkach, a z drugiej wykorzystuje ten sam backend 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ł: zestaw reguł, zwykle plik z kodem zawierający instrukcje dotyczące reguł zabezpieczeń Firebase.
  • Przechowuje pozyskane źródło jako stały zestaw reguł.
  • Śledzi wdrożenie każdego zestawu reguł w wersji. Usługi z włączonymi regułami zabezpieczeń Firebase przeszukują wersję projektu w celu oceny każdego żądania dotyczącego zabezpieczonego zasobu.
  • Możliwość przeprowadzania testów składniowych i semantycznych zestawu reguł.

Użyj 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 w interfejsie wiersza poleceń umożliwia przeprowadzanie pełnych testów lokalnych źródeł.

Interfejs wiersza poleceń pozwala utrzymać kontrolę wersji reguł za pomocą kodu aplikacji i wdrażać reguły w ramach istniejącego procesu wdrażania.

Generowanie pliku konfiguracji

Podczas konfigurowania projektu Firebase za pomocą interfejsu wiersza poleceń Firebase tworzysz plik konfiguracji .rules w katalogu projektu. 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

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

Testowanie aktualizacji

Pakiet emulatorów lokalnych udostępnia emulatory dla wszystkich usług z włączonymi regułami zabezpieczeń. Mechanizm reguł zabezpieczeń dla każdego emulatora wykonuje zarówno ocenę składniową, jak i semantyczną reguł, dzięki czemu przekracza ona testy składniowe oferowane przez interfejs Security Rules Management API.

Jeśli korzystasz z interfejsu wiersza poleceń, pakiet ten jest doskonałym narzędziem do testowania reguł zabezpieczeń Firebase. Aby przetestować aktualizacje lokalnie i sprawdzić, czy reguły aplikacji działają zgodnie z oczekiwaniami, użyj Pakietu emulatorów lokalnych.

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 domyślnymi i dodatkowymi nazwanymi bazami danych. W tym celu sprawdź i zaktualizuj plik firebase.json.

Użyj poniższych poleceń, aby selektywnie wdrożyć reguły 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>

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 za pomocą konsoli Firebase. Testy składniowe są przeprowadzane podczas edycji interfejsu konsoli Firebase, a testowanie semantyczne jest dostępne za pomocą narzędzia Reguły reguł.

Edytowanie i aktualizowanie reguł

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

Testowanie aktualizacji

Poza testowaniem składni w interfejsie edytora możesz też testować działanie reguł semantycznych, korzystając z bazy danych i zasobów miejsca na dane projektu bezpośrednio w konsoli Firebase przy użyciu platformy reguł. Otwórz ekran Środowisko reguł w edytorze reguł, zmień ustawienia i kliknij Uruchom. U góry edytora pojawi się komunikat z potwierdzeniem.

Wdrażanie aktualizacji

Gdy uznasz, że zmiany są zgodne z Twoimi oczekiwaniami, kliknij Opublikuj.

Używanie pakietu Admin SDK

Dla reguł Node.js możesz używać pakietu Admin SDK. Dzięki temu programowi można:

  • Wdróż niestandardowe narzędzia, skrypty, panele i potoki CI/CD do zarządzania regułami.
  • Łatwiejsze zarządzanie regułami w wielu projektach Firebase.

Gdy aktualizujesz reguły automatycznie, pamiętaj, by nie wprowadzać niezamierzonych zmian w kontroli dostępu do aplikacji. Pamiętaj o przygotowaniu kodu pakietu Admin SDK, szczególnie podczas aktualizowania lub wdrażania reguł.

Pamiętaj też, że pełne rozpowszechnienie wersji reguł zabezpieczeń Firebase może potrwać kilka minut. Gdy wdrażasz reguły za pomocą pakietu Admin SDK, unikaj sytuacji wyścigowych, w których aplikacja natychmiast korzysta z reguł, których wdrażanie jeszcze nie zostało ukończone. Jeśli Twój przypadek użycia wymaga częstych aktualizacji reguł kontroli dostępu, rozważ rozwiązania korzystające z usługi Cloud Firestore, która została zaprojektowana tak, aby ograniczyć warunki wyścigu pomimo częstych aktualizacji.

Pamiętaj też o tych limitach:

  • Po zserializowaniu reguły muszą mieć mniej niż 256 KiB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu 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 obejmować 3 oddzielne kroki:

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

Pakiet SDK udostępnia metodę łączenia tych czynności 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 releaseFirestoreRulesetFromSource().

Aby mieć większą kontrolę nad tymi zdarzeniami, możesz też utworzyć plik reguł jako obiekt w pamięci, utworzyć zestaw reguł i osobno wdrożyć zestaw reguł. 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() obiektu admin.database. Zestawy reguł można pobierać w formacie JSON lub w postaci ciągu znaków 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 zestawami reguł, pakiet Admin SDK umożliwia wyświetlenie 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ągną limit 2500 zestawów reguł, możesz utworzyć logikę usuwającą najstarsze reguły w ustalonym cyklu czasu. Aby np. usunąć wszystkie zestawy reguł wdrożone przez ponad 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żyj interfejsu API REST

Narzędzia opisane powyżej dobrze nadają się do różnych przepływów pracy, w tym do zarządzania regułami zabezpieczeń Firebase dla wielu baz danych Cloud Firestore w projekcie. Reguły zabezpieczeń Firebase możesz jednak wdrożyć za pomocą interfejsu API zarządzania. Interfejs API zarządzania zapewnia największą elastyczność.

Pamiętaj też o tych limitach:

  • Po zserializowaniu reguły muszą mieć mniej niż 256 KiB tekstu zakodowanego w formacie UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu 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 również zastosowanie do reguł Cloud Storage.

W przykładach do wykonywania wywołań interfejsu API używamy też narzędzia cURL. Instrukcje konfigurowania i przekazywania tokenów uwierzytelniania zostały pominięte. 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 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 secure_commerce i chcesz wdrożyć zablokowane reguły Cloud Firestore w bazie danych w swoim projekcie o nazwie east_store.

Możesz wdrożyć 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 formacie base64 dla tego pliku. Następnie możesz użyć źródła w tym pliku, aby wypełnić ładunek niezbędny do utworzenia zestawu reguł wywołaniem REST projects.rulesets.create. W tym przypadku użyj polecenia cat, aby wstawić zawartość firestore.rules do ładunku REST.

Na potrzeby śledzenia, aby 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ź sprawdzającą i nazwę zestawu reguł, np. projects/secure_commerce/rulesets/uuid123.

Publikowanie (wdrażanie) zestawu reguł

Jeśli zestaw reguł jest prawidłowy, ostatnim krokiem jest wdrożenie nowego zestawu reguł w wersji z nazwą.

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 reguł zabezpieczeń Firebase może potrwać kilka minut. Podczas wdrażania za pomocą interfejsu API REST zarządzania pamiętaj, aby unikać warunków wyścigowych, w których aplikacja natychmiast korzysta z reguł, 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 artykuł o zarządzaniu 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ł, interfejs API zarządzania udostępnia metody, takie jak:

  • wyświetlanie, pobieranie i usuwanie reguł
  • wyświetlanie, pobieranie i usuwanie wersji reguł

W przypadku bardzo dużych wdrożeń, które z czasem osiągną limit 2500 zestawów reguł, możesz utworzyć logikę usuwającą najstarsze reguły w ustalonym cyklu czasu. Aby np. usunąć wszystkie zestawy reguł wdrożone przez ponad 30 dni, możesz wywołać metodę projects.rulesets.list, przeanalizować listę obiektów JSON Ruleset w ich kluczach createTime, a następnie wywołać metodę project.rulesets.delete w odpowiadających im zestawach reguł przez ruleset_id.

Testowanie aktualizacji za pomocą REST

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

Testowanie za pomocą tego komponentu interfejsu API składa się z tych elementów:

  1. Definiowanie obiektu JSON TestSuite reprezentującego zbiór obiektów TestCase
  2. Przesyłam TestSuite
  3. Analiza zwróciła TestResult obiektu

Zdefiniujmy obiekt TestSuite z jednym obiektem TestCase w pliku testcase.json. W tym przykładzie przekazujemy źródło języka reguł w ramach ładunku REST wraz z pakietem testowym, aby uruchamiać reguły w tych regułach. Określamy oczekiwania dotyczące oceny reguł oraz żądanie klienta, pod kątem którego ma zostać przetestowany zestaw reguł. Możesz również określić stopień kompletności raportu testowego, używając wartości „FULL”, aby wskazać, jakie wyniki powinny zawierać wszystkie wyrażenia w języku reguł, w tym wyrażenia, 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"}}}
            }
          ]
      }
    ]
  }
}

Możemy wtedy przesłać ten plik 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 wynik TestReport (zawierający stan UPRAWNIONE/NIEPRAWIDŁOWY, listy komunikatów debugowania, listy odwiedzonych wyrażeń reguł i ich raportów oceny) potwierdza, że dostęp jest prawidłowy.

Zarządzanie uprawnieniami reguł zabezpieczeń Cloud Storage dla wielu usług

Jeśli utworzysz reguły zabezpieczeń Cloud Storage wykorzystujące zawartość dokumentów Cloud Firestore do oceny warunków zabezpieczeń, w konsoli Firebase lub w interfejsie wiersza poleceń Firebase pojawi się prośba o włączenie uprawnień umożliwiających połączenie tych usług.

Jeśli zdecydujesz się wyłączyć takie zabezpieczenia między usługami:

  1. Najpierw przed wyłączeniem funkcji edytuj reguły, usuwając wszystkie instrukcje korzystające z funkcji reguł dostępu do Cloud Firestore. W przeciwnym razie, gdy ta funkcja zostanie wyłączona, oceny reguł będą kończyć się niepowodzeniem żądań dotyczących miejsca na dane.

  2. Skorzystaj ze strony Uprawnienia w konsoli Google Cloud, aby usunąć rolę „Agent usługi Firestore reguł Firebase”, postępując zgodnie z instrukcjami opisanymi w przewodniku dotyczącym unieważniania ról.

Prośba o ponowne włączenie tej funkcji pojawi się, gdy następnym razem zapiszesz reguły dotyczące różnych usług w interfejsie wiersza poleceń Firebase lub w konsoli Firebase.