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" } })出现。
| 属性 | 类型 | 说明 |
|---|---|---|
id | string | 资源的唯一标识符。 |
type | string | 资源种类。SpaceRole 始终为 "SpaceRole"。 |
space | Refer<Space> | 此 SpaceRole 所属的 Space。 |
createdBy | Refer<User> | 创建者用户。 |
createdAt | string (date-time) | 创建时间。 |
updatedBy | Refer<User> | 最后修改者用户。 |
updatedAt | string (date-time) | 最后修改时间。 |
isLocked | boolean | 为 true 时表示是默认提供的角色,无法修改或删除。自行创建的角色为 false。 |
version | integer (≥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 的资源。
哪个过滤器在哪个权限映射中有意义是固定的。 放入不匹配的过滤器时,角色保存会被拒绝。因为若是悄悄忽略,本以为收窄了的规则就会变成全部允许。
| 权限映射 | 可以使用的过滤器 | 放入就会拒绝保存的过滤器 |
|---|---|---|
contentType | self(该 Content Type 自身)·createdBy | contentType |
content | contentType(该 Content 所属的种类)·createdBy·tag | self |
media | createdBy·tag | self |
script | self(该 Script 自身)·createdBy | contentType·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_GENERAL | Space 本身(名称、说明等) |
SETTING_LOCALE | Locale |
SETTING_WEBHOOK | Webhook(含调用记录与状态) |
SETTING_APP | Market App 安装 |
SETTING_TAG | Tag |
SETTING_DELIVERY_ACCESS_TOKEN | Delivery Access Token |
SETTING_SPACE_ACCESS_TOKEN | Space Access Token |
SETTING_USER | Space Membership(成员分配) |
SETTING_ROLE | SpaceRole |
SETTING_WEB_HOSTING | Web Hosting 与自定义域名 |
SETTING_SERVICE_LOGIN | ServiceLogin、ServiceUser、ServiceUserRole |
SETTING_EMAIL_ACCOUNT | 邮件发送账户 |
SETTING_MONITORING | 使用量与指标查询 |
SETTING_SCHEDULER | Scheduler 与其执行记录 |
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 的默认提供角色无法修改或删除。
相关文档
- Space Membership:将 SpaceRole 绑定到成员的
roles。 - Delivery Access Token:绑定到 least-privilege SpaceRole 的交付令牌。
- Content Type:权限规则所指向的 Content Type。
