platform-dataspace-access-configure

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

platform-dataspace-access-configure

platform-dataspace-access-configure

Configure DataSpace access in Salesforce Data Cloud using a two-layer model:
  1. DataSpace-level access — grant a
    PermissionSet
    access to a DataSpace by embedding a
    <dataspaceScopes>
    element in the permission set XML and deploying via MDAPI.
  2. Object-level access (optional) — grant that permission set access to specific DMO / DLO / CIO objects within the DataSpace using the Object Access Grants Connect API.
The MDAPI layer is required to establish the PermissionSet → DataSpace linkage. The Connect API layer is optional and only needed when access should be scoped to specific objects rather than governed entirely by data governance policies.

采用双层模型配置Salesforce Data Cloud中的DataSpace访问权限:
  1. DataSpace级访问权限 — 通过在权限集XML中嵌入
    <dataspaceScopes>
    元素并通过MDAPI部署,为
    PermissionSet
    授予DataSpace的访问权限。
  2. 对象级访问权限(可选) — 通过Object Access Grants Connect API,为该权限集授予DataSpace内特定DMO/DLO/CIO对象的访问权限。
MDAPI层是建立PermissionSet与DataSpace关联的必需环节。Connect API层为可选,仅当访问权限需要限定到特定对象,而非完全由数据治理策略管控时才需要使用。

Decide the Case First

先确定场景

Pick exactly one case from the table below before writing any files. Each case has a different output shape.
CaseUser intentPermission set stateFiles to emit
A. Create new permset with DS access"create a permission set called X with dataspace scope Y"does NOT exist yet
permissionsets/<Name>.permissionset-meta.xml
and
package.xml
B. Add DS access to existing permset"grant existing permission set X access to dataspace Y"already deployed (may contain other permissions)patched
permissionsets/<Name>.permissionset-meta.xml
and
package.xml
— see Case B workflow below
C. Object-level grant only"grant permset X access to object Z (in dataspace Y)" — permset + scope already configuredalready deployed with
dataspaceScopes
api-request.json
(Connect API body). NO permission set XML, NO
package.xml
Only emit the files listed for the case you picked. Emitting Case A/B files for a Case C prompt (or vice versa) is a correctness failure — extra files change the deployment shape.
Case B — critical: PermissionSet MDAPI deploy is a full metadata replace. Every
<objectPermissions>
,
<fieldPermissions>
,
<userPermissions>
,
<tabSettings>
,
<applicationVisibilities>
,
<recordTypeVisibilities>
,
<customPermissions>
,
<pageAccesses>
,
<classAccesses>
,
<customMetadataTypeAccesses>
,
<customSettingAccesses>
,
<externalDataSourceAccesses>
element you omit from the redeploy is deleted from the org. Before adding
<dataspaceScopes>
to an existing permset, retrieve the current XML and patch it — do not hand-author from scratch.
在编写任何文件之前,请从下表中选择恰好一个场景。每个场景的输出形式不同。
场景用户意图权限集状态需生成的文件
A. 创建包含DataSpace访问权限的新权限集"创建名为X的权限集,使其拥有DataSpace范围Y的访问权限"尚未存在
permissionsets/<Name>.permissionset-meta.xml
package.xml
B. 为现有权限集添加DataSpace访问权限"为现有权限集X授予DataSpace Y的访问权限"已部署(可能包含其他权限)已修改的
permissionsets/<Name>.permissionset-meta.xml
package.xml
— 请参阅下方场景B工作流
C. 仅授予对象级访问权限"为权限集X授予DataSpace Y中对象Z的访问权限" — 权限集和范围已配置完成已部署且包含
dataspaceScopes
api-request.json
(Connect API请求体)。无需权限集XML,无需
package.xml
仅生成所选场景对应的文件。如果针对场景C的请求生成了场景A/B的文件(反之亦然),则视为错误 — 多余的文件会改变部署形态。
场景B — 关键提示: PermissionSet的MDAPI部署是全元数据替换。重新部署时,所有未包含在XML中的
<objectPermissions>
<fieldPermissions>
<userPermissions>
<tabSettings>
<applicationVisibilities>
<recordTypeVisibilities>
<customPermissions>
<pageAccesses>
<classAccesses>
<customMetadataTypeAccesses>
<customSettingAccesses>
<externalDataSourceAccesses>
元素都会从组织中删除。在为现有权限集添加
<dataspaceScopes>
之前,请先检索当前的XML并进行修改 — 不要从头手动编写。

