Управление и развертывание правил безопасности Firebase

Firebase предоставляет несколько инструментов для управления Rules , каждый из которых полезен в определенных случаях, и каждый из них использует один и тот же API управления правилами безопасности Firebase.

Независимо от того, какой инструмент используется для его вызова, API управления:

  • Обрабатывает исходный код правил: набор правил, как правило, файл кода, содержащий операторы Firebase Security Rules .
  • Исходный код хранится в виде неизменяемого набора правил .
  • Отслеживает развертывание каждого набора правил в релизе . Сервисы с поддержкой правил безопасности Firebase ищут релиз проекта для оценки каждого запроса на защищенный ресурс.
  • Предоставляет возможность проводить синтаксические и семантические проверки набора правил.

Используйте Firebase CLI

С помощью Firebase CLI вы можете загружать локальные исходные коды и развертывать релизы . Firebase Local Emulator Suite входящий в состав CLI, позволяет проводить полное локальное тестирование исходных кодов .

Использование интерфейса командной строки позволяет вам контролировать версии ваших правил вместе с кодом приложения и развертывать правила в рамках существующего процесса развертывания.

Сгенерируйте файл конфигурации.

При настройке проекта Firebase с помощью Firebase CLI вы создаете конфигурационный файл .rules в каталоге проекта. Используйте следующую команду, чтобы начать настройку проекта 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

Редактируйте и обновляйте свои правила.

Редактируйте исходный код правил непосредственно в конфигурационном файле .rules .

Убедитесь, что все изменения, внесенные вами в Firebase CLI, отображаются в консоли Firebase , или что вы постоянно вносите обновления, используя либо консоль Firebase , либо Firebase CLI. В противном случае вы можете перезаписать любые обновления, внесенные в консоли Firebase .

Проверьте свои обновления.

Local Emulator Suite предоставляет эмуляторы для всех продуктов с поддержкой правил безопасности. Механизм правил безопасности для каждого эмулятора выполняет как синтаксическую, так и семантическую оценку правил, превосходя тем самым синтаксическую проверку, предлагаемую API управления правилами безопасности.

Если вы работаете с CLI, то этот набор инструментов отлично подходит для тестирования Firebase Security Rules . Используйте Local Emulator Suite , чтобы протестировать обновления локально и убедиться, что Rules вашего приложения демонстрируют желаемое поведение.

Разверните обновления

После обновления и тестирования Rules разверните исходный код в рабочую среду.

Для Cloud Firestore Security Rules свяжите файлы .rules с вашей базой данных по умолчанию и дополнительными именованными базами данных, просмотрев и обновив файл firebase.json .

Используйте следующие команды для выборочного развертывания Rules по отдельности или для развертывания их в рамках стандартного процесса развертывания.

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

Используйте консоль Firebase

Вы также можете редактировать исходный код Rules и развертывать их в качестве релизов из консоли Firebase . Синтаксическое тестирование выполняется во время редактирования в пользовательском интерфейсе консоли Firebase , а семантическое тестирование доступно с помощью Rules Playground.

Редактируйте и обновляйте свои правила.

  1. Откройте консоль Firebase и выберите свой проект.
  2. Затем выберите Realtime Database , Cloud Firestore или Storage в меню навигации продукта, после чего нажмите Rules , чтобы перейти в редактор Rules .
  3. Редактируйте правила непосредственно в редакторе.

Проверьте свои обновления.

Помимо проверки синтаксиса в пользовательском интерфейсе редактора, вы можете проверить семантическое поведение Rules , используя ресурсы базы данных и хранилища вашего проекта, непосредственно в консоли Firebase , используя Rules Playground . Откройте экран Rules Playground в редакторе Rules , измените настройки и нажмите «Запустить» . Дождитесь подтверждающего сообщения в верхней части редактора.

Разверните обновления

Когда вы убедитесь, что ваши обновления соответствуют вашим ожиданиям, нажмите «Опубликовать» .

Используйте Admin SDK.

