mcpField
S
service-itsm-agentic-setup-itsm-agentforce-permset-assign

service-itsm-agentic-setup-itsm-agentforce-permset-assign

github.com/forcedotcom安全1.1k1.2k 次安装1 天前更新
代码仓库

关于 service-itsm-agentic-setup-itsm-agentforce-permset-assign

该 skill 通过 Salesforce CLI 为目标用户分配 ITSM Fulfiller 角色权限集及所需许可证,并验证提示模板操作是否可用。若组织未配置相关角色权限集,则转交 AddOn 配置检查。

主要功能

  1. 01检测三类 Fulfiller 权限集
  2. 02检查并分配许可证与权限集
  3. 03支持运行用户或指定用户
  4. 04验证提示模板操作是否可用
  5. 05未配置时转交 AddOn 检查

适用场景

  1. 01为 Fulfiller Agent 配置提示模板操作访问权限
  2. 02检查分配状态并避免重复写入
  3. 03确认组织是否需要先启用 ITSM AddOn

MCP 相关

该 skill 使用 Salesforce CLI(sf)执行操作,不使用 MCP。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill service-itsm-agentic-setup-itsm-agentforce-permset-assign

安装后在 Claude Code 中输入/service-itsm-agentic-setup-itsm-agentforce-permset-assign确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
cli-invocation.md
helper-contracts.md
permset-topology.md
scripts/
classify-action-surface.mjs
classify-assignment-state.mjs
classify-permset-availability.mjs
resolve-target-user.mjs

详细介绍

分配 ITSM 执行者角色权限集(提示词模板访问权限)

为当前运行用户授予 Core 随附的某个执行者角色权限集,使其能够在目标组织上使用 svc_itsm_intelligence__* 提示词模板可调用操作——执行者 NGA Agent 脚本会通过 source: / target: generatePromptResponse://... 引用这些操作。如果当前运行用户无法通过 /services/data/v67.0/actions/custom/generatePromptResponse 获取这些可调用操作,执行者 Agent 配置技能的 Phase 6 activate 调用就会返回 HTTP 200,但响应正文会静默包含 {success:false, messages:[{... "does not exist"}]},导致 Agent 无法使用。此技能会通过分配正确的执行者角色权限集(以及在存在时分配其关联许可证)来弥补这一缺口;如果组织上完全未配置执行者角色权限集,则转交给 Agentforce Studio 配置/验证技能,以便先启用 ITSM AddOn(s)。

三个执行者角色权限集、对应的 AddOn、PSL 及其授予的 userPerms 记录在 references/permset-topology.md 中。它们均由 Core 随附,命名空间为 force——此功能没有托管软件包命名空间下的权限集。

Employee Agent 不在范围内。 Employee NGA Agent 的访问模型独立存在(基于组织偏好设置和不同的角色层),与这三个角色权限集无关。

每次调用都会通过 Salesforce CLI(sf) 执行:

  • sf api request rest — 经过身份验证的 Connect API GET 请求(身份信息、验证读取权限)。
  • sf data query — 对 PermissionSet 执行 SOQL 查询(检查角色是否存在),对 PermissionSetAssignment / PermissionSetLicenseAssign 执行查询(确保操作幂等)。
  • sf org assign permset — 为当前运行用户分配权限集。
  • 从不提取令牌;不使用 MCP。

范围

  • 范围内:检测组织上配置了三个执行者角色权限集(IncidentFulfiller、ProblemFulfillerPermSet、ChangeRequestFulfillerPermSet)中的哪些;让用户选择要分配的角色;检查现有分配;为当前运行用户(或指定用户)分配权限集许可证(角色受许可证限制时)和权限集;通过后续读取 /actions/custom/generatePromptResponse 验证目标 svc_itsm_intelligence__* 可调用操作是否已显示。
  • 范围外:Employee Agent 访问权限(访问模型不同,使用不同技能);安装/启用 ITSM AddOn(s) 或内容捆绑包(转交给 service-itsm-agentic-setup-agentforce-studio-validate);启用组织级 Agentforce 功能开关;创建权限集;创建或激活执行者 Agent(由 service-itsm-agentic-setup-fulfiller-agent-configure 负责);CMDB 访问权限(service-itsm-agentic-setup-cmdb-access-assign);通用的非 ITSM 权限集分配(dx-org-permission-set-assign)。

机制