Case B workflow

场景B工作流

  1. Retrieve the existing permission set:
    bash
    sf project retrieve start --metadata PermissionSet:<Name> --target-org <alias>
  2. Open the retrieved
    permissionsets/<Name>.permissionset-meta.xml
    . Keep every element already there.
  3. Insert the
    <dataspaceScopes>
    block for the target DataSpace (element order in the file does not matter for MDAPI). If the file already has a
    <dataspaceScopes>
    block for this same DataSpace, replace only that block. Leave every
    <dataspaceScopes>
    block for other DataSpaces untouched — one block per DataSpace, and removing a block revokes that DataSpace grant.
  4. Write
    package.xml
    listing the permset in
    <members>
    .
  5. Redeploy with
    sf project deploy start
    .

  1. 检索现有权限集:
    bash
    sf project retrieve start --metadata PermissionSet:<Name> --target-org <alias>
  2. 打开检索到的
    permissionsets/<Name>.permissionset-meta.xml
    ,保留其中所有已有的元素。
  3. 为目标DataSpace插入
    <dataspaceScopes>
    块(文件中的元素顺序对MDAPI无影响)。如果文件中已有针对同一DataSpace
    <dataspaceScopes>
    块,则仅替换该块。保留针对其他DataSpace的
    <dataspaceScopes>
    块 — 每个DataSpace对应一个块,删除块会撤销对该DataSpace的授权。
  4. 编写
    package.xml
    ,在
    <members>
    中列出该权限集。
  5. 使用
    sf project deploy start
    重新部署。

When This Skill Owns the Task

此技能的适用场景

Trigger this skill when the user wants to:
  • Create a permission set that grants access to a Data Cloud DataSpace
  • Add or modify
    dataspaceScopes
    on an existing permission set
  • Grant a permission set access to specific DMO / DLO / CIO objects in a DataSpace
  • Configure
    dataAccessLevel
    and
    objectAccessLevel
    for a DataSpace scope
  • List or remove object access grants for a permission set + DataSpace pair
Delegate elsewhere when:
  • The permission set has no DataSpace access at all →
    platform-permission-set-generate
  • The task is creating the DataSpace itself →
    data360-orchestrate
  • The task is ingesting data or configuring streams →
    data360-prepare

当用户需要以下操作时触发此技能:
  • 创建授予Data Cloud DataSpace访问权限的权限集
  • 为现有权限集添加或修改
    dataspaceScopes
  • 为权限集授予DataSpace内特定DMO/DLO/CIO对象的访问权限
  • 为DataSpace范围配置
    dataAccessLevel
    objectAccessLevel
  • 列出或移除权限集与DataSpace组合的对象访问授权
请将以下任务转交给其他技能:
  • 权限集不包含任何DataSpace访问权限 → 使用
    platform-permission-set-generate
  • 任务是创建DataSpace本身 → 使用
    data360-orchestrate
  • 任务涉及数据 ingestion或流配置 → 使用
    data360-prepare

Layer 1 — DataSpace-Level Access (MDAPI)

第一层 — DataSpace级访问权限(MDAPI)

Embed a
<dataspaceScopes>
element inside the
PermissionSet
XML. Deploy with MDAPI.
xml
<?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>
PermissionSet
XML中嵌入
<dataspaceScopes>
元素,通过MDAPI部署。
xml
<?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>

Element Rules

元素规则

ElementRequiredValid ValuesPurpose
<dataspaceScopes>
yesparent element (plural)Container for a single dataspace scope grant
<dataspaceScope>
yesDataSpace API name (e.g.
default
)
Which DataSpace this grant is for
<dataAccessLevel>
yes
NONE
,
CONTROLLED_BY_PARENT
,
ALL
Row-level data access within the DataSpace
<objectAccessLevel>
yes
BY_POLICY
,
ALL_IN_DATASPACE
Object-level access.
BY_POLICY
defers to data governance policies.
ALL_IN_DATASPACE
is only allowed when
dataAccessLevel
is
CONTROLLED_BY_PARENT
元素是否必需有效值用途
<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

