Immutable Authorization Models
Authorization Models in OpenFGA are immutable, they are created once and then can no longer be deleted or modified. Each time you write an authorization model, a new version is created.
Viewing all the authorization models
You can list all the authorization models for a store using the ReadAuthorizationModels API. This endpoint returns the results sorted in reverse chronological order, as in the first model in the list is the latest model. By default, only the last 50 models are returned, but you can paginate across by passing in the appropriate continuation_token
.
How to target a particular model
Some endpoints relating to tuples (Check, ListObjects, ListUsers, Expand, Write) accept an authorization_model_id
, which we strongly recommend passing, especially in production.
In practice, you would pin the authorization model ID alongside the store ID in your configuration management system. Your services would read this value and use it in their requests to FGA. This helps you ensure that your services are using the same consistent ID across all your applications, and that rollouts can be seamless.
Benefits of passing in an authorization model ID
Targeting a specific model ID would ensure that you don't accidentally break your authorization checks in production because a mistake was made when updating the authorization model. It would also slightly improve the latency on your check requests.
If that field is passed, evaluation and validation will happen for that particular authorization model ID. If this field is not passed, OpenFGA will use the last created Authorization Model for that store.
Potential use-cases
Complex model migrations
Certain model changes require adapting your application code and migrating tuples before rolling it out. For example, if you rename a relation, you need to change the application and copy the existing tuples to use the new relation name. This scenario requires the following steps:
- Update the authorization model with the renamed relation. A new model ID will be generated but it won't be used in production yet.
- Update the application to use the new relation name.
- Copy existing tuples to use the new relation name.
- Deploy the new application targeting the new model ID.
You can learn more about model migrations here.
Progresivelly rollout changes
Being able to target multiple versions of the authorization model enables you to progressively roll out model changes, which is something you should consider doing if the changes are significant. You could:
-
Do shadow checks where you would perform checks against both your existing model and the new upcoming model you are hoping to replace it with.This will help you detect and resolve any accidental discrepancies you may be introducing, and ensure that your new model is at least as good as your old one.
-
When you are confident with your model, you could implement gradual rollouts that would allow you to monitor and check if any users are having access issues before you go ahead and increase the rollout to 100% of your user base.
The Authorization Model ID is a ULID which includes the date created. You can extract the creation date using a library for your particular language.
For example, in JavaScript you can do the following:
import ulid = require('ulid');
const time = ulid.decodeTime(id);