首先执行只读检测步骤,然后按结果进入以下两个分支:

  • 分支 A — 组织上存在一个或多个执行者角色权限集。 询问用户要分配哪个角色(不要自动选择——执行者通常只需要一个角色)。幂等分配:如果角色受许可证限制,先分配 PSL,再分配权限集;通过回读和后续读取 /actions/custom/generatePromptResponse 进行验证。
  • 分支 B — 组织上不存在三个执行者角色权限集中的任何一个。 ITSM AddOn(s) 尚未配置;分配权限集不会产生任何效果。停止并转交给 service-itsm-agentic-setup-agentforce-studio-validate,以便先启用 AddOn(s)。

有意采用这两个分支——activate 时出现“svc_itsm_intelligence__X does not exist”这一失败特征,无论角色已存在但尚未分配,还是 AddOn 完全缺失,表现都相同,无法仅凭 activate 响应加以区分。预先检查这三个角色 PermissionSet 名称,才能判明具体情况。

四个辅助脚本(均通过 Bash 调用)负责所有确定性判断(A9)。完整的 I/O 契约见 references/helper-contracts.md;下面汇总工作流级别的用法:

  • scripts/classify-permset-availability.mjs — 判断分支 A 或 B,并确定每种角色的 needsPsl 标记。返回完整的 candidates[](组织中实际存在的角色),供调用方提示用户选择。
  • scripts/resolve-target-user.mjs — 从 API 根目录的 identity URL 中提取 005… 格式的运行用户 Id。遇到任何格式错误时都会安全失败。
  • scripts/classify-assignment-state.mjs — 判断幂等性;如果所选角色的 needsPsl:false,则用哨兵值 NO-PSL 代替 PSLA 路径。
  • scripts/classify-action-surface.mjs — 根据 /actions/custom/generatePromptResponse 捕获结果给出 Phase 4 验证判定(可选提供预期操作 CSV)。

前置条件

  1. 已安装 sf CLI,且已通过身份验证连接到目标组织(sf org display -o <alias> 显示 Connected)。所有调用均使用 --target-org <alias>;切勿手动提取或传递访问令牌。
  2. API v67.0+。
  3. PATH 中有 node ≥ 18。

如果任何前置条件不满足,sf 会返回身份验证错误或 401/403/404;请原样报告原始响应并停止。


澄清问题

只询问无法从对话中推断的信息:

  • 目标组织 — sf 别名。如果未设置,默认使用 sf config get target-org。
  • 目标用户 — 默认使用运行用户(通过 scripts/resolve-target-user.mjs 解析)。如果用户要求代表指定用户分配,则先通过 Username 查找该用户。
  • 要使用哪种 Fulfiller 角色? Incident / Problem / Change。只询问组织中实际已配置的角色(来自 candidates[])。不要自动选择——即使组织中已配置其他角色,Fulfiller 通常也只需要一种角色(例如 Incident)。
  • 确认写入操作 — 分配权限集许可证会占用一个名额,并会对当前用户会话立即生效。请向用户显示目标用户、组织和角色权限集名称,并在写入前通过 AskUserQuestion 要求用户明确回复 “yes”。

工作流

所有调用均通过 sf 进行;将 <alias> 替换为目标组织。

Phase 1 — 读取:此组织中配置了哪些 Fulfiller 角色权限集?
  1. 查询 PermissionSet,查找三个已知的 Fulfiller 角色 DeveloperName:

    sf data query \
      -q "SELECT Id, Name, Label, LicenseId FROM PermissionSet WHERE Name IN ('IncidentFulfiller','ProblemFulfillerPermSet','ChangeRequestFulfillerPermSet')" \
      --target-org <alias> --json > /tmp/itsm-personas.json 2>/tmp/itsm-personas.err || true
    

    (这三项的 PermissionSet 命名空间均为 force——不要按 NamespacePrefix 进行筛选。)

  2. 分类:

    node "<skill_dir>/scripts/classify-permset-availability.mjs" /tmp/itsm-personas.json
    

    分类器会打印 { personasFound, personasMissing, candidates, verdict, reasons },其中每一行 candidates[] 的格式为 {Id, Name, Label, LicenseId, needsPsl}:

    • verdict:"ASSIGN"(至少存在一种角色)⇒ 继续执行 Phase 2。通过 AskUserQuestion 向用户展示 personasFound 列表并让其选择角色;记录其 Id、LicenseId 和 needsPsl——这些信息决定 Phase 2b/2d 是否需要操作 PSL。
    • verdict:"HAND-OFF"(三个角色均不存在)⇒ 此组织无法执行 Phase 2;转到 Phase 3(分支 B 移交)。
    • verdict:"CANNOT-CONFIRM"(查询失败)⇒ 原样显示原始 CLI 错误;停止。
