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

Firebase udostępnia kilka narzędzi do zarządzania 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 Management API:

  • Pobiera źródło reguł: zestaw reguł, zwykle plik kodu zawierający instrukcje Firebase Security Rules.
  • Przechowuje źródło jako niezmienny zbiór reguł.
  • Śledzi wdrażanie każdego zestawu reguł w wersji. Usługi z włączonymi regułami zabezpieczeń Firebase sprawdzają wersję projektu, aby ocenić każde żądanie dotyczące zabezpieczonego zasobu.
  • Umożliwia przeprowadzanie testów składniowych i semantycznych zestawu reguł.

Korzystanie z interfejsu wiersza poleceń Firebase

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

Korzystanie z interfejsu wiersza poleceń umożliwia przechowywanie reguł pod kontrolą wersji wraz z kodem aplikacji i wdrażanie 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 konfiguracyjny .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 Firebaseinterfejsie wiersza poleceń są odzwierciedlone w Firebasekonsoli, lub że konsekwentnie wprowadzasz zmiany za pomocą Firebasekonsoli lub interfejsu wiersza poleceń Firebase. W przeciwnym razie możesz zastąpić wszelkie zmiany wprowadzone w Firebasekonsoli.

Testowanie aktualizacji

Local Emulator Suite udostępnia emulatory wszystkich usług z włączonymi regułami zabezpieczeń. Silnik reguł bezpieczeństwa każdego emulatora przeprowadza zarówno syntaktyczną, jak i semantyczną ocenę reguł, co wykracza poza testowanie syntaktyczne oferowane przez interfejs Security Rules Management API.

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

Wdrażanie aktualizacji

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

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

Użyj tych poleceń, aby wdrożyć Rules samodzielnie lub 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ć Rules źródła i wdrażać je jako wersje w Firebasekonsoli. Testowanie składniowe jest przeprowadzane podczas edytowania w interfejsie konsoliFirebase, a testowanie semantyczne jest dostępne w Rulespiaskownicy.

Edytowanie i aktualizowanie reguł

  1. Otwórz Firebasekonsolę i wybierz projekt.
  2. Następnie w menu nawigacyjnym usługi wybierz Realtime Database, Cloud Firestore lub Przechowywanie, a potem kliknij Reguły, aby otworzyć edytor Rules.
  3. Edytuj reguły bezpośrednio w edytorze.

Testowanie aktualizacji

Oprócz testowania składni w interfejsie edytora możesz testować zachowanie semantyczneRules, korzystając z zasobów bazy danych i pamięci projektuFirebase bezpośrednio w Rulespiaskownicy. Otwórz ekran Plac zabaw z regułami w edytorze Rules, zmień ustawienia i kliknij Uruchom. Poszukaj komunikatu z potwierdzeniem u góry edytora.

Wdrażanie aktualizacji

Gdy upewnisz się, że wprowadzone zmiany są zgodne z Twoimi oczekiwaniami, kliknij Opublikuj.

Używanie pakietu Admin SDK

Możesz używać Admin SDK zestawów reguł dla Node.js. Dzięki zautomatyzowanemu dostępowi możesz:

  • 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.

Podczas programistycznego aktualizowania reguł bardzo ważne jest, aby unikać niezamierzonych zmian w kontroli dostępu do aplikacji. Twórz Admin SDKkod z myślą przede wszystkim o bezpieczeństwie, zwłaszcza podczas aktualizowania lub wdrażania reguł.

Kolejną ważną rzeczą, o której należy pamiętać, jest to, że Firebase Security Rules wdrażanie wersji trwa kilka minut. Podczas wdrażania reguł za pomocą interfejsu Admin SDK unikaj sytuacji wyścigu, w których aplikacja natychmiast korzysta z reguł, których wdrażanie 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ć warunki wyścigu pomimo częstych aktualizacji.

Pamiętaj też o tych limitach:

  • Reguły po serializacji muszą mieć mniej niż 256 KiB tekstu zakodowanego w UTF-8.
  • Projekt może zawierać maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu tego limitu musisz usunąć niektóre starsze 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ą Admin SDK może obejmować 3 osobne etapy:

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

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

Możesz też utworzyć plik reguł jako obiekt w pamięci, utworzyć zestaw 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 zestawów reguł Realtime Database

Aby zaktualizować zestawy reguł Realtime Database za pomocą Admin SDK, użyj metod getRules()setRules()admin.database. Możesz pobierać zestawy reguł w formacie JSON lub jako ciąg 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ądzanie zestawami reguł

