Skip to main content

4 posts tagged with "openfga"

View All Tags

Query Consistency Options in OpenFGA

· 2 min read
Andres Aguiar
Product Manager

OpenFGA query APIs now allow specifying the desired consistency of query results. By default, OpenFGA does not use a cache. However, when caching is enabled, it applies to all requests. This means that any changes in permissions won't be reflected in authorization checks during the cache TTL period.

The community expressed the need for flexibility in using the cache on a per-request basis. In response, starting with OpenFGA v1.5.7, all query APIs can accept a consistency parameter with the following values:

NameDescription
MINIMIZE_LATENCY (default)OpenFGA will try to minimize latency (e.g. by making use of the cache)
HIGHER_CONSISTENCYOpenFGA will try to optimize for stronger consistency (e.g. by bypassing cache)

When HIGHER_CONSISTENCY is specified, OpenFGA reads directly from the database, even when the cache is enabled.

How to use it?

The new consistency parameter is available in OpenFGA starting v1.5.7.

The parameter is supported by all OpenFGA SDKs.

For more information on enabling the cache and best practices for specifying consistency values, refer to the documentation.

Custom database adapter implementations

For those with a custom database adapter for a multi-region database, the behavior of the HIGHER_CONSISTENCY parameter can be defined according to your needs. With an eventually consistent database (e.g., Dynamo DB) in a multi-region setup, there will be replication lag even if the cache is bypassed. If the database supports strong reads, you can choose to perform those at an extra cost. Otherwise, you can perform an eventually consistent read without providing full consistency semantics to the caller. In some other databases where you have Read/Write replicas, you may choose to go to the Write replica when the HIGHER_CONSISTENCY preference is selected.

Future work

Google Zanzibar features a consistency token called Zookies, returned from write operations. This token can be stored in a resource table and specified in subsequent query API calls. We are considering introducing a similar feature in future releases.

We want your feedback!

We want to learn how you use this API and how we can improve it!

Please reach out through our community channels with any questions or feedback.

List Users API

· One min read

Today we are launching a new API for OpenFGA: ListUsers.

This API will answer the question "what users have relation X with object Y?". This will be useful, for example, in UIs that want to display the list of users that a resource has been shared with, e.g. the "share" dialog in Google Docs.

You can read more about it in the API docs and the product documentation.

How to use it?

ListUsers is available in OpenFGA starting with v1.5.4.

To be able to call this API, you must turn on this flag on the server: --experimentals enable-list-users. Be sure to also check out the various configuration flags that were added to control its behavior.

The new functionality is available on the latest versions of the Java, .NET, Go and Javascript SDK, CLI and VS Code integration.

We'll be releasing support for the Python SDK soon.

We want your feedback!

We want to learn how you use this API and how we can improve it!

Please reach out through our community channels with any questions or feedback.

Modular Models

· 2 min read

Modular models aims to improve the model authoring experience when multiple teams are maintaining a model, such as:

  • A model can grow large and difficult to understand
  • As more teams begin to contribute to a model, the ownership boundaries may not be clear and code review processes might not scale

With modular models, a single model can be separated across multiple files allow grouping of types and conditions into modules. This means that a model can be organized more easily in terms of team or organizational structure. Used in conjunction with features such as GitHub, GitLab or Gitea's code owners, it should become easier to ensure the owners of a portion of your model are correctly assigned to review it.

How to use it?

Modular models is available in the latest version of OpenFGA. To use it you need to:

What's next?

Looking beyond the near term, modular models allows us to implement additional API authorization options for OpenFGA.

Reach out!

We want to learn how you use this feature and how we can improve it!

Please reach out through our community channels with any questions or feedback.

Conditional Relationship Tuples for OpenFGA

· 5 min read
Andres Aguiar
Product Manager

Relationship Tuples are the facts that the OpenFGA evaluates to determine whether a user is permitted to access a resource.