阶段 2 — 分配路径(分支 A)

2a. **解析目标用户。**读取身份 URL,然后通过解析器提取用户 Id(不要手动解析 URL;不要使用 USER_ID()——仅限 Apex,REST 会拒绝;不要依赖 /chatter/users/me——Chatter 关闭时会返回 403):

sf api request rest "/services/data/v67.0/" --method GET --target-org <alias> > /tmp/api-root.json 2>/tmp/api-root.err || true
node "<skill_dir>/scripts/resolve-target-user.mjs" /tmp/api-root.json

解析器会输出 { userId, identity, verdict, reasons }。当 verdict:"RESOLVED" 时,将 userId 用作当前操作用户;当 verdict:"CANNOT-CONFIRM" 时,原样呈现原因并停止——不要猜测。

如果用户要求代替某个指定用户进行分配,则按 Username 解析:

sf data query \
  -q "SELECT Id, Username, Name, IsActive FROM User WHERE Username = '<username>'" \
  --target-org <alias> --json > /tmp/user-lookup.json 2>/tmp/user-lookup.err || true

2b. **幂等性读取。**查询目标用户与所选角色的 Id 对应的 PermissionSetAssignment(SOQL 格式见 references/cli-invocation.md),然后根据所选角色的 needsPsl 进行分支:

  • needsPsl:true — 查询目标用户与该角色 LicenseId 对应的 PermissionSetLicenseAssign,然后分类:

    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json /tmp/psla-existing.json
    
  • needsPsl:false — 完全跳过 PSLA 查询;传入哨兵值:

    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json NO-PSL
    

分类器会输出 { permsetAssigned, licenseAssigned, needsWrite, verdict, reasons }。如果 needsWrite:false ⇒ 转到阶段 4(仅验证)。否则继续执行阶段 2c。

2c. **写入确认检查点(必需)。**展示目标用户、组织和角色权限集名称,并通过 AskUserQuestion 要求用户明确回答“是”。如果回答“否”,则停止并报告当前状态,不进行任何写入。

2d. 分配 — 顺序取决于所选角色的 needsPsl:

  • needsPsl:true — 先将 PSL POST 到 /sobjects/PermissionSetLicenseAssign,然后运行 sf org assign permset --name <permsetName> --on-behalf-of <userId>。未先分配 PSL 就分配权限集,会导致分配记录保留,但其许可证不会生效。具体调用格式见 references/cli-invocation.md。
  • needsPsl:false — 完全跳过 PSL POST;仅运行 sf org assign permset。(其 PermissionSet 没有关联 LicenseId 的角色不受许可证限制——没有需要占用的 PSL 席位,因此仅分配权限集就是正确且完整的写入。)_防御性保留:_目前所有已发布角色都有 PSL 支持(needsPsl 按行根据 LicenseId 推导),因此当前已发布数据不会触发此 false 分支及其 NO-PSL 连接;保留此分支是为了兼容未来不带关联 LicenseId 的 PermissionSet 角色。

响应处理:

  • POST 返回 201 / sf org assign permset 返回 success:true ⇒ 已分配。
  • PSL POST 返回 400 DUPLICATE_VALUE ⇒ 用户已拥有该许可证;视为成功,不是错误。
  • PSL POST 返回 400 INSUFFICIENT_ACCESS / 席位耗尽错误 ⇒ 停止此次写入;告知用户 PSL 没有可用席位。
阶段 3 — 移交路径(分支 B:未配置 Fulfiller 角色)
  1. 当阶段 1 返回 verdict:"HAND-OFF" 时,当前组织不存在三个 Fulfiller 角色权限集中的任何一个——尚未配置 ITSM AddOn。处于此状态时,权限集分配操作不会产生任何效果。通过 AskUserQuestion 呈现发现结果:

    “此组织未配置任何 Fulfiller 角色权限集(Incident、Problem、Change)——无法通过权限集授予对尚不存在操作的访问权限。是否运行 service-itsm-agentic-setup-agentforce-studio-validate,以诊断需要启用哪个 AddOn?”(选项:是,运行就绪检查 / 否,到此为止)。

    • 选择是:委派给 service-itsm-agentic-setup-agentforce-studio-validate,并让其建议 configure/bundle-deploy 技能。
    • 选择否:停止并报告当前状态(未配置角色,无法分配)——不进行任何写入。
