配置语言 OpenFGA 的配置语言构建了系统授权模型的表示,该模型向 OpenFGA 的 API 提供系统中对象类型及其相互关系的信息。配置语言描述了给定类型对象可能的关联关系,并列出了对象之间建立关联的条件。
配置语言可采用 DSL 或 JSON 语法呈现。JSON 语法被 API 接受,并与 Zanzibar 论文中的语言紧密对应。DSL 在 JSON 基础上添加了语法糖以提升易用性,但在发送至 OpenFGA API 之前会编译为 JSON。JSON语法用于直接调用API或通过SDK调用,而DSL用于在Playground、CLI以及Visual Studio Code和IntelliJ的IDE扩展中与OpenFGA交互。在本文档中,这两种语法可以互换使用。
在开始本指南之前,请先熟悉OpenFGA的基本概念以及如何开始建模。
配置语言是什么样子的? 以下是一个授权模型的示例。接下来的部分将讨论 OpenFGA 配置语言的基础知识。
DSL
model
schema 1.1
type user
type domain
relations
define member: [user]
type folder
relations
define can_share: writer
define owner: [user, domain#member] or owner from parent_folder
define parent_folder: [folder]
define viewer: [user, domain#member] or writer or viewer from parent_folder
define writer: [user, domain#member] or owner or writer from parent_folder
type document
relations
define can_share: writer
define owner: [user, domain#member] or owner from parent_folder
define parent_folder: [folder]
define viewer: [user, domain#member] or writer or viewer from parent_folder
define writer: [user, domain#member] or owner or writer from parent_folder
信息 授权模型描述了四种类型的对象:用户、域、文件夹和文档。
域类型定义有一个名为“成员”的单一关系,仅允许直接关系。
文件夹和文档类型的定义各自包含五个关系:父文件夹、所有者、写入者、查看者和可共享。
直接关系类型限制 当在关系定义开头使用时,[<字符串, <字符串>, ...] 允许指定类型对象之间的直接关系。字符串可以采用以下三种格式之一:
<类型>:表示可以写入将该类型对象作为用户的元组。例如,如果“组”在类型限制中,则可以添加“组:营销”。 <类型:>:表示可以写入将该类型所有对象的元组。例如,如果“用户:”在类型限制中,则可以添加“用户:*”。 <类型>#<关系>:表示与该类型对象通过特定关系关联的用户集合元组。例如,如果“组#成员”在类型限制中,则可以添加“组:营销#成员”。 如果未指定直接关系类型限制,则直接关系被禁止,且无法编写与该类型对象通过此特定关系关联的其他对象的元组。
info [, , ...] 在 OpenFGA DSL 中对应于 OpenFGA API 语法中的以下内容。
例如,以下是团队类型的片段:
type team relations define member: [user, user:*, team#member]
上述团队类型定义指定了用户与团队类型对象之间所有可能的关系。在此示例中,关系为成员关系。
由于使用了 [user, team#member] 直接关系类型限制,系统中的用户可与团队类型建立成员关系,且该关系仅适用于以下对象:
type user 用户类型绑定为公共访问(user:*) 具有团队类型和成员关系的用户集(例如 team:product#member) 在上述类型定义片段中,如果存在以下关系元组集中的任何一个,则 anne 是 team:product 的成员:
-
[// Anne is directly related to the product team as a member { "user": "user:anne", "relation": "member", "object": "team:product", "_description": "Anne is directly related to the product team as a member" }] -
[// Everyone (`*`) is directly related to the product team as a member { "user": "user:*", "relation": "member", "object": "team:product", "_description": "Everyone (`*`) is directly related to the product team as a member" }] -
[// Members of the contoso team are members of the product team { "user": "team:contoso#member", "relation": "member", "object": "team:product", "_description": "Members of the contoso team are members of the product team" }// Anne is a member of the contoso team { "user": "user:anne", "relation": "member", "object": "team:contoso", "_description": "Anne is a member of the contoso team" }]