Security best practices

This guide covers best practices for authentication and authorization in Fauna.

Follow the principle of least privilege

Users and systems should have the fewest privileges needed to complete their required tasks:

  • Only add privileges to roles that need them.

  • Only assign roles to users or systems that require them.

  • Only allow access to sensitive data through user-defined functions (UDFs). UDFs let you control how data is accessed and customize the format of returned data.

Limit the number of user-defined roles

Only create the roles you need when you need them.

Fauna evaluates roles and privileges at query time. This lets you create or change roles as needed. Changes to roles and privileges take effect immediately and affect existing secrets.

For the best performance and lower costs, only use role-related predicates when needed.

Role-related predicates are evaluated for every applicable query. Predicate evaluations consume Transactional Read and Transactional Compute Operations.

Use indexes for filtering

Avoid using role-related predicates to filter collections or large sets of documents. Instead, use indexes.

Set an expiration for secrets

When possible, set a ttl (time-to-live) timestamp for Fauna keys and tokens. To limit the impact of stolen credentials, use the shortest feasible ttl for your use case.

Similarly, JWTs created by an access provider should include the soonest exp timestamp possible for your use case.

Use environmental and identity-based attributes for ABAC

Use predicates with environmental attributes, such as date or time, and identity-based attributes to limit access if credentials are stolen. For example, you can only grant access to users connecting from specific locations or IP addresses or during specific hours.

Use membership predicates for environmental and identity-based attributes

If you use tokens, use membership predicates rather than privilege predicates to check environmental attributes, such as date or time, or identity attributes. This avoids duplicating the predicate across multiple privileges.

Update identity documents in real time

If you use tokens, you can update identity documents in real time to dynamically control access with role-related predicates.

For example, you can use a membership predicate to control access based on the badgedIn field in Employee identity documents. Fauna checks the predicate at query time for every query.

Structure membership predicates to return early

If you use membership predicates to assign multiple roles to tokens, structure the predicates to return as early as possible. This ensures Fauna spends less time evaluating the predicate. See Membership for multiple roles.

Use privilege predicates to verify document changes

Use collection privilege predicates to validate the input and output of document operations.

For example, you can use a write privilege predicate to ensure users can’t read or update specific document fields. This limits the surface area for attacks.

Use privilege predicates to validate UDF arguments

Use function privilege predicates to validate the arguments passed to a UDF call.

For example, you can ensure users can’t call a function with data unrelated to their tasks or scope. This limits the surface area for attacks.

Avoid using middleware

Connect your client application directly to Fauna to limit the surface area for attacks.

Use a CI/CD pipeline to copy roles across databases

Roles are scoped to a single database and don’t apply to its peer or child databases.

If you have a multi-tenant application, 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!