Skip to main content

Authoring Security Rules

Security rules allow you to control data access permissions. Through flexible rule syntax, different granularities of read-write control combinations can be implemented on collections or buckets.

Default Rules

By default, security rules deny all data access.

{}

User Identity Authentication

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

Through the auth variable, file access can be controlled based on identity using the following common methods:

  • Public: The auth value is not evaluated.
  • Accessible only to logged-in users: Check that auth is not null.
  • User-private: Check if auth.uid equals the resource's openid.
  • For a specific login method: Restrict access to anonymously logged-in users by checking that auth.loginType is not ANONYMOUS

Public

Any rule that does not consider auth can be regarded as a public rule, as it disregards the user's authentication context. These rules are well-suited for scenarios involving the presentation of public data (static resource content).

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

Accessible to logged-in users

In some cases, you may want to restrict access to user data to only logged-in users. For example, only logged-in users can view discussions in the forum. Since the auth variable is null for all unauthenticated users, you can set the following rules:

{
"read": "auth != null"
}

Readable by all users, writable only by the creator and administrators

Data records the owner user ID of the current data via _openid

{
"read": true,
"write": "doc._openid == auth.openid", // Login method is WeChat.
"write": "doc._openid == auth.uid" // Login method is not WeChat.
}

Readable and writable only by the creator and administrators

Data records the owner user ID of the current data via _openid

{
"read": "doc._openid == auth.openid", //Login method is WeChat.
"read": "doc._openid == auth.uid", // Log-in method is not WeChat.
"write": "doc._openid == auth.openid", //Login method is WeChat.
"write": "doc._openid == auth.uid" // Login method is not WeChat.
}

Readable by all users, writable only by administrators

{
"read": true,
"write": false
}

Readable and writable only by administrators

{
"read": false,
"write": false
}

Data Validation

You can use security rules to conditionally write new data based on existing data in the database or storage partition. You can also write rules to enforce data validation by restricting write operations based on the new data being written.

Limitations on New Data

If you want to ensure that documents containing specific fields have not been created yet. For example, if you want to reject the creation of all documents containing the ranking field, you can prohibit it in the create condition.

{
// ... //
"create": "request.data.ranking == undefined"
}

Using Existing Data

Many applications store access control information as fields within documents in the database. Security rules can control access based on document data attributes:

To implement this access control, corresponding attributes must be defined in the user data. Security rules inspect requests based on data attributes to determine whether to allow or deny them. For example, when storing grades, different access levels can be assigned to distinct user groups: grant read-only permission to the "student" group, and grant read-write permission for the subjects they teach to the "teacher" group. The user table (user collection) can be designed with the following structure:

{
userID: string, // Unique user id
role: string, // STUDENT, TEACHER,
projects: string[] // Subjects taught by the teacher
}

Score table (score) is designed as follows:

{
studentID: string,
project: string,
score: number
}

The rules for the score table can be set as:

{
"read": "get(`database.user.${auth.uid}`).role == 'STUDENT' || (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"
}