SpaceRole

SpaceRole 是授予 Space 成员的一组权限。它在单个资源中规定了对 Content Type、Content、Media 可以执行哪些操作(读取、创建、编辑、删除、发布),是否可以执行和管理 Script,以及是否可以访问 Space 设置。将权限范围收窄(例如仅限某个 Content Type、仅限自己创建的内容)的过滤器也在 SpaceRole 内部设定。

创建出来的 SpaceRole 本身不会应用于任何人。要将它授予成员,需将该 SpaceRole 的 Refer 放入 Space Membership 的 roles 中。一个成员可以同时拥有多个 SpaceRole。此外,DeliveryAccessToken 也会绑定到一个 least-privilege(最小权限)SpaceRole,由它决定该令牌可以交付的范围。

资源结构

下面是 SpaceRole “商品只读” 的单条查询响应。除了 sys(系统属性)之外,它还拥有用于规定权限的正文属性 contentType、content、media、settings、script。

{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7ObyNrQQbHbm",
    "type": "SpaceRole",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-16T09:53:16.617Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-16T09:53:16.617Z",
    "isLocked": false,
    "version": 1
  },
  "name": "商品只读",
  "contentType": { "All": { "Allow": [] } },
  "content": {
    "Read": {
      "Allow": [
        { "contentType": { "sys": { "id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA", "type": "Refer", "targetType": "ContentType" } } }
      ]
    }
  },
  "media": { "All": { "Allow": [] } },
  "settings": [],
  "script": {}
}

主要键:

  • contentType:对 Content Type 本身(schema)的权限映射。按操作分别规定读取、创建、修改、删除、发布 Content Type 的权限。
  • content:对 Content(内容数据)的权限映射。上面的示例展示了只允许读取某个特定 Content Type 的 Content 的情形。
  • media:对 Media(文件、图片)的权限映射。
  • script:对 Script(前端调用的声明式后端端点)的权限映射。按操作分别规定执行(Execute)与管理(创建、读取、编辑、删除)。
  • settings:规定 Space 设置访问权限的字符串数组。它不是权限映射,而是直接列出操作名称。完全访问为 ["SETTING_ALL"],不授予任何设置访问权限则为 [],也可以只挑选需要的设置放入(参见下面的 settings)。
  • isLocked:为 true 时,表示这是 Weegloo 默认提供的角色(例如 Administrator),因此无法修改或删除。

系统属性 (sys)

每个 SpaceRole 都将公共系统属性放在 sys 对象中。space、createdBy、updatedBy 以 Refer 形式({ "sys": { "id", "type": "Refer", "targetType" } })出现。

属性类型说明
idstring资源的唯一标识符。
typestring资源种类。SpaceRole 始终为 "SpaceRole"。
spaceRefer<Space>此 SpaceRole 所属的 Space。
createdByRefer<User>创建者用户。
createdAtstring (date-time)创建时间。
updatedByRefer<User>最后修改者用户。
updatedAtstring (date-time)最后修改时间。
isLockedboolean为 true 时表示是默认提供的角色,无法修改或删除。自行创建的角色为 false。
versioninteger (≥1)资源版本。每次修改递增 1。

SpaceRole 是没有发布概念的设置类资源。因此与 Content、Media 不同,其 sys 中没有 publish、archive、status,只有 version。每次修改 SpaceRole 时 version 都会递增。

权限映射:contentType、content、media

contentType、content、media 各自都是以操作为键的映射。可以使用的操作是 Create(创建)、Read(读取)、Edit(编辑)、Delete(删除)、Publish(发布)、Unpublish(取消发布)、Archive(归档)、Unarchive(取消归档),另外还有一次性指代所有操作的 All。不存在名为 Save 的操作。修改权限是 Edit,而 Save 是 Webhook 订阅的事件名称。每个操作的值是一个包含 Allow(允许)和 Deny(拒绝)规则数组的对象。

"content": {
  "Read":   { "Allow": [ /* 规则 */ ], "Deny": [ /* 规则 */ ] },
  "Edit":   { "Allow": [ /* 规则 */ ] }
}

