Mengelola dan men-deploy Aturan Keamanan Firebase

Firebase menyediakan beberapa alat untuk mengelola Aturan, masing-masing berguna dalam kasus tertentu, dan masing-masing menggunakan API pengelolaan Aturan Keamanan Firebase back-end yang sama.

Apa pun alat yang digunakan untuk memanggilnya, API pengelolaan akan:

  • Menyerap sumber Aturan: sekumpulan aturan, biasanya file kode yang berisi pernyataan Aturan Keamanan Firebase.
  • Menyimpan sumber yang diserap sebagai kumpulan aturan yang tidak dapat diubah.
  • Melacak deployment setiap kumpulan aturan dalam suatu rilis. Layanan yang mengaktifkan Aturan Keamanan Firebase akan menelusuri rilis project untuk mengevaluasi setiap permintaan guna menemukan resource yang aman.
  • Memberikan kemampuan untuk menjalankan pengujian sintaksis dan semantik terhadap kumpulan aturan.

Menggunakan Firebase CLI

Dengan Firebase CLI, Anda dapat mengupload sumber lokal dan men-deploy rilis. Dengan Firebase Local Emulator Suite CLI, Anda dapat melakukan pengujian lokal lengkap terhadap sumber.

Dengan CLI, Anda dapat menjaga agar kontrol versi tetap diterapkan pada aturan dengan kode aplikasi dan men-deploy aturan sebagai bagian dari proses deployment yang ada.

Membuat file konfigurasi

Saat mengonfigurasi project Firebase menggunakan Firebase CLI, Anda membuat file konfigurasi .rules di direktori project. Gunakan perintah berikut untuk mulai mengonfigurasi project Firebase Anda:

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

Mengedit dan memperbarui aturan

Edit sumber aturan Anda secara langsung di file konfigurasi .rules. Pastikan bahwa edit apa pun yang diterapkan di Firebase CLI juga diterapkan di Firebase console, atau bahwa Anda konsisten melakukan pembaruan dengan Firebase console saja atau Firebase CLI saja. Jika tidak, Anda kemungkinan akan menimpa pembaruan yang diterapkan di Firebase console.

Menguji pembaruan

Local Emulator Suite menyediakan emulator untuk semua produk yang mengaktifkan Aturan Keamanan. Mesin Aturan Keamanan untuk setiap emulator melakukan evaluasi sintaksis dan semantik terhadap aturan, sehingga melebihi pengujian sintaksis yang ditawarkan API pengelolaan Aturan Keamanan.

Jika Anda menggunakan CLI, Suite adalah alat yang sangat cocok untuk pengujian Aturan Keamanan Firebase. Gunakan Local Emulator Suite untuk menguji pembaruan secara lokal dan mengonfirmasi bahwa Aturan aplikasi menunjukkan perilaku yang Anda inginkan.

Men-deploy pembaruan

Setelah memperbarui dan menguji Aturan, deploy sumber ke produksi. Gunakan perintah berikut untuk secara selektif men-deploy Aturan sendiri atau men-deploy-nya sebagai bagian dari proses deployment normal.

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

Menggunakan Firebase console

Anda juga dapat mengedit sumber Aturan dan men-deploy-nya sebagai rilis dari Firebase console. Pengujian sintaksis dilakukan saat Anda mengedit di UI Firebase console, dan pengujian semantik tersedia menggunakan Simulator Aturan.

Mengedit dan memperbarui aturan

  1. Buka Firebase console dan pilih project Anda.
  2. Kemudian, pilih Realtime Database, Cloud Firestore, atau Storage dari navigasi produk, lalu klik Aturan untuk membuka editor Aturan.
  3. Edit aturan Anda langsung di editor.

Menguji pembaruan

Selain menguji sintaksis di UI editor, Anda dapat menguji perilaku Aturan semantik, menggunakan resource database dan penyimpanan project, secara langsung di Firebase console, menggunakan Simulator Aturan. Buka layar Simulator Aturan di editor Aturan, ubah setelan, lalu klik Jalankan. Cari pesan konfirmasi di bagian atas editor.

Men-deploy pembaruan

Setelah puas dengan pembaruan yang diharapkan, klik Publikasikan.

Menggunakan Admin SDK

Anda dapat menggunakan Admin SDK untuk kumpulan aturan Node.js. Dengan akses terprogram ini, Anda dapat:

  • Menerapkan alat, skrip, dasbor, dan pipeline CI/CD khusus untuk mengelola aturan.
  • Mengelola aturan dengan lebih mudah di beberapa project Firebase.