Common Mistakes

常见错误

  • Wrong parent name — using
    <dataspaceScopeAccess>
    instead of
    <dataspaceScopes>
    . Deployment fails silently or with cryptic errors.
  • Wrong child name — using
    <dataspaceScopeName>
    instead of
    <dataspaceScope>
    .
  • Wrong enum values
    ViewAllRows
    /
    Read
    /
    OWNER
    /
    EDIT
    are not valid. Use
    NONE
    ,
    CONTROLLED_BY_PARENT
    , or
    ALL
    for
    dataAccessLevel
    ; use
    BY_POLICY
    or
    ALL_IN_DATASPACE
    for
    objectAccessLevel
    . See Element Rules table for allowed combinations. Deployment error
    -379999659
    means invalid enum.
  • Multiple scopes in one element
    <dataspaceScopes>
    grants access to exactly one DataSpace. To grant access to multiple, add multiple
    <dataspaceScopes>
    blocks.
  • 父元素名称错误 — 使用
    <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>
    块。

Package Layout (Case A and Case B)

包结构(场景A和场景B)

A deployable bundle for Layer 1 always contains both files:
text
<output-root>/
  package.xml
  permissionsets/<Name>.permissionset-meta.xml
package.xml
(required — list every permission set being deployed in
<members>
):
xml
<?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>
Deploy:
bash
sf project deploy start --source-dir force-app/main/default/permissionsets/ --target-org <alias>

第一层的可部署包始终包含两个文件:
text
<output-root>/
  package.xml
  permissionsets/<Name>.permissionset-meta.xml
package.xml
(必需 — 在
<members>
中列出所有待部署的权限集):
xml
<?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>
部署命令:
bash
sf project deploy start --source-dir force-app/main/default/permissionsets/ --target-org <alias>

Layer 2 — Object-Level Access (Connect API) — Case C

第二层 — 对象级访问权限(Connect API)— 场景C

Only needed when
objectAccessLevel
is not
BY_POLICY
, or when governance policies do not cover the target objects. Grants are runtime — no MDAPI deploy, no
package.xml
, no permission set XML
. The only artifact for a Case C task is a single
api-request.json
describing the Connect API call.
仅当
objectAccessLevel
不为
BY_POLICY
,或治理策略未覆盖目标对象时才需要使用此层。授权为运行时操作 — 无需MDAPI部署、无需
package.xml
、无需权限集XML
。场景C任务的唯一产物是描述Connect API调用的单个
api-request.json
文件。

Resolve the API version first

先确定API版本

Every Connect API
endpoint
in this layer contains an
/services/data/v<apiVersion>/…
segment. Do not hardcode
v67.0
.
Resolve the target org's actual API version before writing the envelope so the request matches the org's supported surface:
bash
sf org display --target-org <alias> --json | jq -r '.result.apiVersion'
  • Substitute the returned value (e.g.
    67.0
    ,
    68.0
    ) into the
    endpoint
    as
    v<apiVersion>
    .
  • If the org can't be queried (offline authoring, no alias yet), fall back to the
    minApiVersion
    from this skill's frontmatter (
    67.0
    ) — the endpoint was introduced there and any newer version accepts the same body.
  • If the user explicitly specifies a version in the prompt, use that verbatim.
In the templates below,
{apiVersion}
is a placeholder. Replace it with the resolved API version (e.g.,
67.0
,
68.0
) before emitting
api-request.json
.
此层中每个Connect API的
endpoint
都包含
/services/data/v<apiVersion>/…
段。请勿硬编码
v67.0
。在编写请求包之前,请先确定目标组织的实际API版本,确保请求与组织支持的接口匹配:
bash
sf org display --target-org <alias> --json | jq -r '.result.apiVersion'
  • 将返回值(例如
    67.0
    68.0
    )替换为
    endpoint
    中的
    v<apiVersion>
  • 如果无法查询组织(离线编写、尚未设置别名),则回退到此技能前置信息中的
    minApiVersion
    67.0
    ) — 该端点在此版本引入,所有更高版本均接受相同的请求体。
  • 如果用户在请求中明确指定了版本,请直接使用该版本。
在以下模板中,
{apiVersion}
是占位符。在生成
api-request.json
之前,请将其替换为确定的API版本(例如
67.0
68.0
)。

