Skip to content

Commit d4e343c

Browse files
authored
chore: added docs about nested operations (#952)
1 parent 109950f commit d4e343c

File tree

1 file changed

+118
-5
lines changed

1 file changed

+118
-5
lines changed

docs/content/configuration-language.mdx

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525

2626
<ProductName format={ProductNameFormat.LongForm}/>'s Configuration Language builds a representation of a system's <ProductConcept section="what-is-an-authorization-model" linkName="authorization model" />, which informs <UpdateProductNameInLinks link="/api/service" name="{ProductName}'s API" /> on the <ProductConcept section="what-is-a-type" linkName="object types" /> in the system and how they relate to each other. The Configuration Language describes the <ProductConcept section="what-is-a-relation" linkName="relations" /> possible for an object of a given type and lists the conditions under which one is related to that object.
2727

28-
The Configuration Language can be presented in **DSL** or **JSON** syntax. The JSON syntax is accepted by the API and closely tracks the language in the [Zanzibar paper](https://research.google/pubs/pub48190/). The DSL adds syntactic sugar on top of JSON for ease of use, but compiles down to JSON before being sent to <ProductName format={ProductNameFormat.ShortForm}/>'s API. JSON syntax is used to call API directly or through the [SDKs](./getting-started), while DSL is used to interact with <ProductName format={ProductNameFormat.ShortForm}/> in the [Playground](https://play.fga.dev/), and they can be switched between throughout this documentation.
28+
The Configuration Language can be presented in **DSL** or **JSON** syntax. The JSON syntax is accepted by the API and closely tracks the language in the [Zanzibar paper](https://research.google/pubs/pub48190/). The DSL adds syntactic sugar on top of JSON for ease of use, but compiles down to JSON before being sent to <ProductName format={ProductNameFormat.ShortForm}/>'s API. JSON syntax is used to call API directly or through the [SDKs](./getting-started), while DSL is used to interact with <ProductName format={ProductNameFormat.ShortForm}/> in the [Playground](https://play.fga.dev/), the [CLI](https://github.com/openfga/cli), and the IDE extensions for [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=openfga.openfga-vscode) and [IntelliJ](https://plugins.jetbrains.com/plugin/24394-openfga). They can be switched between throughout this documentation.
2929

3030
Please familiarize yourself with basic <ProductConcept /> and [How to get started on modeling](./modeling/getting-started.mdx) before starting this guide.
3131

@@ -322,7 +322,7 @@ In the type definition snippet above, `anne` is a `member` of `team:product` if
322322
relation: 'member',
323323
object: 'team:product',
324324
_description: 'Everyone (`*`) is directly related to the product team as a member',
325-
},
325+
}
326326
]}
327327
/>
328328

@@ -741,7 +741,7 @@ For more examples, see [Modeling with Multiple Restrictions](./modeling/multiple
741741

742742
### The Exclusion Operator
743743

744-
The **exclusion operator** (`but not` in the DSL, `difference` in the JSON syntax) indicates that a <ProductConcept section="what-is-a-relationship" linkName="relationship" /> exists if the <ProductConcept section="what-is-a-user" linkName="user" /> is in the base userset, but not in the excluded userset. It's helpful when modeling exclusion or block lists.
744+
The **exclusion operator** (`but not` in the DSL, `difference` in the JSON syntax) indicates that a <ProductConcept section="what-is-a-relationship" linkName="relationship" /> exists if the <ProductConcept section="what-is-a-user" linkName="user" /> is in the base userset but not in the excluded userset. This operator is particularly useful when modeling exclusion or block lists.
745745

746746
<AuthzModelSnippetViewer
747747
configuration={{
@@ -774,7 +774,7 @@ The **exclusion operator** (`but not` in the DSL, `difference` in the JSON synta
774774
}} skipVersion={true}
775775
/>
776776

777-
In the type definition snippet above, `user:anne` is a `viewer` of `document:new-roadmap` if:
777+
In the type definition snippet above, `user:anne` is a `viewer` of `document:new-roadmap` if and only if:
778778

779779
- `anne` has a direct relationship as `viewer` to `document:new-roadmap`
780780

@@ -789,7 +789,7 @@ In the type definition snippet above, `user:anne` is a `viewer` of `document:new
789789
/>
790790
AND
791791

792-
- `anne` is not blocked from document:new-roadmap; the following relation tuple **does not exist**:
792+
- `anne` is not blocked from `document:new-roadmap` (i.e., the following relationship tuple must not exist):
793793
<RelationshipTuplesViewer
794794
relationshipTuples={[
795795
{
@@ -820,6 +820,119 @@ but not in:
820820
- `anne` is blocked on the document:new-roadmap `{"user": "user:anne", "relation": "blocked", "object": "document:new-roadmap"}`
821821

822822
:::
823+
### Grouping and nesting operators
824+
825+
You can define complex conditions by using parentheses to group and nest operators. Note that direct relationships can be included in an expression with parentheses.
826+
827+
<AuthzModelSnippetViewer
828+
configuration={
829+
{
830+
"schema_version": "1.1",
831+
"type_definitions": [
832+
{
833+
"type": "user",
834+
"relations": {},
835+
"metadata": null
836+
},
837+
{
838+
"type": "organization",
839+
"relations": {
840+
"member": {
841+
"this": {}
842+
}
843+
},
844+
"metadata": {
845+
"relations": {
846+
"member": {
847+
"directly_related_user_types": [
848+
{
849+
"type": "user"
850+
}
851+
]
852+
}
853+
}
854+
}
855+
},
856+
{
857+
"type": "folder",
858+
"relations": {
859+
"organization": {
860+
"this": {}
861+
},
862+
"parent": {
863+
"this": {}
864+
},
865+
"viewer": {
866+
"intersection": {
867+
"child": [
868+
{
869+
"union": {
870+
"child": [
871+
{
872+
"this": {}
873+
},
874+
{
875+
"tupleToUserset": {
876+
"computedUserset": {
877+
"relation": "viewer"
878+
},
879+
"tupleset": {
880+
"relation": "parent"
881+
}
882+
}
883+
}
884+
]
885+
}
886+
},
887+
{
888+
"tupleToUserset": {
889+
"computedUserset": {
890+
"relation": "member"
891+
},
892+
"tupleset": {
893+
"relation": "organization"
894+
}
895+
}
896+
}
897+
]
898+
}
899+
}
900+
},
901+
"metadata": {
902+
"relations": {
903+
"organization": {
904+
"directly_related_user_types": [
905+
{
906+
"type": "organization"
907+
}
908+
]
909+
},
910+
"parent": {
911+
"directly_related_user_types": [
912+
{
913+
"type": "folder"
914+
}
915+
]
916+
},
917+
"viewer": {
918+
"directly_related_user_types": [
919+
{
920+
"type": "user"
921+
}
922+
]
923+
}
924+
}
925+
}
926+
}
927+
]
928+
}
929+
} skipVersion={true}
930+
/>
931+
932+
933+
### Conditional relationships
934+
935+
<ProductName format={ProductNameFormat.ShortForm}/> supports conditional relationships, which are only considered if a specific condition is met. You can learn more about Conditional Relationships in the [Modeling: Conditional Relationships](./modeling/conditions.mdx) guide.
823936

824937
## Equivalent Zanzibar Concepts
825938

0 commit comments

Comments
 (0)