Вы можете использовать Admin SDK для правил Node.js. Благодаря этому программному доступу вы можете:

  • Внедрить собственные инструменты, скрипты, панели мониторинга и конвейеры CI/CD для управления правилами.
  • Упростите управление правилами в нескольких проектах Firebase.

При программном обновлении правил очень важно избегать непреднамеренных изменений в контроле доступа для вашего приложения. При написании кода Admin SDK учитывайте прежде всего безопасность, особенно при обновлении или развертывании правил.

Ещё один важный момент, который следует учитывать, — это то, что для полного распространения обновлений Firebase Security Rules требуется несколько минут. При использовании Admin SDK для развертывания правил избегайте состояний гонки, когда ваше приложение немедленно начинает полагаться на правила, развертывание которых ещё не завершено. Если ваш сценарий использования требует частых обновлений правил контроля доступа, рассмотрите решения с использованием Cloud Firestore , который разработан для уменьшения состояний гонки, несмотря на частые обновления.

Также обратите внимание на следующие ограничения:

  • При сериализации размер правил должен быть меньше 256 КиБ текста, закодированного в UTF-8.
  • В проекте может быть не более 2500 развернутых наборов правил. После достижения этого лимита необходимо удалить некоторые старые наборы правил, прежде чем создавать новые.

Создайте и разверните наборы правил Cloud Storage или Cloud Firestore

Типичный рабочий процесс управления правилами безопасности с помощью Admin SDK может включать три отдельных шага:

  1. Создайте источник файла правил (необязательно).
  2. Создайте набор правил
  3. Выпустить или развернуть новый набор правил

SDK предоставляет метод для объединения этих шагов в один вызов API для правил безопасности Cloud Storage и Cloud Firestore . Например:

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

Этот же принцип работает и для правил Cloud Storage с releaseFirestoreRulesetFromSource() .

В качестве альтернативы, вы можете создать файл правил как объект в оперативной памяти, создать набор правил и развернуть его отдельно для более тщательного контроля этих событий. Например:

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

Обновление наборов правил Realtime Database

Для обновления наборов правил Realtime Database с помощью Admin SDK используйте методы getRules() и setRules() класса admin.database . Вы можете получить наборы правил в формате JSON или в виде строки с комментариями.

Для обновления набора правил:

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

Управление наборами правил

Для управления большими наборами правил Admin SDK позволяет получить список всех существующих правил с помощью admin.securityRules().listRulesetMetadata . Например:

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

Для очень крупных развертываний, достигающих со временем лимита в 2500 наборов правил, можно создать логику для удаления самых старых правил через фиксированный промежуток времени. Например, чтобы удалить все наборы правил, развернутые более 30 дней назад:

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

Используйте REST API

Описанные выше инструменты хорошо подходят для различных рабочих процессов, включая управление Firebase Security Rules для нескольких баз данных Cloud Firestore в вашем проекте, но вы можете захотеть управлять и развертывать Firebase Security Rules с помощью самого API управления. API управления предоставляет вам наибольшую гибкость.

Также обратите внимание на следующие ограничения:

  • При сериализации размер правил должен быть меньше 256 КиБ текста, закодированного в UTF-8.
  • В проекте может быть не более 2500 развернутых наборов правил. После достижения этого лимита необходимо удалить некоторые старые наборы правил, прежде чем создавать новые.

Создавайте и развертывайте наборы правил Cloud Firestore или Cloud Storage с помощью REST.

В примерах этого раздела используются Rules Firestore, хотя они применимы и к Rules Cloud Storage .

В примерах также используется cURL для выполнения вызовов API. Шаги по настройке и передаче токенов аутентификации опущены. Вы можете поэкспериментировать с этим API, используя API Explorer, интегрированный со справочной документацией.

Типичные шаги для создания и развертывания набора правил с использованием API управления включают в себя:

  1. Создайте источники файлов правил.
  2. Создайте набор правил
  3. Разверните новый набор правил.

Создать источник

Предположим, вы работаете над своим проектом secure_commerce в Firebase и хотите развернуть Rules Cloud Firestore с ограниченным доступом в базу данных вашего проекта под названием east_store .

Эти правила можно реализовать в файле firestore.rules .

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

Создайте набор правил

