Skip to main content

Write security rules

Security Rules are a powerful access control mechanism that allows you to precisely control data access permissions. Through flexible rule syntax, you can implement combinations of read and write controls at different granularities on database collections or buckets, ensuring data security.

Default Rules

By default, security rules deny all data access requests. This "deny by default" security policy ensures that your data will not be accessed unless explicitly granted permissions.

{}  // An empty rule object indicates that all access is denied.

User Authentication

When an authenticated user makes a request, the system automatically populates the auth variable with the user's unique identifier uid and login method loginType. When an unauthenticated user makes a request, the auth variable value is null.

Through the auth variable, you can control data access based on user identity using the following common approaches:

  • Public Access: Without evaluating the auth value, all users are allowed to access
  • Logged-in Users Only: Check auth != null to ensure the user is logged in
  • User Private Data: Check whether auth.uid equals the resource openid to ensure that users can only access their own data
  • Specific Login Method Restrictions: Check auth.loginType, for example, to restrict access by anonymously logged-in users (auth.loginType != "ANONYMOUS")

Public Access Rules

Any rule that does not consider auth can be regarded as a public (public) rule because it does not rely on the user's authentication context. This type of rule is highly applicable in scenarios involving public data, such as static resource content, public information, etc.

{
"read": "doc._openid != null"
}

Logged-in Users Only

In many application scenarios, you may wish to restrict certain data to logged-in users only. For example, only logged-in users can view discussions or user comments in forums. Since the auth variable value is null for all unauthenticated users, the following rule can be defined:

{
"read": "auth != null" // Only logged-in users can read data
}

Readable by All Users, Writable Only by the Creator

The data records the owner user ID of the current data through the _openid field:

{
"read": true, // All users can read
"write": "doc._openid == auth.openid || doc._openid == auth.uid" // Only the creator can modify
}

Note: auth.openid is used for WeChat login methods, auth.uid is used for non-WeChat login methods.

Readable and writable only by the creator

The data records the owner user ID of the current data through the _openid field:

{
"read": "doc._openid == auth.openid || doc._openid == auth.uid", // Only the creator can read
"write": "doc._openid == auth.openid || doc._openid == auth.uid" // Only the creator can modify
}

Note: auth.openid is used for WeChat login methods, auth.uid is used for non-WeChat login methods.

Readable by All Users, Writable Only by Administrators

This rule applies to public content: regular users can view but cannot modify it; only administrators can modify it via cloud functions or the admin console.

{
"read": true, // All users can read
"write": false // Regular users cannot write; administrators can perform operations via cloud functions or the console
}

Readable and Writable Only by Administrators

This rule applies to sensitive data: only administrators can access it via cloud functions or the admin console.

{
"read": false, // Regular users cannot read
"write": false // Regular users cannot write
}

Note: Rules set to false indicate that regular clients cannot access them, but administrators can still perform operations via cloud functions or the console.

Data Validation

Security Rules not only control access permissions but also serve for data validation. You can conditionally write new data based on existing data in databases or storage partitions using Security Rules. By writing data validation rules, you can restrict write operations according to the content of new data being written, ensuring data conforms to expected formats and business rules.

Restrictions and Validation on New Data

If you need to validate fields for newly created data—for example, to reject creating any documents containing a ranking field (to prevent users from self-assigning rankings)—you can impose restrictions in the create condition:

{
"read": true,
"create": "request.data.ranking == undefined", // Reject the creation of documents containing the ranking field
"update": true // Allow updates
}

Access Control Based on Existing Data

Many applications store access control information as fields within database documents. Security Rules can manage access permissions based on the attributes of these document data fields, enabling more complex permission management.

To implement role-based access control, you need to define corresponding role and permission attributes in user data. Security Rules will examine requests based on these data attributes to determine whether to allow or deny access.

Practical Example: Access Control in Education Systems

For example, in an education system, we need to store student grades and assign different access permissions to distinct user groups:

  • The "Students" group can only view their own grades (read-only access)
  • The "Teachers" group can view and modify grades for all students in the subjects they teach (read-write access)

User Table (user collection) can be designed with the following structure:

{
userID: userID: string, // User Unique ID
role: role: string, // User role: 'STUDENT' or 'TEACHER'
projects: projects: string[] // List of subjects taught by the teacher (only present for TEACHER role)
}

Grade Table (score collection) designed as follows:

{
studentID: studentID: string, // Student ID
project: project: string, // Subject Name
score: score: number // Score
}

The security rules for the Grade Table can be set as:

{
"read": "get(`database.user.${auth.uid}`).role == 'STUDENT' && doc.studentID == auth.uid || (get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects)",
"write": "get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects"
}

This rule indicates:

  1. Students can only view their own grades (studentID == auth.uid)
  2. Teachers can view grades for all students in the subjects they teach
  3. Only teachers can modify grades for the subjects they teach