Configuration Language

79 阅读3分钟

配置语言 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"
    }]