Aby ułatwić zarządzanie dużymi zbiorami reguł, funkcja Admin SDK umożliwia wyświetlanie wszystkich istniejących reguł za pomocą funkcji 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ę usuwania najstarszych reguł w ustalonym cyklu czasowym. Aby na przykład usunąć wszystkie zestawy 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.`);

Korzystanie z interfejsu API REST

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

pełnej dokumentacji interfejsu REST API do zarządzania regułami.

Pamiętaj też o tych limitach:

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

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

Przykłady w tej sekcji korzystają z Firestore Rules, ale dotyczą też Cloud Storage Rules.

W przykładach do wywoływania interfejsu API używane jest też narzędzie cURL. Pominięto kroki konfiguracji i przekazywania tokenów uwierzytelniania. Możesz eksperymentować z tym interfejsem API za pomocą narzędzia APIs 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. Wdróż nowy zestaw reguł.

Utwórz źródło

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

Te reguły możesz wdroż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 tego pliku zakodowany w standardzie Base64. Możesz następnie użyć źródła w tym pliku, aby wypełnić ładunek potrzebny do utworzenia zestawu reguł za pomocą projects.rulesets.createwywołania REST. Użyj tutaj polecenia cat, aby wstawić zawartość pliku firestore.rules do ładunku REST.

Aby śledzić i powiązać to z bazą danych east_store, ustaw parametr attachment_point na wartość 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ę zestawu reguł, np.projects/secure_commerce/rulesets/uuid123.

Wdrażanie zestawu reguł

Jeśli zestaw reguł jest prawidłowy, ostatnim krokiem jest wdrożenie nowego zestawu 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 zajmuje kilka minut. Podczas wdrażania za pomocą interfejsu REST API do zarządzania unikaj sytuacji wyścigu, w których aplikacja natychmiast korzysta z reguł, których wdrażanie nie zostało jeszcze zakończone.

Aktualizowanie zestawów reguł Realtime Database za pomocą interfejsu REST

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

Zarządzanie zestawami reguł za pomocą interfejsu REST

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

  • wyświetlać, pobierać i usuwać zbiory reguł;
  • wyświetlanie, pobieranie i usuwanie reguł wersji;

W przypadku bardzo dużych wdrożeń, które z czasem osiągną limit 2500 zestawów reguł, możesz utworzyć logikę usuwania najstarszych reguł w ustalonym cyklu czasowym. Aby na przykład usunąć wszystkie zestawy reguł wdrożone na okres dłuższy niż 30 dni, możesz wywołać metodę projects.rulesets.list, przeanalizować listę JSON obiektów Ruleset na podstawie ich kluczy createTime, a następnie wywołać metodę project.rulesets.delete w odpowiednich zestawach reguł za pomocą metody ruleset_id.

Testowanie aktualizacji za pomocą interfejsu REST

Interfejs Management API umożliwia przeprowadzanie testów składniowych i semantycznych zasobów Cloud FirestoreCloud Storage w projektach produkcyjnych.

.

Testowanie tego komponentu interfejsu API obejmuje:

  1. Definiowanie obiektu JSON TestSuite reprezentującego zbiór obiektów TestCase
  2. Przesyłanie TestSuite
  3. Analizowanie zwróconych obiektów TestResult

Zdefiniujmy obiekt TestSuite z jednym elementem TestCase w pliku testcase.json. W tym przykładzie przekazujemy Rules źródło języka w formie wbudowanej w ładunek REST wraz z pakietem testowym, który ma być uruchomiony na podstawie tych reguł. Określamy oczekiwania dotyczące oceny reguł oraz żądanie klienta, pod kątem którego ma być testowany zestaw reguł. Możesz też określić, jak szczegółowy ma być raport z testu. Wartość „FULL” oznacza, że w raporcie powinny się znaleźć wyniki wszystkich Ruleswyrażeń językowych, w tym tych, 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"}}}
            }
          ]
      }
    ]
  }
}

Możemy wtedy 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 obiekt TestReport (zawierający stan testu SUKCES/NIEPOWODZENIE, listy komunikatów debugowania, listy odwiedzonych wyrażeń reguł i raporty z ich oceną) potwierdzi stan SUKCES, że dostęp jest prawidłowo dozwolony.

Zarządzanie uprawnieniami do usługi Cloud Storage Security Rules

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

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

  1. Najpierw przed wyłączeniem tej funkcji zmień reguły, usuwając wszystkie instrukcje, które używają funkcji Rules do uzyskiwania dostępu do Cloud Firestore. W przeciwnym razie po wyłączeniu tej funkcji oceny Rules będą powodować niepowodzenie żądań dotyczących pamięci.

  2. Na stronie IAM w konsoli Google Cloud usuń rolę „Firebase Rules Firestore Service Agent”, postępując zgodnie z przewodnikiem Cloud dotyczącym cofania ról.

Przy następnym zapisywaniu reguł obejmujących wiele usług za pomocą Firebase CLI lub konsoli Firebase pojawi się prośba o ponowne włączenie tej funkcji.