Теперь сгенерируйте отпечаток в кодировке base64 для этого файла. Затем вы можете использовать исходный код этого файла для заполнения полезной нагрузки, необходимой для создания набора правил с помощью REST-запроса projects.rulesets.create . Здесь используйте команду cat , чтобы вставить содержимое файла firestore.rules в полезную нагрузку REST-запроса.

Для отслеживания и привязки этого объекта к вашей базе данных east_store установите attachment_point равным 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'

API возвращает ответ с подтверждением и имя набора правил, например, projects/secure_commerce/rulesets/uuid123 .

Развернуть набор правил

Если набор правил действителен, заключительным шагом является развертывание нового набора правил в именованном релизе.

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'

Учтите, что для полного распространения обновлений Firebase Security Rules требуется несколько минут. При использовании REST API управления для развертывания избегайте состояний гонки, когда ваше приложение немедленно начинает полагаться на правила, развертывание которых еще не завершено.

Обновление наборов правил Realtime Database с помощью REST

Realtime Database предоставляет собственный REST-интерфейс для управления Rules . См. раздел «Управление Rules Firebase Realtime Database через REST» .

Управление наборами правил с помощью REST

Для упрощения управления масштабными развертываниями правил, помимо REST-метода для создания наборов правил и релизов, API управления предоставляет следующие методы:

  • перечисление, получение и удаление наборов правил.
  • список, получение и удаление правил выпуска

Для очень больших развертываний, достигающих со временем лимита в 2500 наборов правил, можно создать логику для удаления самых старых правил с фиксированным временным циклом. Например, чтобы удалить все наборы правил, развернутые более 30 дней назад, можно вызвать метод projects.rulesets.list , проанализировать JSON-список объектов Ruleset по их ключам createTime , а затем вызвать project.rulesets.delete для соответствующих наборов правил по ruleset_id .

Проверяйте обновления с помощью REST.

Наконец, API управления позволяет запускать синтаксические и семантические тесты ресурсов Cloud Firestore и Cloud Storage в ваших производственных проектах.

Тестирование с использованием этого компонента API включает в себя:

  1. Определение JSON-объекта TestSuite для представления набора объектов TestCase .
  2. Отправка TestSuite
  3. Анализ возвращаемых объектов TestResult

Давайте определим объект TestSuite с одним TestCase в файле testcase.json . В этом примере мы передаем исходный код языка Rules непосредственно в REST-запросе, а также набор тестов для выполнения на основе этих правил. Мы указываем ожидаемое значение оценки правил и запрос клиента, на основе которого должен быть протестирован набор правил. Вы также можете указать, насколько полным должен быть отчет о тестировании, используя значение "FULL", чтобы указать, что результаты для всех выражений языка Rules должны быть включены в отчет, включая выражения, которые не были сопоставлены с запросом.

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

Затем мы можем отправить этот TestSuite на оценку с помощью метода projects.test .

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

Возвращаемый TestReport (содержащий статус SUCCESS/FAILURE теста, списки отладочных сообщений, списки посещенных выражений правил и отчеты об их оценке) со статусом SUCCESS подтвердит, что доступ разрешен надлежащим образом.

Управление разрешениями для Cloud Storage Security Rules между различными сервисами.

Если вы создадите Cloud Storage Security Rules , которые используют содержимое документов Cloud Firestore для оценки условий безопасности , вам будет предложено в консоли Firebase или Firebase CLI включить разрешения на подключение двух продуктов.

Если вы решите отключить подобную межсервисную безопасность:

  1. Во-первых, прежде чем отключать эту функцию, отредактируйте свои правила, удалив все операторы, использующие функции Rules для доступа к Cloud Firestore . В противном случае, после отключения этой функции, выполнение Rules приведет к сбою запросов к хранилищу.

  2. Для удаления роли "Firebase Rules Firestore Service Agent" используйте страницу IAM в консоли Google Cloud, следуя инструкциям в руководстве по отзыву ролей .

При следующем сохранении правил, совместимого с различными сервисами, из интерфейса командной строки Firebase или консоли Firebase вам будет предложено повторно включить эту функцию.