Hero 2

Announcing FaunaDB 2.7

The Fauna team is very pleased to announce the availability of release 2.7 of FaunaDB. This release brings numerous enhancements in security and usability. The sections below summarize the highlights of this release.

Attribute-based access control

Attribute-based access control (ABAC) is designed as a replacement for FaunaDB’s current resource-based security model. It is an alternative to an all-or-nothing security model and is commonly used in applications to restrict access to specific data based on the user's role. Until 2.7, access within FaunaDB was restricted to 4 pre-defined roles. Users would authenticate using keys or tokens and could have any one of the following roles - admin, server, server- read-only, or client. These roles have different levels of access and a developer would pick one that is closest to end users access profile. With ABAC, now developers can define custom roles that match the applications’ requirements and only allow access to the data that the user needs to see.

Just like in the previous releases, end users use keys to authenticate to the system and keys are assigned roles. At any given time a key can have only one role. These user-defined roles are composed of a set of privileges. Privileges are predefined actions like create, delete, read, write etc. to specific resources. In FaunaDB a resource can a database, a collection, an index or even a role or a document. This model provides a lot of flexibility on how access can be controlled within an application.

Validating actions with predicate functions

One of the unique features of ABAC in FaunaDB is the ability to associate a predicate lambda, which is a read-only function that returns a boolean for an action. The function determines whether a user can access a specific resource based on a defined condition. In the following example, executed in Fauna Shell, the role only provides access to users who are defined as “vip”s:

todo-app> CreateRole({
    name: "can_manage_todos",
    membership: [
        // ...
    ],
    privileges: [
        {
            resource: Collection("todos"),
            actions: {
                create: Query(Lambda(newData =>
                    Select(["data", "vip"], Get(Identity()))
                )),
                // ...
            }
        }
    ]
})

Membership

FaunaDB also allows users to define membership rules. Membership rules contain a resource collection, e.g. a collection with a list of users. A predicate function can be used to determine membership dynamically, e.g. only a “vip” can update a certain record:

todo-app> CreateRole({
    name: "can_manage_todos",
    membership: [
        {
            resource: Collection("users"),
            predicate: Query(Lambda(ref =>
                Select(["data", "vip"], Get(ref))
            ))
        }
    ],
    privileges: [
        // ...
    ]
})

Cloud Console support

In addition to support in Fauna Shell, we have also added ABAC support to the Cloud Console. You can access this feature by navigating to a database, clicking "Security" in the left sidebar, and then clicking "Manage Roles". Our built-in roles are not editable, so you need to click "New Role" to get started.

Putting it together

ABAC is ubiquitous in databases, but FaunaDB’s implementation is peerless. The ability to associate a lambda to the membership or privilege definitions notably improves on the standard implementation of roles.

FaunaDB Shell, on the web

We're thrilled to announce another commonly requested feature from users:  a web-based version of the Fauna Shell. 

Users can now access our Shell command-line from any browser, anywhere with an internet connection. FQL commands and functions can now be run directly in the browser. This is especially helpful for new users hoping to get started quickly with FaunaDB, without needing to install CLI tools on their local computer.

You can access this by drilling into a database and then clicking "Shell" in the sidebar. This is a great way to practice queries on-the-fly, especially for users new to FQL. You can issue multiple queries in one shot with the "Open file" button, and download all of your results by clicking "Download":

Renaming classes and instances

Old NameNew Name
ClassCollection
InstanceDocument

One of the biggest user-facing changes in this release is the renaming of "classes" to "collections" and of "instances" to "documents". Usability testing has repeatedly surfaced these terms as a source of confusion for new users. As such, we have renamed these terms.

We decided to go with "collection" because it’s more inclusive of flexible data models and resonates well with developers from a NoSQL background. Because databases that use the term "collections" typically also use the word "documents" to denote the objects in those collections, "instances" have been renamed to "documents". We have also found that most new users start with document-based data models to improve productivity during the early prototyping stage of application development.

This rename appears throughout FaunaDB and the documentation, especially in the FQL reference.

> CreateCollection({ name: "boons" })
{ ref: Ref(id=boons, collection=Ref(id=collections)),
  ts: 1527274777496292,
  history_days: 30,
  name: 'boons' }

Starting with 2.7.0, the use of “Classes” and “Instances” are deprecated and they will eventually be removed in a future release. If you are using classes in your code, please be advised to change them to collections within the next two minor releases of FaunaDB.

Recursive user-defined functions

It's finally here! Recursion has been one of the most commonly requested features from our community, so we have added the ability to make recursive calls to user-defined functions. Since recursive calls can be very resource-intensive, the number of calls is restricted to a hard limit of 200. In the example below, we see how one can implement a custom foldLeft function with recursive calls.

> CreateFunction({
  name: "foldLeft",
  "body": Query(
    Lambda(
      ["lastResult", "array"],
      If(IsEmpty(Var("array")),
        Var("lastResult"),
        Let(
          {
            elem: Select(0, Take(1, Var("array"))),
            tail: Drop(1, Var("array"))
          },
          Call("foldLeft",
            Add(Var("lastResult"), Var("elem")), Var("tail")
          )
        )
      )
    )
  )
})

We are very excited to see how you like this change, and how you are using it in your applications, so please reach out to share your thoughts. You can either email us or ping us in the Community Slack.

Time to Number functions

FaunaDB 2.7.0 introduces new capabilities for time to number conversions. Fauna has two special data types dealing with dates and times. The first data type is date, which stores a calendar date. The second is a timestamp (ts), which stores an instant in time expressed as a calendar date and time of day. These new functions allow developers to extract various valuable information from a timestamp field. Here is a summary of these new functions:

FunctionDescriptionExample
DayofMonthReturns the day of the month from a timestamp> DayOfMonth(Time("2019-04-29T12:51:17Z"))
29
DayofWeekReturns the day of the week from a timestamp> DayOfYear(Time("2019-04-29T12:51:17Z"))
119
DayofYearReturns the day of the year from a timestamp> DayOfWeek(Time("2019-04-29T12:51:17Z"))
1
HourReturns the hour from a timestamp> Hour(Time("2019-04-29T12:51:17Z"))
12
MinuteReturns the minute from a timestamp> Minute(Time("2019-04-29T12:51:17Z"))
51
SecondReturns the second from a timestamp> Second(Time("2019-04-29T12:51:17Z"))
17
MonthReturns the month from a timestamp> Month(Time("2019-04-29T12:51:17Z"))
4
YearReturns the year from a timestamp> Year(Time("2019-04-29T12:51:17Z"))
2019

Conclusion

With 2.7, we give users far more control in how user groups are able to work with and access data in FaunaDB. We’ve also made these improvements easily accessible in our Cloud Console. Furthermore, users can now use their favorite FQL commands and functions directly in the browser with FaunaDB Web Shell.

Renaming classes to collections and instances to documents adds clarity for users both new and existing. With recursive UDFs and new time to number functions, we’ve improved usability and implemented a few fan favorite requests.

To learn more please check out our documentation, ABAC tutorial, and security examples. We also recommend checking out more examples on the web.

We also welcome your feedback! Please email me at product@fauna.com and let us know of any other features that would make FaunaDB an obvious choice for your next project.