ב-Firebase יש כמה כלים לניהול Rules, כל אחד מהם שימושי במקרים מסוימים, וכל אחד מהם משתמש באותו ממשק API לניהול של כללי האבטחה של Firebase בקצה העורפי.
לא משנה באיזה כלי משתמשים כדי להפעיל אותו, ה-Management API:
- הטמעת מקור של כללים: קבוצת כללים, בדרך כלל קובץ קוד שמכיל הצהרות Firebase Security Rules.
- שמירת המקור שעבר הטמעה כקבוצת כללים שלא ניתן לשנות.
- מעקב אחר הפריסה של כל קבוצת כללים בגרסה. שירותים שתומכים בכללי האבטחה של Firebase מחפשים את הגרסה של הפרויקט כדי להעריך כל בקשה למשאב מאובטח.
- מאפשר להריץ בדיקות תחביריות וסמנטיות של קבוצת כללים.
שימוש ב-CLI של Firebase
באמצעות CLI של Firebase אפשר להעלות מקורות מקומיים ולפרוס גרסאות build. בעזרת הפקודה Firebase Local Emulator Suite ב-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
.
חשוב לוודא שכל העריכות שביצעתם ב-CLI של Firebase משתקפות במסוף Firebase, או שאתם מבצעים עדכונים באופן עקבי באמצעות המסוף Firebase או ה-CLI של Firebase. אחרת, יכול להיות שתמחקו את כל העדכונים שבוצעו במסוף Firebase.
בדיקת העדכונים
ב-Local Emulator Suite יש אמוללטורים לכל המוצרים שתומכים בכללי אבטחה. המנוע של כללי האבטחה בכל אמולטור מבצע הערכה תחבירית וגם סמנטית של הכללים, כך שהוא חורג מהבדיקה התחברית שמציע Security Rules management API.
אם אתם עובדים עם CLI, ה-Suite הוא כלי מצוין לFirebase Security Rules בדיקה. משתמשים ב-Local Emulator Suite כדי לבדוק את העדכונים באופן מקומי ולוודא שה-Rules של האפליקציה מציג את ההתנהגות הרצויה.
פריסה של העדכונים
אחרי שמעדכנים ובודקים את Rules, פורסים את המקורות בסביבת הייצור.
ב-Cloud Firestore Security Rules, בודקים ומעדכנים את קובץ firebase.json
כדי לשייך קבצים מסוג .rules
למסדי הנתונים שמוגדרים כברירת מחדל ולמסדי נתונים נוספים עם שם.
אפשר להשתמש בפקודות הבאות כדי לפרוס את 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.
עריכה ועדכון של הכללים
- פותחים את מסוף Firebase ובוחרים את הפרויקט.
- לאחר מכן, בוחרים באפשרות Realtime Database, Cloud Firestore או אחסון בתפריט הניווט של המוצר, ולוחצים על כללים כדי לעבור לעורך Rules.
- עורכים את הכללים ישירות בעורך.
בדיקת העדכונים
בנוסף לבדיקת התחביר בממשק המשתמש של העורך, אפשר לבדוק את ההתנהגות הסמנטית של Rules באמצעות מסדי הנתונים ומשאבי האחסון של הפרויקט, ישירות במסוף Firebase באמצעות Rules Playground. פותחים את המסך Rules Playground בעורך Rules, משנים את ההגדרות ולוחצים על Run. מחפשים את הודעת האישור בחלק העליון של הכלי.
פריסה של העדכונים
כשאתם מרוצים מהעדכונים, לוחצים על פרסום.
שימוש ב-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 יכול לכלול שלושה שלבים נפרדים:
- יצירת מקור לקובץ כללים (אופציונלי)
- יצירת קבוצת כללים
- פרסום או פריסה של מערכת הכללים החדשה
ה-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 לניהול עצמו. ממשק ה-API לניהול מספק את הגמישות הרבה ביותר.
חשוב גם לשים לב למגבלות הבאות:
- כללים חייבים להיות קטנים מ-256KiB של טקסט בקידוד UTF-8 כשהם עוברים סריאליזציה.
- בכל פרויקט יכולים להיות עד 2,500 כללי מדיניות שנפרסו בסך הכול. אחרי שמגיעים למגבלה הזו, צריך למחוק כמה כללי קבוצות ישנים לפני שיוצרים כללי קבוצות חדשים.
יצירה ופריסה של כללי Cloud Firestore או Cloud Storage באמצעות REST
בדוגמאות בקטע הזה נעשה שימוש ב-Rules של Firestore, אבל הן רלוונטיות גם ל-Cloud Storage Rules.
בדוגמאות נעשה גם שימוש ב-cURL כדי לבצע קריאות ל-API. השלבים להגדרה ולהעברה של אסימוני אימות לא נכללים. אפשר להתנסות ב-API הזה באמצעות API Explorer שמשולב במסמכי העזרה.
השלבים הרגילים ליצירה ולפריסה של מערכת כללים באמצעות ממשק ה-API לניהול הם:
- יצירת מקורות של קובצי כללים
- יצירת קבוצת כללים
- משיקים (פורסים) את מערכת הכללים החדשה.
יצירת מקור
נניח שאתם עובדים על פרויקט Firebase בשם secure_commerce
ואתם רוצים לפרוס 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 לניהול לצורך פריסה, חשוב להימנע ממצבים של תחרות (race condition) שבהם האפליקציה מסתמכת באופן מיידי על כללים שהפריסה שלהם עדיין לא הושלמה.
עדכון של כללי Realtime Database באמצעות REST
ל-Realtime Database יש ממשק REST משלו לניהול Rules. למידע נוסף, ראו ניהול Realtime Database Rules ב-Firebase באמצעות REST.
ניהול של כללי קבוצות באמצעות REST
כדי לעזור בניהול פריסות של כללים גדולים, בנוסף ל-method ל-REST ליצירת סטים של כללים ופרסומים, ב-Management API יש שיטות ל:
- הצגת רשימה של קבוצות כללים, אחזור שלהן ומחיקה שלהן
- הצגה, אחזור ומחיקה של גרסאות של כללים
בפריסות גדולות מאוד שמגיעות עם הזמן למגבלה של 2,500 כללי מדיניות, אפשר ליצור לוגיקה למחיקה של הכללים הישנים ביותר במחזור זמן קבוע. לדוגמה, כדי למחוק את כל כללי המדיניות שנפרסו במשך יותר מ-30 יום, אפשר להפעיל את השיטה projects.rulesets.list
, לנתח את רשימת ה-JSON של אובייקטי Ruleset
לפי המפתחות שלהם createTime
, ואז להפעיל את project.rulesets.delete
על כללי המדיניות המתאימים לפי ruleset_id
.
בדיקת העדכונים באמצעות REST
לבסוף, באמצעות Management API אפשר להריץ בדיקות תחביריות וסמנטיות על משאבי Cloud Firestore ו-Cloud Storage בפרויקטים בסביבת הייצור.
הבדיקה עם הרכיב הזה של ה-API כוללת:
- הגדרת אובייקט JSON מסוג
TestSuite
שמייצג קבוצה של אובייקטים מסוגTestCase
- שליחת
TestSuite
- ניתוח אובייקטים
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 או ב-CLI של Firebase להפעיל הרשאות לחיבור בין שני המוצרים.
אם תחליטו להשבית את האבטחה הזו בין שירותים:
לפני השבתת התכונה, צריך לערוך את הכללים ולהסיר את כל ההצהרות שמשתמשות בפונקציות Rules כדי לגשת ל-Cloud Firestore. אחרת, אחרי שהתכונה תושבת, הבדיקות של Rules יגרמו לכישלון של בקשות האחסון.
בדף IAM במסוף Google Cloud, מוחקים את התפקיד 'סוכן שירות של Firebase Rules Firestore' לפי המדריך של Cloud לביטול תפקידים.
תוצג בקשה להפעיל מחדש את התכונה בפעם הבאה שתשמרו כללים חוצי-שירותים דרך ה-CLI של Firebase או דרך מסוף Firebase.