SpaceRole

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

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

资源结构

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

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

系统属性 (sys)

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

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

SpaceRole 是没有发布概念的设置类资源。因此与 ContentMedia 不同,其 sys 中没有 publisharchivestatus,只有 version。每次修改 SpaceRoleversion 都会递增。

权限映射:contentType、content、media

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

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

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

  • self:将该规则适用的对象限定为资源自身这一个。放入指向目标资源的 Refer。在 contentType 映射中表示某一个特定的 Content Type,在 script 映射中表示某一个特定的 Script
  • contentType:限定为该 ContentContent Type。放入指向 Content TypeRefer
  • 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 TypepublishWithAuthor 必须为 true CDA 依据发布快照中的 sys.createdBy 判定该过滤器,而当 publishWithAuthor 为默认值 false 时,快照中没有作者,因此 Allow 规则不会匹配到任何内容,Deny 规则也无法过滤掉任何人。CMA(管理)依据草稿的 sys.createdBy 判定,与该设置无关。publishWithAuthor 不追溯,因此必须在发布内容之前开启,已发布的 Content 也需要重新发布。请参考 Content TypepublishWithAuthor 说明。

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

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

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

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

{
  "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 角色的示例。仅在 contentRead 操作上设置规则,并通过该规则的 contentType 过滤器限定为某一个 Content TypeContent Type 本身和 Media 都以空的 AllowAll 上开放,但对内容数据只能读取这一个种类。由于 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_LOGINServiceLoginServiceUserServiceUserRole
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 TokenDelivery Access TokenServiceUser 令牌无论在角色中放入哪些操作,都无法调用该列表中的 API。

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

script(Script 权限)

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

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

Script 不是需要发布的资源,因此不使用 PublishUnpublish 之类的发布操作。可以用作规则过滤器的是 selfcreatedBy 这两个

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

contentTypetag 是不附加于 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 所涉及的 ContentMedia 操作权限,否则保存会被拒绝(参见 Script 的错误)。详细内容请参见 Script 的执行语义、约束与安全

错误

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

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

API

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