Check out v4 of the Fauna CLI

v4 of the Fauna CLI is now in beta.

The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start.

FSL role schema

Learn: Roles

This page covers the FSL syntax for role schemas. For an overview of user-defined roles, see Roles.

An FSL role schema defines a user-defined role.

Fauna uses secrets for authentication and authorization. Roles determine a secret’s privileges, which control data access.

role manager {

  membership Manager

  membership User {
    predicate (user => user.accessLevel == 'manager')
  }

  privileges Product {
    create
    read
    write
    delete
  }

  privileges User {
    read {
      predicate (doc => Query.identity() == doc)
    }
  }

  privileges getOrCreateCart {
    call
  }

  privileges checkout {
    call {
      predicate ((args) => {
        let order = Order.byId(args[0])!
        order?.customer == Query.identity()
      })
    }
  }
}

You can create and manage schema using any of the following:

Fauna stores each role schema as an FQL document in the Role system collection.

FSL syntax

role <role> {
  [membership <collection> [{
    predicate <predicate>
  }] . . .]

  [privileges <resource> {
    <action> [{
      predicate <predicate>
    }] . . .
  } . . .]
}

Name

role Required

Unique name for the role in the database.

Must begin with a letter. Can only include letters, numbers, and underscores. admin, server, and server-readonly are reserved and can’t be used.

Properties

Property Required Description

membership

Assigns the role to tokens based on the token’s identity document. See Membership definition.

privileges

Allows one or more actions on a resource. See Privileges definition.

Membership definition

role manager {
  membership Manager

  membership User {
    predicate (user => user.accessLevel == 'manager')
  }
  ...
}
Property Required Description

collection

Yes

Name of a user-defined collection.

Fauna assigns the role to tokens with an identity document in the collection.

predicate

Predicate used to conditionally assign the role. If the predicate is not true, the role is not assigned.

The predicate is passed one argument: an object containing the token’s identity document.

The predicate runs with the built-in server role’s privileges. Supports shorthand syntax.

Privileges definition

role manager {
  ...
  privileges Product {
    create
    read
    write
    delete
  }

  privileges User {
    read {
      predicate (doc => Query.identity() == doc)
    }
  }
  ...
}
Property Required Description

resource

Yes

Name of a collection or user-defined function (UDF). Supports user-defined collections and the following system collections:

  • AccessProvider

  • Collection

  • Credential

  • Database

  • Function

  • Key

  • Role

  • Token

read privileges grants the ability to call the collection’s indexes.

action

Yes

Type of operation allowed on the resource. Privileges support different actions based on the resource type. See Privilege actions.

predicate

Predicate used to conditionally grant the privilege. If the predicate is not true, the privilege is not granted.

Privilege predicates are passed different arguments based on their action. See Privilege predicate arguments.

The predicate runs with the built-in server role’s privileges. Supports shorthand syntax.

Privilege actions

Privileges support different actions based on their resource type.

Resource type Action Allows you to …​

Collection

create

Create documents in the collection. To create documents with a custom id, you must also have the create_with_id privilege.

Collection

delete

Delete documents in the collection.

Collection

read

Read documents in the collection. Can also call the collection’s indexes. To read historical document snapshots, you must also have the history_read privilege.

Collection

write

Update or replace documents in the collection.

Collection

create_with_id

Create documents with a custom id in the collection. You must also have the create privilege.

Collection

history_read

Read snapshots for documents in the collection. See Run a temporal query.

User-defined function (UDF)

call

Call the function.

Privilege predicate arguments

Privilege predicates are passed different arguments based on their action.

Action Predicate function signature

create

(doc: Object) => Boolean | Null

 

doc: Object containing the document to create. Includes metadata fields.

delete

(doc: Object) => Boolean | Null

 

doc: Object containing the document to delete. Includes metadata fields.

read

(doc: Object) => Boolean | Null

 

doc: Object containing the document to read. Includes metadata fields.

write

(oldDoc: Object, newDoc: Object) => Boolean | Null

 

oldDoc: Object containing the original document. Includes metadata fields.

newDoc: Object containing the document to write. Includes metadata fields.

create_with_id

(doc: Object) => Boolean | Null

 

doc: Object containing the document to create. Includes metadata fields.

history_read

(doc: Object) => Boolean | Null

 

doc: Object containing the document to read. Includes metadata fields.

call

(args: Array) => Boolean | Null

 

args: Array containing the function call’s arguments.

Examples

role manager {

  // Assign the `manager` role to tokens with
  // an identity document in the `Manager` collection.
  membership Manager

  // If the predicate is `true`,
  // assign the `manager` role to tokens with
  // an identity document in the `User` collection.
  membership User {
    // Check that the identity document's
    // `accessLevel` field value is `manager`
    predicate (user => user.accessLevel == 'manager')
  }

  // Grant full access to `OrderItem` collection documents.
  privileges OrderItem {
    create
    read
    write
    delete
  }

  // Grant `read` access to `Customer` collection documents.
  privileges Customer {
    read
  }

  // If the predicate is `true`,
  // grant `read` access to `Manager` collection documents.
  privileges Manager {
    read {
      predicate (doc =>
        // Check that the `ManagerProfile` document
        // is the token's identity document.
        // `Query.identity()` is `null` (falsy) for JWTs or keys.
        Query.identity() == doc &&
        // Check that it's a weekday.
        Date.today().dayOfWeek < 6
      )
    }
  }

  // Grant the ability to call the user-defined
  // `getOrCreateCart()` function.
  privileges getOrCreateCart {
    call
  }

  // If the predicate is `true`,
  // grant the ability to call the user-defined
  // `submitOrder()` function.
  privileges checkout {
    call {
      // Check that the `orderId` (`args[0]`) belonds to the user.
      // `Query.identity()` is `null` for JWTs or keys.
      predicate ((args) => {
        let order = Order.byId(args[0])!
        order?.customer == Query.identity()
      })
    }
  }
}

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!