阶段 4 — 验证
  1. 无论是写入还是跳过,都要重新读取 /actions/custom/generatePromptResponse,并通过 helper 分类(绝不能通过搜索文本分类 — A9)。CSV 格式和两种调用形式见 references/helper-contracts.md / references/cli-invocation.md:

    sf api request rest "/services/data/v67.0/actions/custom/generatePromptResponse" \
      --method GET --target-org <alias> > /tmp/generate-prompt-response.json 2>/tmp/generate-prompt-response.err || true
    node "<skill_dir>/scripts/classify-action-surface.mjs" /tmp/generate-prompt-response.json [expectedActions-csv]
    

    helper 会输出 { present, missing, totalItsmActionsSeen, verdict, reasons }。若结果为 SURFACED,则进入阶段 5;若成功分配后结果为 PARTIAL / MISSING,则告知用户写入成功,但这些操作未显示 — 可能需要刷新会话,或当前角色不正确。不得谎报成功。若结果为 CANNOT-CONFIRM,则原样展示原因。

阶段 5 — 汇总结论
  1. 报告以下其中一项:
    • ASSIGNED — 分支 A 已写入,验证确认目标操作已显示。
    • ALREADY-ASSIGNED — 分支 A 发现 needsWrite:false;验证确认目标操作已显示。(分配已完成;无需写入。)
    • HAND-OFF — 分支 B;未配置 Fulfiller 角色。已指出后续技能。
    • VERIFY-INCONCLUSIVE — 写入已完成,但验证读取未显示预期的操作集。原样展示观察到的状态;不得报告成功。
    • FAILED — 阶段 2d 的任何写入返回了 DUPLICATE_VALUE 以外的错误。报告原始错误。

规则 / 约束

约束原因
在写入任何权限集之前,通过三个固定的 PermissionSet.Name 值检测是否存在 Fulfiller 角色激活时出现的失败特征(“action does not exist”)对于 AddOn 缺失和未分配权限集的情况完全相同;只有预检查才能区分二者。这三个角色由 force 命名空间随 Core 一同提供,因此 NamespacePrefix 筛选永远不会返回它们
询问用户要分配哪个角色——绝不自动选择Fulfiller 通常只需要一个角色(例如 Incident)。自动分配返回的第一行会导致授权过度
所有决策均由辅助脚本作出,绝不通过文字描述作出分配和幂等逻辑是确定性的;文字解读则不是(A9)
仅当所选角色的 needsPsl:true 时,先分配 PSL,再分配权限集权限集由许可证支持;许可证席位必须先被占用,分配才会生效。所选角色没有 LicenseId 时,needsPsl:false,会完全跳过 PSL POST
按行从所选角色的 LicenseId 读取 needsPsl——绝不通过命名空间范围的 PSL 查询读取同一 org 上不同角色的许可证形态可能不同;若回退到命名空间范围的 PSL,会 POST 错误的 PermissionSetLicenseAssign
使用 scripts/resolve-target-user.mjs 解析当前运行用户的 Id——绝不通过文字解析 identity URLidentity URL 的路径段格式(005…,15 或 18 个字符)是硬性规则;分类器会验证并在验证失败时安全终止
使用 scripts/classify-action-surface.mjs 对 Phase 4 的操作面进行分类——绝不通过 grep 响应中的文字进行判断Verify 是报告 SUCCESS 还是 VERIFY-INCONCLUSIVE 的关卡;决策必须是确定性的
将 PSL POST 返回的 400 DUPLICATE_VALUE 视为成功这表示该用户已拥有该分配——这是幂等结果,不是错误
绝不创建或编辑权限集此技能仅分配标准 Fulfiller 角色权限集;编写权限集不在范围内
绝不安装 AddOn/绝不切换 org 级别的 Agentforce 功能这属于 service-itsm-agentic-setup-agentforce-studio-validate / -configure 的范围;此技能负责移交,不负责启用
写入后通过 /actions/custom/generatePromptResponse 验证——绝不只相信 POST 返回码分配可能成功,但目标操作面仍可能不包含 Fulfiller 模板所需的内容(角色错误、缓存)
在 Phase 2d 之前设置写入确认检查点权限集分配会占用一个许可证席位,并对实时用户会话生效
绝不提取访问令牌使用 sf api request rest / sf data query / sf org assign permset——这些命令使用 CLI 中存储的会话
准确报告 CLI 响应中的错误文本便于支持人员诊断故障

