关于 platform-dataspace-access-configure
用于通过 PermissionSet 元数据和 Connect API 配置或检查 Salesforce Data Cloud DataSpace 权限的技能。它区分基于元数据的范围授权、可选的对象级授权和只读检查。
主要功能
- 01创建或更新 DataSpace 范围
- 02授予 DMO、DLO 和 CIO 对象访问权
- 03列出或撤销对象访问授权
- 04检查现有 DataSpace 范围
- 05区分元数据部署与运行时授权
适用场景
- 01为 PermissionSet 授予 DataSpace 访问权
- 02授予 DataSpace 内特定数据对象权限
- 03只读检查现有 DataSpace 访问设置
- 04撤销对象级权限授权
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-dataspace-access-configure安装后在 Claude Code 中输入/platform-dataspace-access-configure确认已加载。
附带文件scripts/inspect-dataspace-scopes.sh
详细介绍
platform-dataspace-access-configure
使用双层模型在 Salesforce Data Cloud 中配置 DataSpace 访问权限:
- DataSpace 级访问权限 — 在权限集 XML 中嵌入
<dataspaceScopes>元素,并通过 MDAPI 部署,以授予PermissionSet对 DataSpace 的访问权限。 - 对象级访问权限(可选) — 使用 Object Access Grants Connect API,授予该权限集对 DataSpace 中特定 DMO / DLO / CIO 对象的访问权限。
必须通过 MDAPI 层建立 PermissionSet → DataSpace 关联。Connect API 层为可选,只有在需要将访问权限限定于特定对象,而不是完全由数据治理策略控制时才需要使用。
先确定场景
写入任何文件之前,请从下表中准确选择一个场景。每个场景的输出内容都不同。
| 场景 | 用户意图 | 权限集状态 | 要输出的文件 |
|---|---|---|---|
| A. 创建具有 DS 访问权限的新权限集 | “创建一个名为 X、具有 dataspace 范围 Y 的权限集” | 尚不存在 | permissionsets/<Name>.permissionset-meta.xml 和 package.xml |
| B. 为现有权限集添加 DS 访问权限 | “授予现有权限集 X 对 dataspace Y 的访问权限” | 已部署(可能包含其他权限) | 已修补的 permissionsets/<Name>.permissionset-meta.xml 和 package.xml — 参见下文的场景 B 工作流 |
| C. 仅授予对象级访问权限 | “授予权限集 X 对对象 Z(位于 dataspace Y 中)的访问权限” — 权限集和范围已配置 | 已部署且包含 dataspaceScopes | api-request.json(Connect API 请求正文)。不需要权限集 XML,也不需要 package.xml |
| D. 检查现有 DS 访问权限 | “哪些权限集有权访问 dataspace Y?” | 任意 | 仅聊天回复 / 报告。不需要可部署文件,也不执行运行时 API 修改 |
只输出所选场景列出的文件。对于场景 C 的请求输出场景 A/B 文件(反之亦然)属于正确性错误 — 多余文件会改变部署内容。
场景 B — 至关重要: PermissionSet MDAPI 部署会完全替换元数据。重新部署时,任何被省略的
<objectPermissions>、<fieldPermissions>、<userPermissions>、<tabSettings>、<applicationVisibilities>、<recordTypeVisibilities>、<customPermissions>、<pageAccesses>、<classAccesses>、<customMetadataTypeAccesses>、<customSettingAccesses>、<externalDataSourceAccesses>元素都会从组织中删除。向现有权限集添加<dataspaceScopes>之前,先检索当前 XML 并在此基础上修补 — 不要从头手动编写。
场景 B 工作流
- 检索现有权限集:
sf project retrieve start --metadata PermissionSet:<Name> --target-org <alias> - 打开检索到的
permissionsets/<Name>.permissionset-meta.xml。保留其中已有的所有元素。 - 插入目标 DataSpace 的
<dataspaceScopes>块(在文件中的元素顺序不影响 MDAPI)。如果文件中已有针对同一 DataSpace 的<dataspaceScopes>块,只替换该块。保留针对其他 DataSpace 的所有<dataspaceScopes>块 — 每个 DataSpace 对应一个块。若请求移除范围,则仅移除匹配的块并部署;省略该块即可撤销对应 DataSpace 的授权。通过重新检索 PermissionSet 并确认匹配的<dataspaceScopes>块已不存在来验证。 - 编写
package.xml,在<members>中列出该权限集。 - 使用
sf project deploy start重新部署。
此技能负责的任务
用户希望执行以下操作时,触发此技能:
- 创建一个可访问 Data Cloud DataSpace 的权限集
- 为现有权限集添加或修改
dataspaceScopes - 授予权限集对 DataSpace 中特定 DMO / DLO / CIO 对象的访问权限
- 列出哪些权限集具有 DataSpace 范围,并检查其访问级别
- 配置 DataSpace 范围的
dataAccessLevel和objectAccessLevel - 列出或移除某个权限集与 DataSpace 配对的对象访问授权
以下情况应委派给其他技能:
- 权限集完全没有 DataSpace 访问权限 →
platform-permission-set-generate
第 1 层 — DataSpace 级访问权限(MDAPI)
在 PermissionSet XML 中嵌入 <dataspaceScopes> 元素。使用 MDAPI 部署。
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Data Cloud Analyst</label>
<description>Data cloud analyst access to the default dataspace</description>
<hasActivationRequired>false</hasActivationRequired>
<dataspaceScopes>
<dataspaceScope>default</dataspaceScope>
<dataAccessLevel>ALL</dataAccessLevel>
<objectAccessLevel>BY_POLICY</objectAccessLevel>
</dataspaceScopes>
</PermissionSet>
元素规则
| 元素 | 必填 | 有效值 | 用途 |
|---|---|---|---|
<dataspaceScopes> | 是 | 父元素(复数) | 单个 DataSpace 范围授权的容器 |
<dataspaceScope> | 是 | DataSpace API 名称(例如 default) | 此授权对应的 DataSpace |
<dataAccessLevel> | 是 | NONE、CONTROLLED_BY_PARENT、ALL | DataSpace 内的行级数据访问权限 |
<objectAccessLevel> | 是 | BY_POLICY、ALL_IN_DATASPACE | 对象级访问权限。BY_POLICY 表示遵循数据治理策略。仅当 dataAccessLevel 为 CONTROLLED_BY_PARENT 时,才允许使用 ALL_IN_DATASPACE |
常见错误
- 父元素名称错误 — 使用
<dataspaceScopeAccess>而不是<dataspaceScopes>。部署可能会静默失败,或返回难以理解的错误。 - 子元素名称错误 — 使用
<dataspaceScopeName>而不是<dataspaceScope>。 - 枚举值错误 —
ViewAllRows/Read/OWNER/EDIT均为无效值。dataAccessLevel使用NONE、CONTROLLED_BY_PARENT或ALL;objectAccessLevel使用BY_POLICY或ALL_IN_DATASPACE。允许的组合请参见“元素规则”表。部署错误-379999659表示枚举值无效。 - 在一个元素中指定多个范围 — 一个
<dataspaceScopes>只授予对一个 DataSpace 的访问权限。若要授予对多个 DataSpace 的访问权限,请添加多个<dataspaceScopes>块。
包布局(案例 A 和案例 B)
第 1 层的可部署包始终包含两个文件:
<output-root>/
package.xml
permissionsets/<Name>.permissionset-meta.xml
package.xml(必需 — 在 <members> 中列出每个要部署的权限集):
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Data_Cloud_Analyst</members>
<name>PermissionSet</name>
</types>
<version>67.0</version>
</Package>
部署:
sf project deploy start --source-dir force-app/main/default/permissionsets/ --target-org <alias>
只读 DataSpace 范围检查 — 案例 D
当用户询问哪些权限集有权访问某个 DataSpace,或要求检查 dataAccessLevel 和 objectAccessLevel 但不进行更改时,使用案例 D。
切勿使用 SOQL 查询 DataspaceScope 或 DataspaceScopeAccess。 这些对象不支持通过查询来检索此关系。不要尝试将 SOQL 用作发现、回退或故障排查手段。
- 将 PermissionSet 元数据检索到隔离的临时本地项目和输出目录中。不要检索到用户现有的元数据目录树中。先保存技能仓库路径(如有可能,使用绝对路径):
Inspect the JSON result before continuing. A nonzero command status, a failedREPO_ROOT="<absolute/path/to/sf-skills-internal>" # or $(pwd) if you're in the repo root WORK_DIR=$(mktemp -d) sf project generate --name dataspace-scope-inspection --output-dir "$WORK_DIR" cd "$WORK_DIR/dataspace-scope-inspection" sf project retrieve start --json \ --metadata "PermissionSet:*" --target-org <alias> \ --output-dir "$WORK_DIR/retrieved"result.status, warnings, or an unexpectedly lowresult.filePropertiescount means the retrieve may be incomplete. Report that limitation rather than treating the result as empty, and do not fall back to SOQL. - Run the inspection script from the skill directory (do not rely on relative paths
after
cdchanged the working directory). Supply the retrieved directory and optional DataSpace name:
每行向用户报告一条结果。"$REPO_ROOT/skills/platform-dataspace-access-configure/scripts/inspect-dataspace-scopes.sh" \ "$WORK_DIR/retrieved" "<DataSpace API name, if given>"
案例 D 对组织是只读的。不要部署元数据、分配权限集、执行 Apex、执行记录 DML,也不要发出 POST、PUT、PATCH 或 DELETE 请求。检查过程中,不要在用户的工作区中生成 package.xml、PermissionSet XML 或 api-request.json。报告完成后,删除临时工作目录:rm -rf "$WORK_DIR"。范围级别的 objectAccessLevel 并不列出明确的对象授权;只有在用户要求时,才使用只读对象访问授权端点单独检查这些授权。
第 2 层 — 对象级访问(Connect API)— 案例 C
仅在 objectAccessLevel 不是 BY_POLICY,或治理策略未涵盖目标对象时需要。授权在运行时生效——无需 MDAPI 部署、无需 package.xml、无需权限集 XML。案例 C 任务唯一需要的产物是一个描述 Connect API 调用的 api-request.json。
先解析 API 版本
此层中的每个 Connect API endpoint 都包含一个 /services/data/v<apiVersion>/… 段。不要硬编码 v67.0。 在编写请求封套之前,先解析目标组织的实际 API 版本,确保请求与该组织支持的接口一致:
sf org display --target-org <alias> --json | jq -r '.result.apiVersion'
- 将返回值(例如
67.0、68.0)替换到endpoint中,格式为v<apiVersion>。 - 如果无法查询组织(离线编写,尚无别名),则回退到此技能 frontmatter 中的
minApiVersion(67.0)——该 endpoint 在此版本引入,任何更新版本都接受相同的请求体。 - 如果用户在提示词中明确指定了版本,则原样使用。
在以下模板中,{apiVersion} 是占位符。生成 api-request.json 前,将其替换为已解析的 API 版本(例如 67.0、68.0)。
api-request.json — 规范格式
将请求输出为包含 method、endpoint、headers、body 和 expectedResponse 的自描述封套。不要只输出请求体——审阅者和下游工具会读取整个封套。
{
"method": "POST",
"endpoint": "/services/data/v{apiVersion}/ssot/data-governance/object-access-grants",
"headers": {
"Content-Type": "application/json"
},
"body": {
"permissionSetName": "Data_Cloud_Analyst",
"dataSpaceName": "default",
"objectApiName": "Account__dlm"
},
"expectedResponse": {
"status": 201,
"body": {
"permissionSetName": "Data_Cloud_Analyst",
"dataSpaceName": "default",
"objectApiName": "Account__dlm"
}
}
}
批量授权
使用相同的 api-request.json 封套格式。endpoint 增加 /actions/bulk-create 后缀,body.objectApiName 替换为列表类型的 body.objectApiNames,并且 expectedResponse 省略 body 字段,因为批量响应会返回每个对象的状态条目,而不是扁平的请求负载(见下文的注意事项)。
{
"method": "POST",
"endpoint": "/services/data/v{apiVersion}/ssot/data-governance/object-access-grants/actions/bulk-create",
"headers": {
"Content-Type": "application/json"
},
"body": {
"permissionSetName": "Data_Cloud_Analyst",
"dataSpaceName": "default",
"objectApiNames": ["Account__dlm", "Contact__dlm", "Opportunity__dlm"]
},
"expectedResponse": {
"status": 201
}
}
列出授权
使用相同的封套格式,method: "GET",在 endpoint 中添加查询参数,并且不包含 body。
{
"method": "GET",
"endpoint": "/services/data/v{apiVersion}/ssot/data-governance/object-access-grants?permissionSetName=Data_Cloud_Analyst&dataSpaceName=default",
"headers": {
"Accept": "application/json"
},
"expectedResponse": {
"status": 200
}
}
撤销授权
使用相同的封套格式,method: "DELETE",将对象 API 名称作为路径段,并设置 expectedResponse.status: 204(无内容)。
{
"method": "DELETE",
"endpoint": "/services/data/v{apiVersion}/ssot/data-governance/object-access-grants/Account__dlm?permissionSetName=Data_Cloud_Analyst&dataSpaceName=default",
"headers": {
"Accept": "application/json"
},
"expectedResponse": {
"status": 204
}
}
对象类型
- DMO(数据模型对象)——统一的配置文件对象,后缀为
__dlm - DLO(数据湖对象)——原始摄取数据,后缀为
__dll - CIO(计算洞察对象)——计算得出的指标,后缀为
__cio
组合设置 — 从零开始的案例 A + 案例 C
仅当用户从零开始,并要求在同一个请求中同时配置权限集和范围以及逐对象授权时,才使用本节。如果用户的提示词仅涉及 Connect API 授权(案例 C)——例如“授予 Account__dlm 访问权限;权限集和数据空间范围已经存在”——则完全跳过本节,只输出第 2 层中的 api-request.json。
以下命令是面向操作员的 sf CLI 调用(可运行的从零开始操作指南),而不是要输出的产物。对于常规案例 C 任务,产物是一个第 2 层所述的 api-request.json 封套。
目标: 授予 Data_Cloud_Analyst 权限集对 default DataSpace 中 Account__dlm 和 Contact__dlm 的访问权限。
步骤 1 — 部署带有 DataSpace 范围的 PermissionSet(MDAPI):
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Data Cloud Analyst</label>
<description>Data cloud analyst access to the default dataspace</description>
<hasActivationRequired>false</hasActivationRequired>
<dataspaceScopes>
<dataspaceScope>default</dataspaceScope>
<dataAccessLevel>ALL</dataAccessLevel>
<objectAccessLevel>BY_POLICY</objectAccessLevel>
</dataspaceScopes>
</PermissionSet>
sf project deploy start --source-dir permissionsets/ --target-org <alias>
步骤 2 — 授予对象访问权限(Connect API):
(此处需要此步骤,因为 default DataSpace 没有涵盖 Account__dlm 和 Contact__dlm 的治理策略。如果 BY_POLICY 策略已管理目标对象,则跳过步骤 2——仅第 1 层即可。)
先解析组织的 API 版本(参见上文先解析 API 版本),然后将其替换到 --path 值中:
API_VERSION=$(sf org display --target-org <alias> --json | jq -r '.result.apiVersion')
sf org api rest --target-org <alias> \
--method POST \
--path "/services/data/v${API_VERSION}/ssot/data-governance/object-access-grants/actions/bulk-create" \
--body '{
"permissionSetName": "Data_Cloud_Analyst",
"dataSpaceName": "default",
"objectApiNames": ["Account__dlm", "Contact__dlm"]
}'
步骤 3 — 验证:
sf org api rest --target-org <alias> \
--path "/services/data/v${API_VERSION}/ssot/data-governance/object-access-grants?permissionSetName=Data_Cloud_Analyst&dataSpaceName=default"
规则与限制
| 规则 | 原因 |
|---|---|
使用 <dataspaceScopes>(复数)作为父级,使用 <dataspaceScope>(单数)作为子级 | XML 架构要求;使用其他名称会导致部署失败 |
dataAccessLevel 仅可使用以下值:NONE、CONTROLLED_BY_PARENT、ALL | 其他值(例如 OWNER、ViewAllRows)会被拒绝 |
objectAccessLevel 仅可使用以下值:BY_POLICY、ALL_IN_DATASPACE | 其他值(例如 READ、EDIT、Read)会被拒绝。ALL_IN_DATASPACE 要求 dataAccessLevel=CONTROLLED_BY_PARENT |
存在数据治理策略时,优先使用 BY_POLICY | 将行/列筛选委托给中央策略,无需针对每个对象授予权限 |
每个 DataSpace 使用一个 <dataspaceScopes> 块 | 同一权限集包含多个 DataSpace 时,重复使用此块 |
部署 <dataspaceScopes> 要求组织已配置 Data Cloud | 在未配置 Data Cloud 的组织中,此元素会被忽略或拒绝 |
不要通过 SOQL 查询 DataspaceScope / DataspaceScopeAccess | 无法查询;请使用案例 D PermissionSet Metadata API 检索来检查现有范围。切勿将 SOQL 用作备用方案。 |
注意事项
| 问题 | 解决方案 |
|---|---|
部署失败,报错 -379999659 | 检查枚举值:dataAccessLevel 必须为 NONE/CONTROLLED_BY_PARENT/ALL;objectAccessLevel 必须为 BY_POLICY/ALL_IN_DATASPACE |
| 权限集已部署,但用户仍无法查询 DataSpace 数据 | 未应用第 2 层:如果 objectAccessLevel != BY_POLICY,对象需要明确授权 |
批量创建对某些对象返回 AlreadyExists | 操作具有幂等性,可以安全重试;响应会显示每个对象的状态 |
| Connect API 对象授权端点返回 404 | 组织未配置 Data Cloud,或者解析出的 API 版本低于最低要求。此端点在 v67.0 中引入;重新运行 sf org display --json,确认组织的 apiVersion 字段为 67.0 或更高,并将该值替换到 endpoint 路径中 |
| 检索到的 PermissionSet XML 显示的元素名称与已部署的不同 | Metadata API 在检索时有时会返回旧名称;始终使用当前名称编写 |