Navigation

Query Roles

Overview

A MongoDB service role is a group of document-level and field-level CRUD permissions that Stitch evaluates and enforces for each document that matches an incoming request.

Roles define what the user who issued a query is allowed to do with a particular document, including which fields they can read and write to and whether or not they can insert or delete entire documents. Every role is associated with a specific collection in a linked cluster and any collection can include multiple roles.

Role Evaluation Process

When Stitch receives a query request, it determines which documents in the collection the query applies to and evaluates a separate role for each document. To assign a role to a document, Stitch steps through each role definition in order and evaluates the Apply When JSON expression that you defined for the role. If a role’s Apply When expression evaluates to true, Stitch assigns the role to the current document and moves on to the next document. If the expression evaluates to false, Stitch evaluates the next role definition. If no roles apply to a document, Stitch withholds the entire document and prevents any modifications.

Query Role Configuration

{
   "name": "<Role Name>",
   "apply_when": <JSON Expression>,
   "insert": <boolean|JSON Expression>,
   "delete": <boolean|JSON Expression>,
   "read": <boolean|JSON Expression>,
   "write": <boolean|JSON Expression>,
   "fields": {
      "<Field Name>": {
         "read": <boolean|JSON Expression>,
         "write": <boolean|JSON Expression>,
         "fields": <Fields Document>
      },
      ...
   },
   "additional_fields": {
     "read": <boolean|JSON Expression>,
     "write": <boolean|JSON Expression>
   },
}
Field Required/Optional Description
name Required The name of the role. Role names are useful for identifying and distinguishing between roles. Limited to 100 characters or fewer.
apply_when Required A JSON Expression that evaluates to true when this role should be applied.
read
Optional
Default: false

A boolean or JSON Expression that evaluates to true if the role has permission to read all fields in the document.

Document-level read permissions take priority over any field-level permissions. If a role has a document-level read rule, it applies to all fields in the document and cannot be overridden. To define specific field-level rules with a default fallback, use additional_fields instead.

write
Optional
Default: false

A boolean or JSON Expression that evaluates to true if the role has permission to add, modify, or remove all fields in the document.

Document-level write permissions take priority over any field-level permissions. If a role has a document-level write rule, it applies to all fields in the document and cannot be overridden. To define specific field-level rules with a default fallback, use additional_fields instead.

Implicit Read Permission

Any time a role has write permission for a particular scope it also has read permission even if that is not explicitly defined.

MongoDB Expansions

You can use MongoDB expansions, like %%root and %%prevRoot, in write JSON expressions.

insert
Optional
Default: false

A boolean or JSON Expression that evaluates to true if the role has permission to insert a new document into the collection.

Note

Document-level insert permission does not imply that a role can insert any document. The role must also have write permission for all fields in an inserted document for the insert to succeed.

delete
Optional
Default: false
A boolean or JSON Expression that evaluates to true if the role has permission to delete a document from the collection.
fields
Optional
Default: {}

A document where the value of each field defines the role’s field-level read and write permissions for the corresponding field in a queried document.

"fields": {
  "<Field Name>": {
     "read": <boolean|JSON Expression>,
     "write": <boolean|JSON Expression>,
     "fields": <Fields Document>
  },
  ...
}

Permission Priority

Document-level read or write permissions override all field-level permissions of the same type. If permissions are defined for a field that contains an embedded document, those permissions override any permissions defined for the document’s embedded fields.

fields.<Field Name>.read
Optional
Default: false
A boolean or JSON Expression that evaluates to true if the role has permission to read the field.
fields.<Field Name>.write
Optional
Default: false
A boolean or JSON Expression that evaluates to true if the role has permission to add, modify, or remove the field.
fields.<Field Name>.fields
Optional
Default: {}

A fields document that defines read and write permissions for fields that are embedded within this field in a queried document.

See the Field-level Permissions for Embedded Documents role pattern for more information.

additional_fields
Optional
Default: {}

A document that defines the role’s field-level read and write permissions for any fields in a queried document that don’t have explicitly defined permissions.

"additional_fields": {
  "read": <boolean|JSON Expression>,
  "write": <boolean|JSON Expression>
}
additional_fields.read
Optional
Default: false
A boolean or JSON Expression that evaluates to true if the role has permission to read any field that does not have a field-level permission definition.
additional_fields.write
Optional
Default: false
A boolean or JSON Expression that evaluates to true if the role has permission to add, modify, or remove any field that does not have a field-level permission definition.

Role Templates

This section demonstrates patterns for common use cases that you might encounter when you define roles for your own collection.

Apply When Expressions

Stitch determines if a role applies to a given document by evaluating the Apply When expression that you define for each role.

This section contains Apply When templates for common scenarios. To apply an expression to a role, find the scenario that most closely matches your use case and then copy and paste the provided template into the Apply When field of the role. You may need to modify placeholder values (denoted by <angle brackets>) in the template to match your collection.

Note

You can use the Apply When expressions on this page for external services as well as in MongoDB roles.

The User Is the Document Owner

This expression evaluates to true if the active user’s unique id value matches the value the specified field.

{
  "<Owner ID Field>": "%%user.id"
}

An Array Field Contains the User’s ID

