关于 platform-policy-rule-generate
面向 Salesforce 开发者的元数据编写技能,用于创建 PolicyRuleDefinition 和 PolicyRuleDefinitionSet XML 文件。内容涵盖架构选择、验证约束,以及与 Data Governance Policy Builder UI 的兼容性。
主要功能
- 01编写策略规则 XML 元数据
- 02选择类别、效果与作用范围
- 03定义 WHEN 和 UNLESS 条件
- 04检查架构与部署约束
- 05核对 Policy Builder UI 兼容性
适用场景
- 01创建可部署的策略规则包
- 02设置访问或治理条件
- 03部署前审查 XML
- 04准备可由 UI 编辑的规则
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-policy-rule-generate安装后在 Claude Code 中输入/platform-policy-rule-generate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/deploy-errors.mdpolicy-schema-full.mdtemplates-access.mdtemplates-advanced.mdtemplates-record.mdtemplates-transform.mdtemplates.mdui-compatibility.md详细介绍
编写策略规则定义
**门控要求:**需要 EnforceOMatic 和 PolicyRuleMDAPI 组织权限。
**最低 API 版本:**64.0(使用 PolicyJsonExpression 的条件要求 66.0)。
本技能介绍用于编写策略的磁盘元数据 XML 格式。只要任务要求编写 *.policyRuleDefinition 或 *.policyRuleDefinitionSet 文件,或交付包含这些文件的元数据包,就应使用本技能。运行时部分(RuleProvider、钩子)不在范围内。
**评估覆盖范围:**本技能由团队的 ADK 评估框架测试,而非技能目录下的
tests/evals/。涵盖 ACCESS / GOVERNANCE / RECORD / TRANSFORM 变体的五个数据集位于packages/adk-eval/eval/domains/platform-policy-rule-generate/datasets/。
1. 包布局
可部署的包始终包含:
<fixture>/
package.xml
policyRuleDefinitionSets/<setName>.policyRuleDefinitionSet
policyRuleDefinitions/<ruleName>.policyRuleDefinition
package.xml 模板(ftest 使用 <version>[ftest]</version>,真实组织使用 64.0 或更高版本):
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Rule0</members>
<name>PolicyRuleDefinition</name>
</types>
<types>
<members>Set1</members>
<name>PolicyRuleDefinitionSet</name>
</types>
<version>64.0</version>
</Package>
2. PolicyRuleDefinitionSet 架构
<PolicyRuleDefinitionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Set1</label>
<description>Optional free text</description>
<replicated>false</replicated>
<builderCompatible>true</builderCompatible>
</PolicyRuleDefinitionSet>
| 元素 | 必填 | 说明 |
|---|---|---|
<label> | 是 | 主标签。文件基本名(devName)是 MDAPI 标识符,而非标签。 |
<description> | 否 | 自由文本。 |
<replicated> | 否 | true 会触发在配套组织之间转换占位符。若为 null/false,则省略。 |
<builderCompatible> | 否 | true = 规则已根据 §7 检查清单审核。false = 仅限 API。省略 = 未审核。仅供参考,不影响部署/运行时。 |
<builderValidated> | 否 | **由服务端管理。编写的 XML 中绝不可设置。**服务端会在验证时覆盖此值。 |
3. PolicyRuleDefinition — 核心字段
| 元素 | 必填 | 说明 |
|---|---|---|
<label> | 是 | MasterLabel。 |
<category> | 是 | 参见 §4。决定 resourceScopeType,以及是否需要 policyRuleResourceDomains/resourceTransform。除 TRANSFORM 外,不会限制 effect。 |
<effect> | 是 | Permit、Forbid 或 Transform。核心逻辑中唯一强制执行的类别关联:effect=Transform ↔ category=TRANSFORM_POLICY_RULE_DEFINITION(双向)。其他所有类别均可自由接受 Permit 和 Forbid。 |
<action> | 是(≥1) | Read、TupleRead、Create 等。多个元素按 OR 组合。 |
<policyRuleDefinitionSetName> | 是 | 父级集合的开发者名称。 |
<principalScopeType> | 是 | 始终为 ANY。 |
<resourceScopeType> | 是 | ANY、FIELD、RECORD、DATASPACE 或 SPAN。必须与类别匹配(§4)。 |
<principalAuthenticationLevel> | 否 | INTERNAL、AUTHENTICATED、UNIDENTIFIED、IDENTIFIED。 |
<ruleConsumer> | 否 | ALL、DATACLOUD、MULESOFT、TABLEAU、CORE。 |
<policyRuleResourceDomains> | 否 | 仅 RECORD(RLS)和 FIELD 作用域的 TRANSFORM 规则必填。ACCESS/GOVERNANCE 中禁止使用。 |
<resourceTransform> | 否 | 当 category=TRANSFORM 时必填,且仅在此时有效。 |
<whenPolicyRuleDefinitionClauseConjunction> | 否 | WHEN 条件。 |
<unlessPolicyRuleDefinitionClauseConjunction> | 否 | UNLESS 条件。无法通过 UI 编辑,建议使用 WHEN + 否定运算符。 |
4. 类别决策树
类别表示一个领域(规则适用的平台强制执行层)。效果表示操作(允许 / 拒绝 / 转换)。两者彼此独立,TRANSFORM 除外。
平台验证的唯一 Category × Effect 规则:
effect=Transform⇔category=TRANSFORM_POLICY_RULE_DEFINITION(双向;不匹配会抛出INVALIDFORCATEGORY)。- 其他所有类别(
ACCESS、GOVERNANCE、RECORD、IDENTIFIED_RECORD)均接受Permit或Forbid。
**关于平台自动填充默认值的说明:**如果编写的 XML 中省略了
<category>,服务端会根据effect填充值:Permit→ACCESS、Forbid→GOVERNANCE、Transform→TRANSFORM。**这是默认填充,而非验证。**如果显式填写的类别与此默认值矛盾,仍会被接受并按原值持久化。
选择类别
What kind of policy?
│
├── OLS/FLS allow/deny on tagged or classified resources
│ category = ACCESS_POLICY_RULE_DEFINITION (allow/deny attestation in the access plane)
│ | GOVERNANCE_POLICY_RULE_DEFINITION (governance-audited)
│ effect = Permit | Forbid (chosen independently from category)
│ resourceScopeType = ANY | FIELD | DATASPACE
│ NO <policyRuleResourceDomains>
│ condition: resourcePath=TAG|CLASSIFICATION CONTAINS_ANY <ref>
│ For "objects AND all their fields" → action=TupleRead + OR-of-ENTITYTYPE clause (§7)
│ Note: "Block access to Foo object" → tag Foo with <yourTag>, write rule on tag
│ Do NOT use <resourceDomain>Foo</resourceDomain> — forbidden for ACCESS/GOVERNANCE
│
├── Row-level filter on a DMO/DLO
│ category = RECORD_POLICY_RULE_DEFINITION
│ effect = Permit | Forbid
│ resourceScopeType = RECORD
│ <policyRuleResourceDomains> = the DMO/DLO API name ← entity targeting allowed here
│
├── Identified-Guest record access
│ NOT authorable via MDAPI — SESSION_CONSUMER_ID is not in RuleContextPathType
│ Must be implemented as a runtime RuleProvider.
│
└── Field masking
category = TRANSFORM_POLICY_RULE_DEFINITION ← required by RuleBuilder validator
effect = Transform ← required by RuleBuilder validator
resourceScopeType = FIELD (structured) or SPAN (unstructured)
<policyRuleResourceDomains> = the DMO whose field is masked
<resourceTransform> required (e.g. NULL_RESOURCE_TRANSFORM, LAST_N_CHARS_RESOURCE_TRANSFORM)
ACCESS 与 GOVERNANCE——如何选择
两者在法律层面都接受 Permit 和 Forbid。请根据应由哪个执行层记录/审计规则以及提示词的字面要求进行选择:
| 用例 | 选择 | 原因 |
|---|---|---|
| 提示词明确提到“ACCESS policy rule”/“access rule”/“OLS/FLS” | ACCESS_POLICY_RULE_DEFINITION | 与提示词的用词一致;位于数据访问执行层。 |
| 提示词提到“governance”/“audit”/“policy framework”/数据驻留或合规相关内容 | GOVERNANCE_POLICY_RULE_DEFINITION | 与提示词的用词一致;规则会显示在治理报告中。 |
| 提示词含糊不清,只描述允许/拒绝语义 | Permit 默认选 ACCESS,Forbid 默认选 GOVERNANCE(与平台的自动填充默认值一致;安全且可部署,但并非必需) |
**重要——遵循提示词中明确指定的类别。**如果提示词写的是“ACCESS policy rule that denies …”或“GOVERNANCE policy rule that permits …”,就准确输出对应类别。不要仅仅因为效果是 Forbid(或 Permit),就悄悄改用自动填充默认类别。平台两者都接受。Agent 不得擅自更改用户明确表达的意图。
范围 × 类别兼容性——矩阵之外的任意组合都会抛出 INVALIDFORCATEGORY:
ACCESS | GOVERNANCE | TRANSFORM | RECORD | |
|---|---|---|---|---|
ANY | 是 | 是 | 否 | 否 |
DATASPACE | 是 | 是 | 否 | 否 |
FIELD | 是 | 是 | 是 | 否 |
RECORD | 否 | 否 | 否 | 是 |
SPAN | 否 | 否 | 是 | 否 |
5. 条件模式(快速参考)
每个 <conditions> 块都需要以下全部四项:<clause>、<operator>、一个路径元素,以及值。
| 目标 | 路径元素 | 运算符 | 值 |
|---|---|---|---|
| 资源具有标签 | <resourcePath>TAG</resourcePath> | CONTAINS_ANY | <valueReferenceType>CUSTOM_TAG | STANDARD_TAG</valueReferenceType> |
| 资源具有分类 | <resourcePath>CLASSIFICATION</resourcePath> | CONTAINS_ANY | CUSTOM_CLASSIFICATION | STANDARD_CLASSIFICATION |
| 主体具有权限 | <principalPath>ASSIGNED_PERMISSIONS_PATH</principalPath> | CONTAINS_ANY | CONTAINS_NONE | <valueReferenceType>CUSTOM_PERMISSION</valueReferenceType> |
| 会话位于数据空间中 | <contextPath>SESSION_DATASPACE</contextPath> | CONTAINS_ANY | <valueReferenceType>DATASPACE</valueReferenceType> |
| 记录字段 = 用户属性 | <resourcePath>RECORDFIELD</resourcePath> + <valueDomain>Schema:field</valueDomain> | EQUALS | <valuePrincipalPath>USER_ID | ORGANIZATION_ID | USER_ROLE_ID</valuePrincipalPath> |
| 实体类型检查 | <resourcePath>ENTITYTYPE</resourcePath> | IS | <valueString>{"t":"Text","v":"FIELD"}</valueString> |
<conjunctionExpression> 使用从 1 开始索引的前缀表示法:1、(AND 1 2)、(OR 1 2)、(AND (OR 1 2) (AND 3))。像 1 这样的顶层单独索引可用于部署,但会导致 Data Governance Policy Builder UI 崩溃——如果需要在 UI 中编辑,请参见 §7。
完整路径枚举(RulePrincipalPathType、RuleResourcePathType、RuleContextPathType)、运算符和 JSON 表达式(PROJECTION / ARGLIST / SOQLTARGETLISTEXPR),请参见 references/policy-schema-full.md。
所有策略变体的可复制粘贴模板,请参见 references/templates.md。
6. 验证防护规则
- 每个
<conditions>都必须包含一个<operator>。缺少运算符 → 拒绝。 - 每个
<conditions>都必须至少包含一个路径元素(<resourcePath>、<principalPath>、<contextPath>或<valueDomain>)。 <contextPath>仅用于SESSION_DATASPACE。切勿在其中放置资源路径值。- 范围 × 类别必须符合 §4 中的矩阵。常见违规组合:ACCESS/GOVERNANCE + RECORD 范围;RECORD + ANY/FIELD 范围;TRANSFORM + ANY/RECORD 范围。(除 TRANSFORM 外,类别与效果无关 — 参见 §4。)
<resourceTransform>与effect=Transform必须配套。Transform 效果需要<resourceTransform>。Permit/Forbid 不得包含此元素。- RECORD(RLS)和 FIELD 范围的 TRANSFORM 必须包含
<policyRuleResourceDomains>;ACCESS/GOVERNANCE 不得包含此元素。 <conjunctionExpression>的索引必须与实际的<conditions>数量一致。索引偏差 → 拒绝。<conditions>内的<clause>必须与外层包装元素匹配(<when…>中使用WHEN,<unless…>中使用UNLESS)。<valueString>中的 JSON 字面量必须将"转义为"。转义错误会导致字面量静默损坏。- 部署时,引用目标(
<valueReference>、<resourceDomain>)必须存在于目标组织中。 SCALAR_ATTRIBUTE/PLURAL_ATTRIBUTE不属于RulePrincipalPathType,也不在 MDAPI 契约中。对于这些形态,请使用运行时 RuleProvider。IDENTIFIED_RECORD无法通过 MDAPI 编写 —SESSION_CONSUMER_ID不属于RuleContextPathType。- 标准标签/分类开发人员名称是完全限定的点分路径(例如
DataGovernanceTags.ExternalData.Visibility.Public)。编写规则前,请先检索一条现有规则以获取准确字符串。 - 最低 API 版本:
PolicyRuleDefinition= 64.0;PolicyJsonExpressionconditions = 66.0;<replicated>= 260+;<builderCompatible>/<builderValidated>= 262+。
关于
<conjunctionExpression>形态的说明: 顶层索引可以是裸值(例如<conjunctionExpression>1</conjunctionExpression>),且可顺利部署 — 服务端解析器接受顶层的裸标记。这不会导致部署时验证错误。但它会导致 Data Governance Policy Builder UI 在加载时崩溃 — 参见 §7。
7. UI 兼容性——核心规则
Data Governance Policy Builder 会编辑 MDAPI 的一个严格子集。默认目标:生成与 UI 兼容的策略。生成仅适用于 API 的 XML 前,务必先与操作员确认。
硬性阻碍——以下任一情况都会使策略无法编辑(其中几种还会导致构建器加载时崩溃):
- ACCESS/GOVERNANCE 规则缺少 OR-of-ENTITYTYPE 子句 → 导致硬性崩溃:
Cannot use 'in' operator to search for 'Permit' in undefined。即使与TupleRead搭配使用(此时在运行时功能上是冗余的),也必须包含IS条件,值为{"t":"Text","v":"OBJECT"}和{"t":"Text","v":"FIELD"}。 <conjunctionExpression>中出现裸的顶层条件索引(例如1或(AND (OR 1 2) 3))→ 构建器加载时在buildCriteria中崩溃。部署不受影响,但该策略无法在 UI 中编辑。务必用括号包裹:单个条件使用(AND 1);使用(AND (OR 1 2) (AND 3)),而不是(AND (OR 1 2) 3)。category = ACCESS_POLICY_RULE_DEFINITION+effect = Forbid→ Data Governance Policy Builder UI(而非 MDAPI)会在保存时将其折叠为 GOVERNANCE;经由构建器往返转换会重写类别。MDAPI 部署不受影响——原始的 ACCESS+Forbid 组合有效,且部署时不会被修改。如果目标是支持 UI 往返转换,Forbid 优先使用 GOVERNANCE;如果 MDAPI 是事实来源,则 ACCESS+Forbid 没问题。- 任何
<unlessPolicyRuleDefinitionClauseConjunction>块 → 首次通过 UI 保存时会被静默丢弃。 - 存在多个
<action>→ 只保留第一个。 ruleConsumer≠DATACLOUD→ UI 保存时会将其硬编码为 DATACLOUD。- 顶层
(OR 1 2)合取式 → 触发// ERROR: Unsupported rule!路径,规则会被静默丢弃。
兼容 UI 的 “unless” 重写方式:
| 作者意图 | 兼容 UI 的形式 |
|---|---|
unless principal has permission X | WHEN ASSIGNED_PERMISSIONS_PATH CONTAINS_NONE X |
unless resource has tag X | WHEN TAG CONTAINS_NONE X |
unless record field = value | WHEN RECORDFIELD NOT_EQUALS value |
完整的 UI 兼容性检查清单、往返转换规则和运算符支持矩阵,请参阅 references/ui-compatibility.md。
8. 编写工作流
- 从最接近的模板开始,参见
references/templates.md——从模板修改,不要从空白开始。 - 先选择类别(§4)。类别决定 effect、resourceScopeType,以及是否需要 policyRuleResourceDomains/resourceTransform。
- 先搭建基本规则:仅包含顶层字段,不含条件。匹配
references/templates.md中的类别模板。 - 逐个添加条件,每个条件都包含全部四个锚点:
<clause>、<operator>、一个路径元素和值。 - 更新
<conjunctionExpression>——使用从 1 开始索引的前缀表示法。仅使用顶层索引(例如1)可以部署,但会导致 UI 无法正常工作;如果需要在 UI 中编辑,请将其包装为(AND 1)(§7)。 - 运行 UI 兼容性检查(§7 /
references/ui-compatibility.md)。如果有任何项目触发问题,先尝试使用“unless”改写;如果无法改写,请在继续前取得操作员的明确确认。 - 更新
package.xml——为两种类型分别列出每个<members>。 - 如果通过 §7 检查清单,则将集合上的
<builderCompatible>设为true;如果有意仅供 API 使用,则设为false。 - 在认为完成前,根据 §6(防护措施)进行合理性检查。
- 对持久组织进行任何非试运行部署前,先使用试运行进行验证。根据
references/deploy-errors.md中的错误参考呈现错误。
完成前进行三层正确性检查:
- 运行时强制执行——规则是否按预期执行?(操作选择、条件结构)
- MDAPI 部署有效性——是否可以部署?(§6 防护措施、范围×类别、标签开发者名称、组织权限)
- UI 可编辑性——构建器能否渲染并重新保存?(§7 检查清单、OR-of-ENTITYTYPE 要求)
9. 输出规范——Agent 不得对用户说的内容
Agent 面向用户的聊天回复会与每个生成的文件一同提供。客户不应看到内部引擎或实现细节。
- 不得在面向用户的文本中提及内部评估引擎——包括但不限于
Cedar、policy engine、AuthZ engine、evaluation engine、Rego、OPA或类似名称。面向客户的界面是 Data Governance、Policy Builder、Data Cloud Governance——只能使用这些术语。 - 不得在结尾添加“运行时工作原理”说明,描述评估流程、主体与资源的匹配语义或引擎内部的条件顺序。生成的文件就是交付内容;用一句话概述部署的内容即可。如果用户明确询问强制执行的工作原理,请使用产品术语进行说明(例如,“Data Governance 会在……时拒绝读取”),绝不要使用引擎术语。
- 不得在面向用户的文本中提及内部软件包、源目录、Java 类名、方法名或行号引用。内部实现标识符不是面向客户的内容;只能使用产品术语描述平台行为(“服务器会验证……”、“Data Governance 会拒绝……”)。
- 除非用户询问,否则不要解释自动填充/默认填充/回退语义。交付规则;只有在约束会影响用户接下来必须执行的操作时才说明(例如,“部署前必须存在 DMO 标签”)。
如果用户需要更多背景信息,他们会主动询问——届时再使用产品语言作答。
参考文档
| 详情 | 文件 |
|---|---|
| 完整的路径枚举、运算符、值集、JSON 表达式(PROJECTION / ARGLIST / SOQLTARGETLISTEXPR) | references/policy-schema-full.md |
可复制粘贴的模板——索引见 references/templates.md;各变体模板:templates-access.md、templates-record.md、templates-transform.md、templates-advanced.md | |
| 完整的 UI 兼容性清单、往返规则、运算符 / 路径支持矩阵 | references/ui-compatibility.md |