Keys

FaunaDB keys provide anonymous-based access to a database.

Anyone who possesses the secret for a FaunaDB key can access the database associated with the key and perform any operations that are permitted by the key’s role (see Access roles). Keys are typically used by database owners or administrators to manage database structure and contents with few restrictions, and by background tasks that automate various database procedures at regular intervals.

When a key is created, you must copy the key’s secret out of the query result when it is first created, and store it securely. It is impossible to recover the key’s secret if it is discarded or lost, because the key only stores the BCrypt hash of the secret.

A key’s secret is then included as a bearer token in FaunaDB queries:

Anonymous-based authentication and access control with FaunaDB keys

How FaunaDB accepts the secret for a key

  • The client send a query to FaunaDB, and the request includes the secret for a Key as an HTTP bearer token header.

  • If the secret exists, FaunaDB looks up the associated Key document. If not, the response is Unauthorized.

  • If the Key exists and has not expired (due to ttl), FaunaDB evaluates the Key’s role field within the database associated with the Key. The active role could be a built-in role or an ABAC role, and determines whether the query should be permitted to execute. If not, the response is Unauthorized.

  • If the Key provides permission, the query is executed and the response is returned.

A key’s secret can be used in multiple queries until its key becomes invalid or is deleted.

Keys are defined as documents within the system keys collection. Like databases, keys exist within the system-global root database context. Keys are tied to a specific database and allow access to its contents. If no database is specified, the key grants access to the database in which it was created. The level of access that a key provides depends on its role.

Once you have key, you can use its secret to authenticate GraphQL queries.
A key’s secret is a password equivalent. Guard secrets with the same care and attention that you use for passwords.

Beginning with FaunaDB 2.11.0, the FaunaDB access control logic has been changed to use attribute-based access control (ABAC) roles, or the key-based permission system, but never both.

If a resource is a member of an ABAC role, the ABAC role specifies all privileges for that resource. Otherwise, the key-based permission system determines whether read/write/execute privileges are enabled.

For example, when an ABAC role includes a user-defined function as a member, that function cannot be called unless the ABAC privileges permit the call action.

On this page:

Access roles

Keys belong to one of four built-in roles, either admin, server, server-readonly, or client, or to one or more used-defined roles.

Admin role

Keys with the admin role are used for managing databases, keys, and user-defined roles. An admin key can be used to create and destroy databases and keys. They should be very well protected.

Admin keys for FaunaDB accounts are managed in the FaunaDB Dashboard.

Server role

Keys with the server role bypass all permission checks within the database they’re assigned to. Because they provide unrestricted access, they should be well protected and only used in trusted or server-side environments.

Server read-only role

Keys with the server-readonly role allow read-only access to all data within the database that they are assigned to. Because they provide unrestricted read access, they should be well protected and only used in trusted or server-side environments.

User-defined role

Keys can specify one or more user-defined roles. The privileges for such a key are specified by the associated role(s).

Keys having user-defined roles are, essentially, equivalent to tokens, in that there are no specific privileges provided by default, but there is no associated identity.

Client role

Keys with the client role are restricted to actions and resources that are specifically marked with the public permission. Because their access is controlled, they are suitable for embedding in untrusted environments, such as mobile clients.

Typically they are used as part of an application’s user authentication flow, or to access public data, such as an application’s logged-out view.

Client keys and roles, and public permissions are deprecated as of the 2.12.0 release. You should use the Attribute-based access control (ABAC) system instead,

See Deprecations for more details.

Scoped keys

There are several situations where you might want to impersonate access to a database, because regular access is more difficult or you are lacking information. For example:

  • You have a reporting tool that needs to gather information from all of your child databases. To access a child database, you would typically need to use a secret associated with each child database. With hundreds or thousands of child databases, managing those secrets is challenging.

  • Your application performs queries on behalf of users, and you need to test that functionality and/or access controls are working correctly. However, you don’t have access to any user’s password in order to call Login.

  • Similarly, your applications provides different functionality for users with differing roles, and you need to test the functionality and access controls.

