ניהול ופריסה של כללי האבטחה ב-Firebase

ב-Firebase יש כמה כלים לניהול Rules, כל אחד מהם שימושי במקרים מסוימים, וכל אחד מהם משתמש באותו ממשק API לניהול כללי האבטחה של Firebase בקצה העורפי.

לא משנה באיזה כלי משתמשים כדי להפעיל אותו, ה-Management API:

  • מטמיע מקור של כללים: קבוצת כללים, בדרך כלל קובץ קוד שמכיל Firebase Security Rules הצהרות.
  • שמירת המקור שעבר הטמעה כקבוצת כללים שלא ניתן לשנות.
  • מעקב אחר הפריסה של כל קבוצת כללים בגרסה. אבטחה ב-Firebase שירותים שמופעלים בהם כללים מחפשים את פריט התוכן של פרויקט כדי להעריך כל בקשה למשאב מאובטח.
  • מאפשרת להריץ בדיקות תחביריות וסמנטיות של קבוצות כללים.

שימוש ב-CLI של Firebase

בעזרת CLI של Firebase, אפשר להעלות מקורות מקומיים ולפרוס גרסאות. שם ה-CLI באמצעות Firebase Local Emulator Suite אפשר לבצע בדיקה מקומית מלאה של מקורות.

השימוש ב-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.

חשוב לוודא שכל העריכות שמבצעים ב-CLI של Firebase באות לידי ביטוי Firebase, או שאתם מבצעים עדכונים באופן עקבי באמצעות מסוף Firebase או ה-CLI של Firebase. אחרת, אפשר להחליף עדכונים שבוצעו במסוף Firebase.

בדיקת העדכונים

Local Emulator Suite מספק אמולטורים לכל כללי האבטחה שבהם מופעלים כללי אבטחה מוצרים. מנגנון כללי האבטחה של כל אמולטור מבצע הן פעולות תחביריות וההערכה הסמנטית של כללים, ובכך תחרוג מהבדיקה הסמנטית של הצעות של ממשקי API לניהול כללי אבטחה.

אם אתם עובדים עם CLI, ה-Suite הוא כלי מצוין ל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 או אחסון מתוך בתפריט הניווט של המוצרים, ואז ללחוץ על כללים כדי לעבור אל עורך Rules.
  3. עורכים את הכללים ישירות בעורך.

בדיקת העדכונים

בנוסף לבדיקת התחביר בממשק המשתמש של העריכה, אפשר לבדוק סמנטי התנהגות של Rules, באמצעות מסד הנתונים ומשאבי האחסון של הפרויקט, ישירות במסוף Firebase, באמצעות הפקודה Playground של Rules. פותחים את מגרש המשחקים של הכללים בעורך Rules, משנים את ההגדרות ולוחצים על הפעלה. מחפשים את הודעת האישור שמוצגת בחלק העליון של כלי העריכה.

פריסת העדכונים

אם העדכונים תואמים לציפיות שלכם, לוחצים על פרסום.

שימוש ב-Admin SDK

אפשר להשתמש ב-Admin SDK ל-Node.js מערכי כללים. בעזרת הגישה הפרוגרמטית הזו, אתם יכולים:

  • תטמיעו כלים מותאמים אישית, סקריפטים, מרכזי בקרה וצינורות עיבוד נתונים של CI/CD לניהול כללים.
  • קל יותר לנהל כללים בכמה פרויקטים של Firebase.

כשמעדכנים כללים באופן פרוגרמטי, חשוב מאוד להימנע שינויים לא מכוונים בבקרת הגישה של האפליקציה. לכתוב את קוד אחד (Admin SDK) אבטחה בראש סדר העדיפויות, במיוחד בעת עדכון או פריסה של כללים.

חשוב לזכור גם שעדכון Firebase Security Rules מופץ באופן מלא תוך כמה דקות. כשמשתמשים ב-Admin SDK כדי לפרוס כללי, כדי להימנע ממרוץ תהליכים שבו האפליקציה מסתמכת באופן מיידי בכללים שהפריסה שלהם עדיין לא הושלמה. אם בתרחיש לדוגמה שלכם יש צורך עדכונים תכופים של הכללים של בקרת הגישה, כדאי לשקול פתרונות באמצעות Cloud Firestore, שמטרתו להפחית מרוץ תהליכים למרות עדכונים תכופים.

חשוב גם לשים לב למגבלות הבאות:

  • כשהכללים עוברים סריאליזציה, הגודל שלהם צריך להיות קטן מ-256KiB של טקסט בקידוד UTF-8.
  • פרויקט יכול לכלול עד 2,500 מערכי כללים פרוסים. אחרי שהמגבלה הזו עליך למחוק כמה קבוצות כללים ישנות לפני יצירת קבוצות כללים חדשות.

יצירה ופריסה של קבוצות כללים 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;
      }
    }

