Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

Firebase セキュリティ ルールの管理とデプロイ

Firebase CLI を使用する

Firebase CLI を使用してルールを編集し、デプロイします。CLI を使用すると、アプリケーション コードとともにルールがバージョン管理下のもとで維持されます。また、既存のデプロイメント プロセスの一環としてルールをデプロイできます。

構成ファイルを生成する

Firebase CLI を使用して Firebase プロジェクトを構成する際に、プロジェクト ディレクトリ内に .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 コンソールで行った更新を上書きしてしまう可能性があります。

更新をテストする

Firebase エミュレータを使用してローカルに更新内容をテストし、アプリのセキュリティ ルールが意図した通りに動作することを確認します。

更新をデプロイする

セキュリティ ルールを更新してテストしたら、ルールを本番環境にデプロイします。以下のコマンドを使用して、セキュリティ ルールだけを選択的にデプロイするか、通常のデプロイ プロセスの一環としてデプロイします。

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

Realtime Database

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

Firebase コンソールを使用する

Firebase コンソールでルールを編集してデプロイすることもできます。

ルールを編集して更新する

  1. Firebase コンソールを開き、プロジェクトを選択します。
  2. 次に、プロダクト ナビゲーションから [Realtime Database]、[Cloud Firestore]、[Storage] のいずれかを選択し、[ルール] をクリックしてルールエディタを開きます。
  3. エディタでルールを直接編集します。

更新をテストする

Firebase コンソールでルールの動作を直接テストするには、ルール シミュレータを使用します。ルールエディタで [シミュレータ] 画面を開き、設定を変更して [実行] をクリックします。エディタの上部に確認メッセージが表示されます。

更新をデプロイする

更新が意図したとおりのものであることを確認したら、[Publish] をクリックします。

Admin SDK の使用

Node.js 用の Admin SDK を使用すると、プログラムでセキュリティ ルールの作成、管理、デプロイを行うことができます。次の操作を行うことができます。

  • ルールを管理するカスタムツール、スクリプト、ダッシュボード、CI / CD パイプラインを実装する。
  • 複数の Firebase プロジェクト間でルールを管理する。

プログラムでルールを更新する場合は、アプリのアクセス制御に不要な変更を行わないように注意してください。特にルールを更新またはデプロイする場合は、セキュリティを最優先事項として Admin SDK コードを記述する必要があります。

Firebase セキュリティ ルールが完全にデプロイされるまでに数分かかります。デプロイがまだ完了していないルールをアプリで使用すると競合状態が発生します。Admin SDK を使用してルールをデプロイする場合は、こうした競合が発生しないように注意してください。アクセス制御ルールを頻繁に更新する必要がある場合は Cloud Firestore の使用を検討してください。このソリューションでは、頻繁に更新が発生しても競合状態を減らすことができます。

また、次のような制限もあります。

  • シリアル化する場合、ルールは 64 KB 未満にし、UTF-8 でエンコードされたテキストにする必要があります。
  • 1 つのプロジェクトにデプロイできるルールセットの最大数は 2,500 です。この上限に達したら、新しいルールセットを作成する前に古いルールセットを削除する必要があります。

Cloud Storage または Cloud Firestore のルールセットを作成してデプロイする

Admin SDK でセキュリティ ルールを管理する標準的なワークフローでは、次の 3 つのステップを行います。

  1. ルールファイルを作成する(省略可)
  2. ルール セットを作成する
  3. 新しいルールセットをリリースまたはデプロイする

この SDK には、これらのステップを組み合わせ、Cloud Storage と Cloud Firestore のセキュリティ ルールに対する 1 回の API 呼び出しで処理を実行できるメソッドが用意されています。次に例を示します。

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

このパターンは、releaseFirestoreRulesetFromSource() を使用した Cloud Storage ルールでも機能します。

また、ルールファイルをメモリ内オブジェクトとして作成し、作成したルールセットを個別にデプロイすると、これらのイベントを細かく制御できます。次に例を示します。

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

Realtime Database ルールセットを更新する

Admin SDK で Realtime Database ルールセットを更新するには、admin.databasegetRules() メソッドと setRules() メソッドを使用します。ルールセットは、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;
      }
    }

非常に大きなルールセットで、ルール数が上限の 2, 500 に達する可能性がある場合は、定期的に最も古いルールを削除するロジックを作成します。たとえば、デプロイされてから 30 日を経過したルールセットをすべて削除するには、次のようにします。

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.crateTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);