The way tuples are considered when making authorization decisions in OpenFGA is guided by an authorization model, which employs concepts from Relationship-Based Access Control (ReBAC) to establish authorization policies. For instance, you might declare that users are allowed to view a document if they have permission to view its parent folder.

Although ReBAC offers a highly flexible method for structuring permissions, it encounters difficulties with defining permissions based on attributes that are not easily represented as relationships. Attributes such as “parent folder,” “department,” “region,” and “country” can be conceptualized as relationships between two entities. However, attributes like “IP address,” “time of day,” “team size limit,” or “maximum amount for a bank transfer” cannot be easily handled.

In our ongoing efforts to expand OpenFGA’s capacity for articulating a broader range of authorization policies, we are introducing Conditional Relationship Tuples. These allow for the specification of conditions under which a particular tuple is relevant when evaluating an authorization query.

Consider the following example, where we utilize Conditional Tuples to grant access for a user over a specified time duration. We stipulate that a user may be granted either unconditional access or access constrained to a certain time period:

model
schema 1.1

type user

type document
relations
define viewer: [user, user with non_expired_grant]

condition non_expired_grant(current_time: timestamp, grant_time: timestamp, grant_duration: duration) {
current_time < grant_time + grant_duration
}

If we write the following tuples:

userrelationobjectcondition
user:bobviewerdocument:1
user:anneviewerdocument:1name : non_expired_grant, context : { grant_time : 2023-01-01T00:00:00Z, grant_duration : 1h }

You'll get the following results for the Check operations below:

userrelationobjectcontextresult
user:bobviewerdocument:1allowed : true
user:anneviewerdocument:1current_time : 2023-01-01T00:10:00Zallowed : true
user:anneviewerdocument:1current_time : 2023-01-01T02:00:00Zallowed : false
user:anneviewerdocument:1error : "failed to evaluate relationship condition 'non_expired_grant': context is missing parameters '[current_time]'

You'll get the following results for the ListObjects operations below:

userrelationobjectcontextresult
user:anneviewerdocument:1current_time : 2023-01-01T00:10:00Zobjects: [ "document:1"]
user:anneviewerdocument:1error: "failed to evaluate relationship condition 'non_expired_grant': tuple 'document:1#viewer@user:anne' is missing context parameters '[current_time]'

Note that:

  • user:bob will always get allowed:true as we have assigned as viewer unconditionally.
  • user:anne will get allowed:true if the current_time is before the grant_time + grant_duration and allowed:false otherwise.
  • If you don't provide the current_time in the context, the Check and ListObjects operations will fail.

Use Cases

The OpenFGA Sample Stores repository has several examples that take advantage of this new feature:

How to use it?

Conditional Relationship Tuples are included in OpenFGA 1.4.0-rc1 version. You can run it by pulling it from docker:

docker pull openfga/openfga:v1.4.0-rc1
docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 openfga/openfga:v1.4.0-rc1 run`

OpenFGA has a rich ecosystem of developer tools. The following have been updated to support Conditional Relationship Tuples:

What’s Next?

We’ll address some limitations of the current implementation:

  • The Expand API does not consider conditions.
  • The Visual Studio Code integration is not validating the expressions in conditions.
  • The Playground does not let you add context for tuples and assertions. You should use the VS Code Extension + the FGA CLI to test your models for now.

We'll also improve ListObjects scenarios when it's called with missing context. For example, consider the following model that enables access only to documents with a specific status:

model
schema 1.1

type user

type document
relations
define can_access: [user with docs_in_draft_status]

condition docs_in_draft_status(status: string) {
status == "draft"
}

If you want to list all the documents a user can view, you'll need to know the status of all of those documents. Given you don't know the documents the user has access too, you can't send the status of those as a parameter to ListObjects.

Our goal is to return a structure that you can use to filter documents on your side, similar to: (document.id = ‘1’ and document.status = ‘draft’) or (document.id = ‘2’ and.status = draft)
This won’t scale to a large number of documents, but would be useful in some scenarios.

Reach out!

We want to learn how you use this feature and how we can improve it!

Please reach out through our community channels with any questions or feedback.