api-request.json
— canonical shape

api-request.json
— 标准格式

Emit the request as a self-describing envelope with
method
,
endpoint
,
headers
,
body
, and
expectedResponse
. Do NOT emit only the body — reviewers and downstream tooling read the envelope.
json
{
  "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"
    }
  }
}
将请求生成为包含
method
endpoint
headers
body
expectedResponse
的自描述包。请勿仅生成请求体 — 审核人员和下游工具需要读取完整包。
json
{
  "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"
    }
  }
}

Bulk Grant

批量授权

Same
api-request.json
envelope shape.
endpoint
gains the
/actions/bulk-create
suffix,
body.objectApiName
is replaced by the list-valued
body.objectApiNames
, and
expectedResponse
omits the
body
field because bulk responses return per-object status entries rather than the flat request payload (see Gotchas below).
json
{
  "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
  }
}
使用相同的
api-request.json
包格式。
endpoint
添加
/actions/bulk-create
后缀,
body.objectApiName
替换为数组类型的
body.objectApiNames
expectedResponse
省略
body
字段,因为批量响应会返回每个对象的状态条目,而非扁平的请求负载(请参阅下方注意事项)。
json
{
  "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
  }
}

List Grants

列出授权

Same envelope shape with
method: "GET"
, query parameters on the
endpoint
, and no
body
.
json
{
  "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
设为
GET
endpoint
添加查询参数,无需
body
json
{
  "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
  }
}

Revoke Grant

撤销授权

Same envelope shape with
method: "DELETE"
, the object API name as a path segment, and
expectedResponse.status: 204
(No Content).
json
{
  "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
  }
}
使用相同的包格式,
method
设为
DELETE
,对象API名称作为路径段,
expectedResponse.status
设为
204
(无内容)。
json
{
  "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
  }
}

Object Types

对象类型

  • DMO (Data Model Object) — unified profile objects, suffix
    __dlm
  • DLO (Data Lake Object) — raw ingested data, suffix
    __dll
  • CIO (Calculated Insight Object) — computed metrics, suffix
    __cio

  • DMO(Data Model Object)— 统一档案对象,后缀为
    __dlm
  • DLO(Data Lake Object)— 原始导入数据,后缀为
    __dll
  • CIO(Calculated Insight Object)— 计算指标对象,后缀为
    __cio

Combined Setup — Case A + Case C from a Cold Start

组合配置 — 从无到有实现场景A + 场景C

Use this section ONLY when the user is starting from nothing and asks for both the permset+scope AND per-object grants in a single request. If the user's prompt is only about the Connect API grant (Case C) — for example "grant Account__dlm access; the permset and dataspace scope already exist" — SKIP this section entirely and emit only
api-request.json
from Layer 2.
The commands below are operator-facing
sf
CLI invocations (a runnable cold-start walkthrough), NOT the artifact you emit. For a normal Case C task the artifact is a single
api-request.json
envelope as documented in Layer 2 above.
Goal: Grant
Data_Cloud_Analyst
permission set access to
Account__dlm
and
Contact__dlm
in the
default
DataSpace.
Step 1 — Deploy PermissionSet with DataSpace scope (MDAPI):
xml
<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>
bash
sf project deploy start --source-dir permissionsets/ --target-org <alias>
Step 2 — Grant object access (Connect API): (Required here because the
default
DataSpace has no governance policies covering
Account__dlm
and
Contact__dlm
. Skip Step 2 when
BY_POLICY
policies already govern the target objects — Layer 1 alone is sufficient.)
Resolve the org's API version first (see Resolve the API version first above), then substitute it into the
--path
value:
bash
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"]
  }'
Step 3 — Verify:
bash
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"