每个规则(rule)对象都带有用于收窄权限范围的可选过滤器。

  • self:将该规则适用的对象限定为资源自身这一个。放入指向目标资源的 Refer。在 contentType 映射中表示某一个特定的 Content Type,在 script 映射中表示某一个特定的 Script。
  • contentType:限定为该 Content 所属的 Content Type。放入指向 Content Type 的 Refer。
  • createdBy:仅限定为某个特定用户创建的资源。在 sys.id 中填入某个用户 id 则仅限其创建的内容;填入保留值 :self 则限定为“仅当前调用者创建的内容”。
  • tag:仅限定为带有某个特定 Tag 的资源。

哪个过滤器在哪个权限映射中有意义是固定的。 放入不匹配的过滤器时,角色保存会被拒绝。因为若是悄悄忽略,本以为收窄了的规则就会变成全部允许。

权限映射可以使用的过滤器放入就会拒绝保存的过滤器
contentTypeself(该 Content Type 自身)·createdBycontentType
contentcontentType(该 Content 所属的种类)·createdBy·tagself
mediacreatedBy·tagself
scriptself(该 Script 自身)·createdBycontentType·tag
  • contentType 映射的对象要用 self 指定,而不是 contentType。 因为那是限定 Content Type 自身。contentType 过滤器的含义是“该资源所引用的种类”,因此只适用于 content 映射。
  • 若要用该资源上并不存在的轴来收窄(在 Content Type 上用 tag,在 Media 上用 contentType),保存虽然不会被拦,但规则不会按预期判定。请不要使用。

在 CDA(交付)中判定 createdBy 过滤器(含 :self)时,目标 Content Type 的 publishWithAuthor 必须为 true。 CDA 依据发布快照中的 sys.createdBy 判定该过滤器,而当 publishWithAuthor 为默认值 false 时,快照中没有作者,因此 Allow 规则不会匹配到任何内容,Deny 规则也无法过滤掉任何人。CMA(管理)依据草稿的 sys.createdBy 判定,与该设置无关。publishWithAuthor 不追溯,因此必须在发布内容之前开启,已发布的 Content 也需要重新发布。请参考 Content Type 的 publishWithAuthor 说明。

空的 Allow 数组 [] 表示对该种类的全部资源允许该操作。由于过滤器为空,没有可过滤的内容,因此该操作对所有资源开放。

空的 Deny 数组 [] 的行为则相反。 它不是“什么都不拒绝”,而是拒绝该种类的全部资源,从而彻底禁止该操作。即使同时写上 Allow 也一样会被禁止。若以“没有要拒绝的对象”之意放入 [],行为会完全相反,因此若不想拒绝任何内容,请不要放入 Deny 键本身。

示例 1:Administrator(全部权限,默认提供)

Administrator 角色对 contentType、content、media、script 都在 All 操作上给出空的 Allow 以允许全部,并在 settings 中给出 ["SETTING_ALL"] 以访问 Space 设置的全部内容。该角色由 Weegloo 默认提供,因此 sys.isLocked 为 true,无法修改或删除。