This expression evaluates to true if the active user’s unique id value matches one or more values in the specified array field.

{
  "<Array Field>": "%%user.id"
}

The User Has An Email Address

This expression evaluates to true if the active user has any email address listed in their internal user object.

{
  "%%user.data.email": { "%exists": true }
}

The User Has A Specific Email Address

This expression evaluates to true if the active user’s email address matches the specified email address.

{
  "%%user.data.email": "<Email Address>"
}

A Field Contains the User’s Email Address

This expression evaluates to true if the active user’s email address matches the value the specified field.

{
  "%%root.email": "%%user.data.email"
}

An Array Field Contains the User’s Email Address

This expression evaluates to true if the active user’s email address matches one or more string values in the specified array field.

{
  "<Array Field>": "%%user.data.email"
}

A Field Satisfies a Complex Condition

This expression evaluates to true if the Function isAuthorizedUser returns true when passed the active user’s id value.

Note

You can call any Stitch Function from a JSON expression using the %function operator.

{
  "%%true": {
    "%function": {
      "name": "isAuthorizedUser",
      "arguments": ["%%user.id"]
    }
  }
}

CRUD Permissions

Stitch uses a role’s permissions configuration to determine if the active user can insert or delete a document as well as which fields in the document they can read and write.

This section contains templates that define role permissions for common scenarios. To apply a set of permissions to a role, find the scenario that most closely matches your use case. Update the role’s permissions table to match the provided screenshot or copy and paste the provided template into the collection’s advanced mode configuration. Make sure that you modify any placeholder values (denoted by <angle brackets>) in the template to match your needs.

The Role Can Read All Fields but Cannot Write

To allow a role to read any field, set the document-level read field to true.

A role with permission to read all document fields
{
  "name": "<Role Name>",
  "apply_when": <JSON Expression>,
  "insert": <boolean>,
  "delete": <boolean>,
  "read": true,
}

The Role Can Read & Write All Fields

To allow a role to read or write any field, set the document-level write field to true. Document-level writes require read permission, so the role will be able to read all fields.

A role with permission to read and write all document fields
{
  "name": "<Role Name>",
  "apply_when": <JSON Expression>,
  "insert": <boolean>,
  "delete": <boolean>,
  "write": true,
}

The Role Can Read All Fields & Write to Specific Fields

To allow a role to read all fields, set the document-level read field to true. To specify a field that the role can write to, set the write field to true in the field’s configuration document, which is embedded in the fields document.

A role with permission to write to specific fields
{
  "name": "<Role Name>",
  "apply_when": <JSON Expression>,
  "insert": <boolean>,
  "delete": <boolean>,
  "read": true,
  "fields": {
    "<Field Name>": { "write": true },
    ...
  }
}

The Role Can Read & Write All Fields but Cannot Insert New Documents

To allow a role to read or write any field, set the document-level write field to true. Document-level writes require read permission, so the role will be able to read all fields.

To prevent the role from inserting new documents, set the document-level insert field to false.

A role that lacks permission to insert new documents
A role with permission to read and write all document fields
{
  "name": "<Role Name>",
  "apply_when": <JSON Expression>,
  "insert": false,
  "delete": <boolean>,
  "write": true,
}

The Role Cannot Write to Specific Fields

To allow a role to write to any field except for those you specify, set the corresponding field-level write fields to false in the fields document and set the additional_fields.write field to true.

A role with permission to write to some but not all fields
{
  "name": "<Role Name>",
  "apply_when": <JSON Expression>,
  "insert": <boolean>,
  "delete": <boolean>,
  "read": true,
  "fields": {
    "<Field Name>": {
      "read": true,
      "write": false
    },
    ...
  },
  "additional_fields": { "write": true }
}

Advanced Role Patterns

The use cases described in this section require you to use advanced functionality that is not supported by the default collection rules editor in the Stitch UI. To use this template, convert to advanced mode or import a collection rule configuration with Stitch CLI.

Insert-Only Roles

To allow a role to insert new documents but otherwise prevent them from reading or modifiying any data, set insert to true and set the value of document-level write to a JSON expression that evaluates to true only if the document didn’t exist prior to the operation.

{
  "name": "insertOnly",
  "apply_when": <JSON Expression>,
  "delete": false,
  "insert": true,
  "write": {
    "%%prevRoot": { "%exists": false }
  },
  "additional_fields": {}
}

Note

You must specify a JSON expression for write to prevent users from reading data. To insert a document a role must also have write permission for all fields in the document; however, setting write directly to true would also give the role read permission. The JSON expression ensures that the role only has read permission for the initial document insert.

Field-level Permissions for Embedded Documents

To allow a role to read or write some but not all fields of an embedded document, add embedded documents that match the path of the embedded field to the fields document.

{
  "name": "canReadEmbeddedField",
  "apply_when": {},
  "delete": true,
  "insert": true,
  "fields": {
    "someEmbeddedDocument": {
      "fields": {
        "someEmbeddedField": {
          "read": true,
          "write": true
        }
      }
    }
  },
  "additional_fields": {}
}

Note

Stitch applies any read and write permissions defined for a given field to all embedded fields that the field contains regardless of any permissions defined for those fields.