仅当用户从零开始,且请求同时包含权限集+范围配置和对象级授权时,才使用本节内容。如果用户的请求仅涉及Connect API授权(场景C) — 例如“授予Account__dlm访问权限;权限集和DataSpace范围已存在” — 请完全跳过本节,仅生成第二层中的
api-request.json
以下命令是面向操作人员的
sf
CLI调用(可运行的从零开始操作指南),并非需要生成的产物。对于普通场景C任务,产物仅为第二层中记录的单个
api-request.json
包。
目标:
Data_Cloud_Analyst
权限集授予
default
DataSpace中
Account__dlm
Contact__dlm
的访问权限。
步骤1 — 部署包含DataSpace范围的PermissionSet(MDAPI):
xml
<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>
bash
sf project deploy start --source-dir permissionsets/ --target-org <alias>
步骤2 — 授予对象访问权限(Connect API): (此处需要执行此步骤,因为
default
DataSpace没有覆盖
Account__dlm
Contact__dlm
的治理策略。如果
BY_POLICY
策略已覆盖目标对象,请跳过步骤2 — 仅第一层配置即可满足需求。)
先确定组织的API版本(请参阅上方的先确定API版本),然后将其替换到
--path
参数中:
bash
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 — 验证:
bash
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"

Rules and Constraints

规则与约束

RuleReason
Use
<dataspaceScopes>
(plural) as parent,
<dataspaceScope>
(singular) as child
XML schema requirement; other names deploy-fail
dataAccessLevel
values:
NONE
,
CONTROLLED_BY_PARENT
,
ALL
only
Other values (e.g.
OWNER
,
ViewAllRows
) are rejected
objectAccessLevel
values:
BY_POLICY
,
ALL_IN_DATASPACE
only
Other values (e.g.
READ
,
EDIT
,
Read
) are rejected.
ALL_IN_DATASPACE
requires
dataAccessLevel=CONTROLLED_BY_PARENT
Prefer
BY_POLICY
when data governance policies exist
Delegates row/column filtering to central policy — no per-object grants needed
One
<dataspaceScopes>
block per DataSpace
Repeat the block for multiple DataSpaces on the same permission set
Org must have Data Cloud provisioned to deploy
<dataspaceScopes>
On non-Data-Cloud orgs, the element is ignored or rejected
Do not query
DataspaceScope
/
DataspaceScopeAccess
via SOQL
Not queryable; use MDAPI retrieve to inspect existing grants

规则原因
使用
<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,请重复添加该块
组织必须已启用Data Cloud才能部署
<dataspaceScopes>
在未启用Data Cloud的组织中,该元素会被忽略或拒绝
请勿通过SOQL查询
DataspaceScope
/
DataspaceScopeAccess
这些对象不可查询;请使用MDAPI检索来查看现有授权

Gotchas

注意事项

IssueResolution
Deployment fails with error
-379999659
Check enum values —
dataAccessLevel
must be
NONE
/
CONTROLLED_BY_PARENT
/
ALL
;
objectAccessLevel
must be
BY_POLICY
/
ALL_IN_DATASPACE
Permission set deploys but users still can't query DataSpace dataLayer 2 not applied — objects need explicit grants if
objectAccessLevel != BY_POLICY
Bulk-create returns
AlreadyExists
for some objects
Idempotent — safe to retry; response shows per-object status
Connect API returns 404 for object grants endpointOrg lacks Data Cloud provisioning, or the resolved API version is below the minimum. The endpoint was introduced in
v67.0
— re-run
sf org display --json
to confirm the org's
apiVersion
field is
67.0
or later, and substitute that value into the
endpoint
path
Retrieved PermissionSet XML shows different element names than deployedMetadata API sometimes echoes legacy names on retrieve — always author with current names
问题解决方案
部署失败并返回错误
-379999659
检查枚举值 —
dataAccessLevel
必须为
NONE
/
CONTROLLED_BY_PARENT
/
ALL
objectAccessLevel
必须为
BY_POLICY
/
ALL_IN_DATASPACE
权限集部署成功,但用户仍无法查询DataSpace数据未应用第二层配置 — 如果
objectAccessLevel != BY_POLICY
,则对象需要显式授权
批量创建返回部分对象的
AlreadyExists
状态
操作具有幂等性 — 可安全重试;响应会显示每个对象的状态
Connect API返回404错误(对象授权端点不存在)组织未启用Data Cloud,或确定的API版本低于最低要求。该端点在
v67.0
引入 — 重新运行
sf org display --json
确认组织的
apiVersion
字段为
67.0
或更高,并将该值替换到
endpoint
路径中
检索到的PermissionSet XML显示的元素名称与部署时不同Metadata API有时会在检索时返回旧名称 — 编写时请始终使用当前名称