{
  "sys": {
    "id": "3trmXRLdJF4GBlAjtcuoWfVubsasp4",
    "type": "SpaceRole",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "_", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-14T14:56:04.737Z",
    "updatedBy": { "sys": { "id": "_", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-14T14:56:04.737Z",
    "isLocked": true,
    "version": 1
  },
  "name": "Administrator",
  "description": "Members of this role have full access to everything in this space.",
  "contentType": { "All": { "Allow": [] } },
  "content": { "All": { "Allow": [] } },
  "media": { "All": { "Allow": [] } },
  "settings": ["SETTING_ALL"],
  "script": { "All": { "Allow": [] } }
}

示例 2:只读(仅限某个 Content Type)

这是自行创建的 least-privilege 角色的示例。仅在 content 的 Read 操作上设置规则,并通过该规则的 contentType 过滤器限定为某一个 Content Type。Content Type 本身和 Media 都以空的 Allow 在 All 上开放,但对内容数据只能读取这一个种类。由于 settings 为 [],因此无法访问 Space 设置。将这样的角色绑定到 DeliveryAccessToken,交付令牌就只会读取该范围。该角色的 JSON 与上面资源结构中的 “商品只读” 相同。

settings(Space 设置访问)

settings 不是权限映射,而是字符串数组。它承载对 Space 设置的访问权限,既没有 Allow/Deny,也没有过滤器。放入数组的操作即被允许,未放入的操作则不被允许。

完全访问为 ["SETTING_ALL"],不授予任何访问权限则设为 []。如果需要介于两者之间的粒度,可以从下面的操作中挑选放入。

操作可以操作的内容
SETTING_GENERALSpace 本身(名称、说明等)
SETTING_LOCALELocale
SETTING_WEBHOOKWebhook(含调用记录与状态)
SETTING_APPMarket App 安装
SETTING_TAGTag
SETTING_DELIVERY_ACCESS_TOKENDelivery Access Token
SETTING_SPACE_ACCESS_TOKENSpace Access Token
SETTING_USERSpace Membership(成员分配)
SETTING_ROLESpaceRole
SETTING_WEB_HOSTINGWeb Hosting 与自定义域名
SETTING_SERVICE_LOGINServiceLogin、ServiceUser、ServiceUserRole
SETTING_EMAIL_ACCOUNT邮件发送账户
SETTING_MONITORING使用量与指标查询
SETTING_SCHEDULERScheduler 与其执行记录
SETTING_ALL以上全部

两类令牌的操作是分开的。只授予 SETTING_DELIVERY_ACCESS_TOKEN 时,虽然可以签发只读的 Delivery Access Token,却无法签发连写入也能进行的 Space Access Token。

settings 中的操作只能通过控制台登录会话和 Personal Access Token 调用。Space Access Token、Delivery Access Token、ServiceUser 令牌无论在角色中放入哪些操作,都无法调用该列表中的 API。

权限映射(contentType、content、media、script)的操作列表,过滤器键(self、contentType、createdBy、tag)和 :self 的含义,以及哪个过滤器在哪个映射中有效,均遵循上面的权限映射:contentType、content、media一节。

script(Script 权限)

script 是对 Script(前端调用的声明式后端端点)的权限映射。其结构与 content、media 相同,以操作为键,以 Allow/Deny 规则数组为值。使用的操作如下。

  • Create、Read、Edit、Delete:创建、查询、修改、删除 Script 资源。
  • Execute:执行 Script(调用 /execute)。这是 Script 特有的操作。
  • All:包含上述全部的上位操作。

Script 不是需要发布的资源,因此不使用 Publish、Unpublish 之类的发布操作。可以用作规则过滤器的是 self 与 createdBy 这两个。

  • self:限定为某一个特定的 Script。放入指向该 Script 的 Refer(targetType 为 Script)。
  • createdBy:限定为创建者(用 :self 表示“仅自己创建的 Script”)。

contentType、tag 是不附加于 Script 的轴,放入后角色保存会被拒绝。

例如,要允许执行所有 Script,但将查询收窄为仅限自己创建的内容,可以这样写。

"script": {
  "Execute": { "Allow": [] },
  "Read": {
    "Allow": [
      { "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } } }
    ]
  }
}

用 self 收窄后,就成为只能执行一个 Script 的最小权限。 这是在把执行权限交给支付服务商这类外部系统时,只打开它要调用的那一个窗口、其余全部关闭的做法。

"script": {
  "Execute": {
    "Allow": [
      { "self": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } } }
    ]
  }
}

把这个角色绑定到 Space Access Token,该令牌就只能执行所指定的那一个 Script。为什么要收窄到一项执行权限,以及 Script 的执行是受委托作者权限这一点,参见 Script 的执行语义、约束与安全。

该 script 权限规定的是“能否执行和管理 Script 资源”。除此之外,在编写(创建、修改)Script 时,创建者在保存时必须实际拥有该 Script 的各 statement 所涉及的 Content、Media 操作权限,否则保存会被拒绝(参见 Script 的错误)。详细内容请参见 Script 的执行语义、约束与安全。

错误

以下是处理 SpaceRole 时会遇到的错误码。所有资源共通的错误码,请参见通用错误。

错误码条件
WGL400020在规则中放入了在该权限映射中没有意义的过滤器,并试图保存该角色。

API

以下所有端点的基准 URL 均为 https://cma.weegloo.com/v1,并需要在 Authorization 头中携带用于认证 CMA 的 Bearer 令牌。修改角色(PUT、PATCH)时,为实现乐观并发控制,必须一并发送 X-Weegloo-Version 头(当前资源的 sys.version)。创建和删除没有该头。sys.isLocked 为 true 的默认提供角色无法修改或删除。