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. |
Roles
Reference: | FSL role schema |
---|
Fauna uses secrets for authentication and authorization. Roles determine a secret’s privileges, which control data access.
Role types
Fauna supports two types of roles:
Built-in roles
Built-in roles grant access to all of a database’s resources. Built-in roles are assigned to keys and typically used for system processes. You can’t assign built-in roles to tokens or JWTs.
Built-in role | Privileges |
---|---|
Full access to a database, including all:
You can also create an |
|
Same as
|
|
|
Same as |
|
Deprecated. Do not use. |
User-defined roles
User-defined roles can grant:
-
Access to documents and indexes in specific collections, including user-defined and system collections.
-
The ability to call specific user-defined functions (UDFs).
You create and manage user-defined roles as FSL role schema:
role manager {
// Assign the `manager` role to tokens with
// an identity document in the `Manager` collection.
// Not applicable to JWTs or keys.
membership Manager
// If the predicate is `true`,
// assign the `manager` role to tokens with
// an identity document in the `Customer` collection.
membership Customer {
// Check that the identity document's
// `accessLevel` field value is `manager`.
predicate (customer => customer.accessLevel == 'manager')
}
// Grant `read` access to the `Customer` collection,
// including its documents and indexes.
privileges Customer {
read
}
// Grant full access to the `OrderItem` collection.
privileges OrderItem {
create
read
write
delete
}
// If the predicate is `true`,
// grant `create` access to the `Order` collection.
privileges Order {
create {
predicate (doc =>
// Check the order's `status` field.
doc.status == "cart"
)
}
}
// If the predicate is `true`,
// grant `read` access to the `Manager` collection.
privileges Manager {
read {
// Check that the `Manager` document
// is the token's identity document.
// `Query.identity()` is `null` for JWTs or keys.
predicate (doc => Query.identity() == doc)
}
}
// If the predicate is `true`,
// grant `call` access to the
// user-defined `checkout` function.
privileges checkout {
call {
// Check that the `orderId` belonds to the user.
// `Query.identity()` is `null` for JWTs or keys.
predicate ((orderId, status, payment) => {
let order = Order.byId(orderId)!
order?.customer == Query.identity()
})
}
}
}
Role
collection
Fauna stores user-defined roles as documents in the Role
system collection.
These documents are an FQL version of the FSL role schema. You can use
Role methods to access and manage
user-defined roles in FQL.
See Role FQL docs |
---|
Membership
Fauna assigns user-defined roles to tokens based on their
identity document’s collection and the role’s membership
property:
role customer {
// Assign the `customer` role to tokens with
// identity documents in the `Customer` collection.
membership Customer
}
The membership
property doesn’t assign roles to JWTs or keys.
Membership predicates
Each membership
property can include a
predicate.
Membership predicates let you conditionally assign roles to tokens:
role customer {
// If the predicate is `true`,
// assign the `customer` role to tokens with
// identity documents in the `Customer` collection.
membership Customer {
// Checks the `status` field in the
// token's identity document.
predicate (user => user.status == "active")
}
}
You can use membership predicates to implement attribute-based access control (ABAC).
See Attribute-based access control (ABAC) |
---|
Membership for multiple roles
You can use membership to assign a token up to 64 roles.
For performance, Fauna stops checking a token’s roles once it verifies the token has the privileges required for a query.
Fauna evaluates membership predicates sequentially, prioritizing previously successful ones.
Privileges
A role can grant one or more privileges. A privilege allows a specific action,
such as read
or write
, on a specific resource, such as a collection or
UDF.
Privileges act as an allowlist. Roles grant no privileges by default.
Collection privileges
Collection privileges grant access to a collection’s documents. A collection
privilege can allow the create
, delete
, read
, or write
actions. read
access includes the ability to call the
collection’s indexes.
role customer {
// Grant read access to `Product` documents and indexes.
privileges Product {
read
}
}
You can also grant access to system collections that store Fauna resources:
role manager {
// Grant `create` and `read` access to the `Token` system collection.
// Allows the role to create token secrets.
privileges Token {
create
read
}
}
To allow a role to create, delete, or manage user-defined collections
themselves, grant access to the Collection
system collection:
role manager {
// Grant full access to the `Collection` system collection.
// Allows the role to create, delete, read, and update
// user-defined collections.
privileges Collection {
create
delete
read
write
}
}
Function privileges
Function privileges grant the ability to call
a server-side UDF:
role customer {
// Grants `call` access to the `getOrCreateCart` UDF.
privileges getOrCreateCart {
call
}
}
By default, UDFs run with the same privileges as the query’s authentication secret. You can override this default by specifying an optional role in the UDF’s function schema.
If a role is specified in the function schema, the UDF runs with that role’s privileges, regardless of the authentication secret’s privileges.
See User-defined functions (UDFs) |
---|
Privilege predicates
Each privilege
action can include a
predicate. Privilege
predicates let you conditionally grant privileges to a role:
role customer {
// If the predicate is `true`,
// grant `write` access to the `Order` collection.
privileges Order {
write {
predicate ((oldDoc, newDoc) =>
// Disallow write access 10 hours after
// the original order's last update (`ts`)
Time.now().difference(oldDoc!.ts, "hours") < 10 &&
// Check that the user's `country` is
// in the updated order's `allowedCountries`
newDoc.allowedCountries.includes( Query.identity()!.country)
)
}
}
}
Privilege predicates are passed different arguments based on their action. See Privilege predicate arguments.
You can use membership predicates to implement ABAC.
See Attribute-based access control (ABAC) |
---|
Query-time evaluation
Fauna evaluates a secret’s roles and privileges, including any predicates, at query time for every query. Changes to roles and privileges take effect immediately and affect pre-existing secrets.
Check a secret’s roles
You can use a user-defined collection and UDFs to check a secret’s assigned roles. See Check a secret’s user-defined roles.
Multi-tenancy and scope
Roles are scoped to a single database. A parent database’s roles don’t apply to its peer or child databases.
You can copy and deploy roles across databases using FSL and a CI/CD pipeline. See Manage schema with a CI/CD pipeline.
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!