Saat memperbarui aturan secara terprogram, hindari membuat perubahan yang tidak diinginkan pada kontrol akses untuk aplikasi Anda. Tulis kode Admin SDK Anda dengan memperhatikan keamanan, khususnya saat memperbarui atau men-deploy aturan.

Hal penting lainnya yang perlu diingat adalah bahwa rilis Aturan Keamanan Firebase memerlukan waktu beberapa menit untuk diterapkan sepenuhnya. Saat menggunakan Admin SDK untuk men-deploy aturan, pastikan untuk menghindari kondisi race yang menyebabkan aplikasi langsung bergantung pada aturan yang belum selesai di-deploy. Jika kasus penggunaan Anda memerlukan pembaruan berkala pada aturan kontrol akses, pertimbangkan solusi penggunaan Cloud Firestore, yang dirancang untuk mengurangi kondisi race meskipun aturan tersebut sering diperbarui.

Perhatikan juga batasan berikut:

  • Aturan harus lebih kecil dari 256 KiB teks berenkode UTF-8 saat diserialisasi.
  • Sebuah project dapat memiliki maksimal 2.500 kumpulan aturan yang di-deploy. Setelah batas ini tercapai, Anda harus menghapus beberapa kumpulan aturan lama sebelum membuat yang baru.

Membuat dan men-deploy kumpulan aturan Cloud Storage atau Cloud Firestore

Alur kerja standar untuk mengelola aturan keamanan dengan Admin SDK dapat mencakup tiga langkah berbeda:

  1. Membuat sumber file aturan (opsional)
  2. Membuat kumpulan aturan
  3. Merilis atau men-deploy kumpulan aturan baru

SDK menyediakan metode untuk menggabungkan langkah-langkah ini ke dalam satu panggilan API untuk aturan keamanan Cloud Storage dan Cloud Firestore. Contoh:

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

Pola yang sama ini berfungsi untuk aturan Cloud Storage dengan releaseFirestoreRulesetFromSource().

Cara lainnya, Anda dapat membuat file aturan sebagai objek dalam memori, membuat kumpulan aturan, dan men-deploy kumpulan aturan secara terpisah demi mendapatkan kontrol yang lebih dekat terhadap peristiwa ini. Contoh:

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

Memperbarui kumpulan aturan Realtime Database

Untuk memperbarui kumpulan aturan Realtime Database dengan Admin SDK, gunakan metode getRules() dan setRules() dari admin.database. Anda dapat mengambil kumpulan aturan dalam format JSON, atau sebagai string dengan menyertakan komentar.

Untuk memperbarui kumpulan aturan:

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

Mengelola kumpulan aturan

Untuk membantu mengelola kumpulan aturan berukuran besar, Admin SDK memungkinkan Anda melihat semua aturan yang ada dalam daftar dengan admin.securityRules().listRulesetMetadata. Contoh:

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

Untuk deployment yang sangat besar yang mencapai batas 2.500 kumpulan aturan sepanjang waktu, Anda dapat membuat logika untuk menghapus aturan yang paling lama dalam suatu siklus waktu tetap. Misalnya, untuk menghapus semua kumpulan aturan yang di-deploy selama lebih dari 30 hari:

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

Menggunakan REST API

Alat-alat yang dijelaskan di atas cocok untuk berbagai alur kerja, tetapi Anda mungkin ingin mengelola dan men-deploy Aturan Keamanan Firebase menggunakan API pengelolaan itu sendiri. API pengelolaan memberi Anda fleksibilitas terbaik.

Perlu diketahui bahwa rilis Aturan Keamanan Firebase memerlukan waktu beberapa menit untuk diterapkan sepenuhnya. Saat menggunakan REST API pengelolaan untuk men-deploy, pastikan untuk menghindari kondisi race yang menyebabkan aplikasi langsung bergantung pada aturan yang belum selesai di-deploy.

Perhatikan juga batasan berikut:

  • Aturan harus lebih kecil dari 256 KiB teks berenkode UTF-8 saat diserialisasi.
  • Sebuah project dapat memiliki maksimal 2.500 kumpulan aturan yang di-deploy. Setelah batas ini tercapai, Anda harus menghapus beberapa kumpulan aturan lama sebelum membuat yang baru.

Membuat dan men-deploy kumpulan aturan Cloud Storage atau Cloud Firestore dengan REST

