Define your application's authorization model using a domain-specific language (DSL).
The schema language is a domain-specific language (DSL) designed to express authorization models. It is simpler and more human-readable than the JSON syntax.
It transpiles to JSON, making it possible to use alongside existing JSON resource-types. This approach can be useful for managing more complex logical structures.
The JSON syntax also converts into schema language syntax which makes it easier to adopt. If you would like to see your existing resource types in schema language syntax, visit the schema editor in the FGA dashboard. There you can apply a new schema to your environment or convert JSON syntax to schema language syntax.
You can also convert a schema with the CLI using the fga schema convert
command:
workos fga schema convert ./schema.txt --to json
Or apply a schema with the CLI using the fga schema apply
command:
workos fga schema apply ./schema.txt
Each schema must start with a version
declaration. This version declaration dictates the version of the schema language the transpiler will use to convert the schema into its JSON representation. As we add support for new features and functionality to the schema language, we will release new versions of it. Versioning the language in this way allows us to ensure backwards compatibility as we roll out these enhancements. See a full changelog of schema versions here.
version 0.2
Resource types are the building blocks of your authorization model. They represent different types of entities in your application. For example users, organizations, stores, items, etc. See more information about resource types here.
To define a resource type, use the type
keyword followed by the name of the resource type.
type user
Relations are a specific type of connection between two resources. Relations define how a subject can access a resource. For instance, the user
resource type might define a manager
relation. The manager
relation authorizes certain users to access employee information for a user.
To define a relation for a resource type, use the relation
keyword followed by the name of the relation. Optionally, you can add the type(s) of resources the service can assign to the relation.
Use brackets []
after the relation name for resource type checking. The resource type can be empty, a single type, or an array of types. Type checking occurs at runtime when your application calls the service create warrants. The server validates that warrants have proper subject types. The service also checks types when applying a new schema to confirm that inheritance rules are valid.
Use empty resource types to define computed relationships with no direct subjects. Such as a relation inherited from other relations.
Version 0.1
of the schema language does not support type safety on relations.
type user relation manager [user]
In this example, the manager
relation indicates that only a user
can be a manager
of another user
.
type user relation editor [user] relation manager [user] relation computed [] inherit computed if any_of relation editor relation manager
In this example, the computed
relation is inherited if either the editor
or manager
relation exists. You cannot assign a subject to the computed
relation directly.
Use inheritance rules to define how certain relations are granted implicitly based on the existence of other relations. They are useful for expressing hierarchical relationships without having to explicitly define every possible relation as a warrant.
There are two types of inheritance rules:
To define an inheritance rule, use the inherit
keyword followed by the name of the inherited relation. On the next line add a condition that the subject should meet in order for the inheritance to occur.
type store relation viewer [user] relation editor [user] inherit viewer if relation editor
In this example, the viewer
relation is inherited if the editor
relation exists for a subject.
Use relation inheritance to inherit from another relation within the same resource type. This is useful when you want to create hierarchical relationships. One common use case is to inherit the viewer
relation if the editor
relation exists.
To define a relation inheritance rule, specify the relation to inherit, and the relation to inherit based on.
type store relation viewer [user] relation editor [user] relation owner [user] inherit viewer if relation editor inherit editor if relation owner
In this example, the viewer
relation is inherited if the editor
relation exists. The editor
relation is inherited if the owner
relation exists.
Use resource inheritance to inherit from a relation in another resource type. This is useful when you want to create hierarchical relationships between different resource types.
To define a resource inheritance rule, specify the relation, the resource type to inherit from, and the relation to inherit based on.
type item relation owner [user] relation parent [store] inherit owner if relation owner on parent [store]
In this example, the owner
relation on an item
is inherited if all of the following conditions are met
owner
relation on the parent
.owner
parent
is a store
.Use logical operators to combine multiple inheritance conditions. The supported operators are all_of
, any_of
, and none_of
. They behave the same as JSON resource type inheritance rules.
type item relation owner [user] relation editor [user] relation manager [user] inherit editor if any_of relation owner relation manager on owner [user]
In this example, the editor
relation is inherited if either of the following conditions are met:
owner
relation exists on the item type (relation inheritance).manager
relation exists on the owner
if the owner
is a user
(resource inheritance).You can also nest logical operators to define complex relationships between resource types. Here’s an example:
inherit editor if any_of relation owner relation editor on parent [store] all_of relation viewer on parent [store] relation manager on owner [user]
In this example, the schema defines an editor
relationship that is granted if any of the following conditions are met:
owner
.editor
on the parent
store
.viewer
on the parent
store
and a manager
on the owner
user
.Here is an example schema that incorporates resource types, relations, inheritance rules, and logical operators:
version 0.2 type user relation manager [user] type store relation viewer [user] relation owner [user] relation editor [user] inherit viewer if relation editor inherit editor if relation owner type item relation viewer [user] relation parent [store] relation owner [user] relation editor [user] inherit viewer if relation editor inherit owner if relation owner on parent [store] inherit editor if any_of relation owner relation editor on parent [store] relation manager on owner [user]