To facilitate these use cases, FaunaDB accepts a scoped key. A scoped key allows you to use a secret that you already possess to impersonate access to FaunaDB in several ways. However, it is not possible to use a scoped key to gain additional privileges.

A scoped key is formed from the secret of a key that you already possess, plus some additional information that provides three impersonation alternatives:

  1. secret[:child_database]:role

    Where:

    • secret is the key’s secret. An admin key is required to access a child database.

    • child_database is the name of a child database (optional). When specified, the secret for an admin key must be used. When not specified, the secret from an admin or server key can be used.

    • role is the name of a system role to use, one of admin, server, server-readonly, or client.

    This kind of scoped key would typically be used to impersonate access to a child database.

    For example: fnACysRJGIACAHiL_5f0UxHlPFIZgq876ptMNJ72:posts:admin

    Provided that the secret belong to an admin key, this scoped key provides full access to the child database called posts.

  2. secret[:child_database]:@doc/collection/id

    Where:

    • secret is the key’s secret. An admin key is required to access a child database.

    • child_database is the name of a child database (optional). When specified, the secret for an admin key must be used. When not specified, the secret from an admin or server key can be used.

    • collection is the name of a collection in the current database, or if child_database is specified, in the child database.

    • id is the reference id for the document to authorize as.

    This kind of scoped key would be used to impersonate a specific user.

    For example: fnACysRJGIACAHiL_5f0UxHlPFIZgq876ptMNJ72:@doc/users/1234

    This scoped key would have the same privileges as the authenticated Ref(Collection("users"), 1234) document.

  3. secret[:child_database]:@role/name

    Where:

    • secret is the key’s secret. An admin key is required to access a child database.

    • child_database is the name of a child database (optional). When specified, the secret for an admin key must be used. When not specified, the secret from an admin or server key can be used.

    • name is the name of an ABAC role to authorize as.

    This kind of scoped key would be used to impersonate any user having the privileges of the specified role.

    For example: fnACysRJGIACAHiL_5f0UxHlPFIZgq876ptMNJ72:@role/developers

    This scoped key would have the same privileges as any member document with the developers role.

Definition

{
  ref: Ref(Keys(), "265969362433737234"),
  ts: 1589906999970000,
  name: 'A server key for my_app',
  role: 'server',
  hashed_secret: '$2a$05$o6GjiF54FaZ6IBy4Qaxiz.NybQ0BcFGaze4WZ178VaTMUT.voXw5G'
}
Field name Value type Description

ref

The reference for this key.

ts

The timestamp, with microsecond resolution, associated with the creation of the key.

name

Optional - The key’s user-defined name.

role

The key’s role. Either admin, server, server-readonly, client, or one or more user-defined roles.

Client keys and roles, and public permissions are deprecated as of the 2.12.0 release. You should use the Attribute-based access control (ABAC) system instead,

See Deprecations for more details.

secret

The key’s authentication secret. Only present on creation of a key, not recoverable if lost or discarded.

hashed_secret

The key’s hashed authentication secret.

priority

A priority between 1 and 500, inclusive. Defaults to 1.

The priority option is deprecated as of release 2.10.0. You should avoid specifying priority. In some future FaunaDB release, priority will be removed. See Deprecations for more details.

database

Optional - A reference for the database associated with this key. When not provided, the key is associated with the database in which it was created (the current database).

data

Optional - User-defined metadata for the key.

Operations on keys

  • Create keys with the CreateKey function.

    You cannot create a key with greater privileges that the key you are already using.
  • List keys in the current database by running the query:

    Paginate(Keys())
  • Delete keys, which immediately makes their associated secrets invalid, using the Delete function.

  • Rename a key, or modify its optional user-defined metadata (the data field) by using the Update function.

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's Discourse forums or email docs@fauna.com

Thank you for your feedback!