验证清单

  • 通过 scripts/classify-permset-availability.mjs 根据三个固定的 persona Name 判定 persona 是否可用,绝不扫描查询输出中的文本。
  • 请用户从 personasFound[] 中选择一个 persona,不得自动选择。
  • 通过 scripts/resolve-target-user.mjs 解析目标用户 Id,绝不通过拆分身份 URL 来获取。
  • 所选 persona 的 needsPsl 决定 Phase 2b/2d 的处理方式:值为 true 时执行 PSL SOQL 查询和 POST,值为 false 时跳过。
  • PSL POST 使用的 permsetLicenseId 来自所选 persona 自身的 LicenseId,绝不使用命名空间范围查询中的备用值。
  • 在 Branch A 上:写入前通过 sf data query 读取现有分配,并由 scripts/classify-assignment-state.mjs 判定状态(needsPsl:false 时使用 NO-PSL sentinel)。
  • 在 Branch A 上:用户在 Phase 2c 检查点确认了写入操作。
  • 在 Branch A 且 needsPsl:true 时:先 POST PSL,再分配权限集。
  • 将 PSL POST 返回的 DUPLICATE_VALUE 视为成功,而非失败。
  • 在 Branch B 上:未尝试写入;已提供移交给 service-itsm-agentic-setup-agentforce-studio-validate 的选项。
  • Phase 4 验证通过 scripts/classify-action-surface.mjs 判定;只有 helper 返回 verdict:"SURFACED" 时才能报告 ASSIGNED。
  • 报告汇总判定结果(ASSIGNED / ALREADY-ASSIGNED / HAND-OFF / VERIFY-INCONCLUSIVE / FAILED)。

输出格式

ITSM Fulfiller Persona Permset Assignment (via service-itsm-agentic-setup-itsm-agentforce-permset-assign)

Org:            <org-alias> (API v67.0)
Target user:    <username> (<userId>)
Persona:        <Incident | Problem | Change>
PermSet:        <DeveloperName>

  Personas provisioned on org ...... <comma-separated list | none>
  Existing PSL assignment .......... <yes | no | n/a>
  Existing permset assignment ...... <yes | no>
  Write PSL ........................ <succeeded | already-had | skipped | FAILED>
  Write permset .................... <succeeded | already-had | skipped | FAILED>
  Verify actions surface ........... <yes | partial | no>

Verdict: ASSIGNED | ALREADY-ASSIGNED | HAND-OFF | VERIFY-INCONCLUSIVE | FAILED
Reason:  <plain-language explanation, or empty on success>

Next steps:
  - <If ASSIGNED / ALREADY-ASSIGNED: "Re-run service-itsm-agentic-setup-fulfiller-agent-configure — the invocable actions should now surface, and the activate call will succeed.">
  - <If HAND-OFF: "No Fulfiller persona is provisioned on this org. Run service-itsm-agentic-setup-agentforce-studio-validate to identify which AddOn needs enabling.">
  - <If VERIFY-INCONCLUSIVE: list the observed state verbatim; a session refresh or a different persona may be required>
  - <If FAILED: list the observed error verbatim + remediation>

面向用户的输出中不得包含内部术语(record Id、HTTP 状态码、FUNCTIONALITY_NOT_ENABLED、DUPLICATE_VALUE、对象/开发者名称、sf api request rest)。


参考文件索引

文件何时阅读
references/permset-topology.md每当 persona 列表发生变化时——三个随 Core 提供的 Fulfiller 权限集、它们的 AddOns/PSLs/userPerms,以及固定查找发现查询
references/cli-invocation.md每个阶段——确切的 sf api request rest / sf data query / sf org assign permset 调用格式、绝不提取令牌的规则、响应封装结构
references/helper-contracts.md四个 helper 脚本(classify-permset-availability.mjs、resolve-target-user.mjs、classify-assignment-state.mjs、classify-action-surface.mjs)的输入/输出格式,以及如何解读各项判定结果

评论

支持 Markdown