בפריסות גדולות מאוד שמגיעות למגבלה של 2,500 כללים לאורך זמן, ניתן ליצור לוגיקה למחיקת הכללים הישנים ביותר במחזור זמן קבוע. לדוגמה, כדי למחוק את כל קבוצות הכללים שנפרסו במשך יותר מ-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.`);

שימוש ב-API ל-REST

הכלים שמתוארים למעלה מתאימים היטב לתהליכי עבודה שונים, כולל ניהול Firebase Security Rules עבור מספר מסדי נתונים של Cloud Firestore בפרויקט, אבל כדאי גם לנהל ולפרוס את Firebase Security Rules באמצעות ממשק ה-API לניהול עצמו. ה-Management API מספק את הגמישות הגבוהה ביותר.

כמו כן, חשוב לשים לב למגבלות הבאות:

  • כשהכללים עוברים סריאליזציה, הגודל שלהם צריך להיות קטן מ-256KiB של טקסט בקידוד UTF-8.
  • פרויקט יכול לכלול עד 2,500 מערכי כללים פרוסים. אחרי שמגיעים למגבלה הזו, צריך למחוק כמה כללי קבוצות ישנים לפני שיוצרים כללי קבוצות חדשים.

יצירה ופריסה של כללי Cloud Firestore או Cloud Storage באמצעות REST

הדוגמאות בקטע הזה משתמשות ב-Firestore Rules, אבל הן חלות על וגם Cloud Storage Rules.

בדוגמאות נעשה גם שימוש ב-cURL כדי לבצע קריאות ל-API. שלבים להגדרה ולהעברה אסימוני אימות מושמטים. אפשר להתנסות ב-API הזה באמצעות API Explorer משולב מסמכי עזר.

שלבים אופייניים ליצירה ולפריסה של ערכת כללים באמצעות ממשק ה-API לניהול הם:

  1. יצירת מקורות קבצים של כללים
  2. יצירת קבוצת כללים
  3. פרסום (פריסה) של קבוצת הכללים החדשה.

יצירת מקור

נניח שאתם עובדים על פרויקט secure_commerce Firebase ואתם רוצים לפרוס את Cloud Firestore Rules נעולה במסד נתונים לפרויקט בשם 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 במטען הייעודי (payload) של 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 יסופקו באופן מלא להפיץ. כשמשתמשים ב-API ל-REST לניהול, חשוב להימנע ממרוץ תהליכים תנאים שבהם האפליקציה מסתמכת באופן מיידי על כללים שהפריסה שלהם לא מיושמת עדיין לא הושלמה.

עדכון של כללי Realtime Database באמצעות REST

ל-Realtime Database יש ממשק REST משלו לניהול Rules. צפייה ניהול של Firebase Realtime Database Rules דרך REST.

ניהול מערכי כללים באמצעות REST

לעזור בניהול פריסות של כללים גדולות, בנוסף ל-method REST בשביל ליצירת קבוצות כללים וגרסאות, ה-Management API מספק שיטות לביצוע:

  • הצגה, קבלה ומחיקה של מערכי כללים
  • הצגה, קבלה ומחיקה של גרסאות של כללים

בפריסות גדולות מאוד שמגיעות למגבלה של 2,500 כללים לאורך זמן, ניתן ליצור לוגיקה למחיקת הכללים הישנים ביותר במחזור זמן קבוע. לדוגמה, כדי למחוק את כל כללי המדיניות שנפרסו במשך יותר מ-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 שפה חדשה שמוטבעת במטען הייעודי (payload) של 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 שהוחזר (מכיל סטטוס הצלחה/כשל של הבדיקה, רשימות של הודעות ניפוי באגים, רשימות של ביטויים של כללים לביקור ודוחות ההערכה שלהם) הפעולה תגרום לאישור הסטטוס CCPA שהגישה מותרת באופן תקין.

ניהול ההרשאות בשירותים השונים Cloud Storage Security Rules

אם יוצרים Cloud Storage Security Rules שנעשה בהם שימוש בCloud Firestore תכנים של מסמכים כדי להעריך את תנאי האבטחה, תופיע בקשה להפעיל במסוף Firebase או ב-CLI של Firebase הרשאות לחיבור בין שני המוצרים.

אם תחליטו להשבית את האבטחה בין שירותים שונים:

  1. קודם כול, לפני שתשביתו את התכונה, תצטרכו לערוך את הכללים ולהסיר את כל הצהרות שמשתמשות בפונקציות Rules כדי לגשת אל Cloud Firestore. אחרת, אחרי השבתת התכונה, Rules הערכות לגרום לבקשות אחסון להיכשל.

  2. משתמשים בדף IAM במסוף Google Cloud כדי למחוק את Firebase כללים של סוכן שירות של Firestore" לפי ההוראות במדריך של Cloud שלילת תפקידים.

בפעם הבאה ששומרים את התכונה תופיע בקשה להפעיל מחדש כללים בכמה שירותים שונים מה-CLI של Firebase או מהמסוף של Firebase.