Contoh di bagian ini menggunakan Aturan Cloud Storage, tetapi juga berlaku untuk Aturan Cloud Firestore.

Contoh tersebut juga menggunakan cURL untuk melakukan panggilan API. Langkah-langkah untuk menyiapkan dan meneruskan token autentikasi dihilangkan. Anda dapat bereksperimen dengan API ini menggunakan API Explorer yang terintegrasi dengan dokumentasi referensi.

Langkah-langkah umum untuk membuat dan men-deploy kumpulan aturan menggunakan API pengelolaan adalah:

  1. Membuat sumber file aturan
  2. Membuat kumpulan aturan
  3. Merilis (men-deploy) kumpulan aturan baru

Anggaplah Anda sedang mengerjakan project Firebase secure_commerce dan ingin men-deploy Aturan Cloud Storage yang terkunci. Anda dapat menerapkan aturan ini dalam file storage.rules.

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

Sekarang, buat sidik jari berenkode base64 untuk file ini. Anda kemudian dapat menggunakan sumber dalam file ini untuk mengisi payload yang diperlukan guna membuat kumpulan aturan dengan panggilan REST projects.rulesets.create. Di sini, kita menggunakan perintah cat untuk menyisipkan konten storage.rules ke dalam payload REST.

curl -X POST -d '{
  "source": {
    {
      "files": [
        {
          "content": "' $(cat storage.rules) '",
          "name": "storage.rules",
          "fingerprint": <sha fingerprint>
        }
      ]
    }
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

API menampilkan respons validasi dan nama kumpulan aturan, misalnya projects/secure_commerce/rulesets/uuid123. Jika kumpulan aturan valid, langkah terakhir adalah men-deploy kumpulan aturan baru ke dalam suatu rilis tertentu.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/prod/v23   "  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

Memperbarui kumpulan aturan Realtime Database dengan REST

Realtime Database menyediakan antarmuka REST-nya sendiri untuk mengelola Aturan. Buka Mengelola Aturan Firebase Realtime Database melalui REST.

Mengelola kumpulan aturan dengan REST

Untuk membantu mengelola deployment aturan yang besar, selain metode REST untuk membuat kumpulan aturan dan rilis, API pengelolaan menyediakan metode untuk:

  • membuat daftar, memperoleh, dan menghapus kumpulan aturan
  • membuat daftar, memperoleh, dan menghapus rilis aturan

Untuk deployment yang sangat besar yang mencapai batas 2.500 kumpulan aturan sepanjang waktu, Anda dapat membuat logika untuk menghapus aturan yang paling lama dalam suatu siklus waktu tetap. Misalnya, untuk menghapus semua kumpulan aturan yang di-deploy selama lebih dari 30 hari, Anda dapat memanggil metode projects.rulesets.list, mengurai daftar JSON objek Ruleset pada kunci createTime-nya, lalu memanggil project.rulesets.delete pada kumpulan aturan yang sesuai dengan ruleset_id.

Menguji pembaruan dengan REST

Terakhir, API pengelolaan memungkinkan Anda menjalankan pengujian sintaksis dan semantik pada resource Cloud Firestore dan Cloud Storage dalam project produksi Anda.

Pengujian dengan komponen API ini terdiri dari:

  1. Menentukan objek JSON TestSuite untuk mewakili kumpulan objek TestCase
  2. Mengirimkan TestSuite
  3. Mengurai objek TestResult yang ditampilkan

Mari tentukan objek TestSuite dengan satu TestCase dalam file testcase.json. Dalam contoh ini, kita meneruskan sumber bahasa Aturan yang sesuai dengan payload REST, bersama rangkaian pengujian untuk dijalankan pada aturan tersebut. Kita menentukan ekspektasi evaluasi Aturan, dan permintaan klien yang akan digunakan untuk menguji kumpulan aturan. Anda juga dapat menentukan kelengkapan laporan pengujian, menggunakan nilai "LENGKAP" untuk menunjukkan hasil untuk semua ekspresi bahasa Aturan yang harus disertakan dalam laporan, termasuk ekspresi yang tidak cocok dengan permintaan.

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

Selanjutnya, kita dapat mengirimkan TestSuite ini untuk evaluasi dengan metode projects.test.

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

TestReport yang ditampilkan (berisi status SUKSES/GAGAL pengujian, daftar pesan debug, daftar ekspresi Aturan yang dikunjungi dan laporan evaluasinya) akan mengonfirmasi dengan status SUKSES bahwa akses telah diizinkan dengan benar.