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 について

Salesforce CLI を使い、ITSM Fulfiller の権限セットと必要なライセンスをユーザーに割り当て、プロンプトテンプレートのアクションを検証します。権限セットが組織にない場合は、AddOn の有効化確認に引き継ぎます。

主な機能

  1. 013 種類の Fulfiller 権限セットを検出
  2. 02ライセンスと権限セットを確認・割り当て
  3. 03実行ユーザーまたは指定ユーザーに対応
  4. 04プロンプトテンプレートのアクションを検証
  5. 05AddOn がない場合は確認に引き継ぎ

活用シーン

  1. 01Fulfiller Agent にプロンプトテンプレートアクションへのアクセスを付与
  2. 02変更前に割り当て状態を確認
  3. 03先に ITSM AddOn の有効化が必要かを判定

MCP 対応

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 Fulfiller ペルソナの権限セットを割り当てる(プロンプトテンプレートへのアクセス)

実行中のユーザーに、ターゲット組織上で svc_itsm_intelligence__* プロンプトテンプレートの呼び出し可能アクションを公開する、Core に同梱されたFulfiller ペルソナ権限セットのいずれかを付与します。これらのアクションは、Fulfiller NGA エージェントのスクリプトで source: / target: generatePromptResponse://... を通じて参照されています。実行中のユーザーに対してこれらの呼び出し可能アクションが /services/data/v67.0/actions/custom/generatePromptResponse に表示されない場合、Fulfiller エージェント設定スキルの Phase 6 activate 呼び出しは、サイレントな {success:false, messages:[{... "does not exist"}]} 本文を伴う HTTP 200 を返し、エージェントは利用可能になりません。このスキルは、適切な Fulfiller ペルソナ権限セット(存在する場合はその基盤となるライセンスも)を割り当てて、この不足を解消します。あるいは、組織に Fulfiller ペルソナ権限セットがまったくプロビジョニングされていない場合は、Agentforce Studio の設定/検証スキルに引き継ぎ、先に ITSM AddOn を有効にできるようにします。

3 つの Fulfiller ペルソナ権限セット、その AddOn、PSL、および付与する userPerms については、references/permset-topology.md に記載されています。これらはすべて force 名前空間の Core に同梱されたものであり、この機能にはマネージドパッケージの名前空間付き権限セットはありません。

Employee エージェントは対象外です。 Employee NGA エージェントのアクセスモデルは別個のもの(組織設定+別のペルソナレイヤー)であり、これら 3 つのペルソナ権限セットには対応しません。

すべての呼び出しは Salesforce CLI(sf) を通じて実行されます。

  • sf api request rest — 認証済み Connect API GET(ID の取得、読み取りの検証)。
  • sf data query — PermissionSet(ペルソナの有無)、PermissionSetAssignment / PermissionSetLicenseAssign(冪等性)に対する SOQL。
  • sf org assign permset — 実行中のユーザーへの権限セットの割り当て。
  • トークンを抽出することはありません。MCP も使用しません。

範囲

  • 対象範囲内:3 つの Fulfiller ペルソナ権限セット(IncidentFulfiller、ProblemFulfillerPermSet、ChangeRequestFulfillerPermSet)のうち、どれが組織にプロビジョニングされているかを検出すること、ユーザーに割り当てるペルソナを選んでもらうこと、既存の割り当てを確認すること、ペルソナにライセンス制限がある場合は権限セットライセンスを実行中のユーザー(または指定されたユーザー)に割り当てること、ターゲットの svc_itsm_intelligence__* 呼び出し可能アクションが後続の /actions/custom/generatePromptResponse 読み取りで表示されることを検証すること。
  • 対象範囲外:Employee エージェントへのアクセス(アクセスモデルが異なるため、別のスキルを使用)、ITSM AddOn またはコンテンツバンドルのインストール/有効化(service-itsm-agentic-setup-agentforce-studio-validate に引き継ぎます)、組織レベルの Agentforce 機能トグルの有効化、権限セットの作成、Fulfiller エージェントの作成または有効化(これは service-itsm-agentic-setup-fulfiller-agent-configure の役割です)、CMDB アクセス(service-itsm-agentic-setup-cmdb-access-assign)、ITSM 以外の一般的な権限セットの割り当て(dx-org-permission-set-assign)。

仕組み

まず読み取り専用の検出ステップを実施し、その結果に応じて 2 つの分岐に進みます。

  • 分岐 A — 1 つ以上の Fulfiller ペルソナ権限セットが組織に存在する。 割り当てるペルソナをユーザーに選んでもらいます(自動選択はしません。Fulfiller が必要とするペルソナは通常 1 つだけです)。冪等に割り当てます。ペルソナにライセンス制限がある場合は、まず PSL を割り当て、続いて権限セットを割り当てます。読み戻しと、後続の /actions/custom/generatePromptResponse 読み取りで検証します。
  • 分岐 B — 3 つの Fulfiller ペルソナ権限セットがいずれも組織に存在しない。 ITSM AddOn がプロビジョニングされていないため、権限セットの割り当ては何も行いません。停止し、service-itsm-agentic-setup-agentforce-studio-validate に引き継いで、先に AddOn を有効にできるようにします。

この 2 分岐の構成には明確な理由があります。activate で "svc_itsm_intelligence__X does not exist" が返る場合、ペルソナは存在するが未割り当ての場合と、AddOn 自体が存在しない場合とで、エラーの特徴は同じです。また、activate の応答だけでは両者を判別できません。3 つのペルソナ PermissionSet 名に対する事前チェックによって、両者を区別できます。

4 つのヘルパースクリプトが、すべての決定論的な判断を担います(いずれも Bash 経由で実行、A9)。完全な入出力契約は 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 の場合は、PSLA パスの代わりにセンチネル値 NO-PSL を渡します。
  • scripts/classify-action-surface.mjs — /actions/custom/generatePromptResponse のキャプチャを基に、Phase 4 の検証結果を判定します(任意の expected-actions CSV に対応)。

前提条件

  1. sf CLI がインストールされ、対象組織に認証されていること(sf org display -o <alias> で Connected と表示されること)。すべての呼び出しで --target-org <alias> を使用します。アクセストークンを手作業で抽出したり、渡したりしないでください。
  2. API v67.0 以降。
  3. node ≥ 18 が PATH 上にあること。

前提条件を満たさない場合、sf は認証エラーまたは 401/403/404 を返します。応答を一字一句そのまま報告し、処理を中止してください。


確認事項

会話から推測できないことだけを確認してください。

  • 対象組織 — sf のエイリアスです。未設定の場合は sf config get target-org をデフォルトとして使用します。
  • 対象ユーザー — デフォルトは実行ユーザーです(scripts/resolve-target-user.mjs で解決)。名前を指定したユーザーに代わって割り当てるよう依頼された場合は、まず Username でそのユーザーを解決します。
  • どの Fulfiller ペルソナか — Incident/Problem/Change。組織に実際にプロビジョニングされているペルソナ(candidates[] に含まれるもの)だけを確認します。自動選択しないでください。複数のペルソナがプロビジョニングされていても、Fulfiller が必要とするのは通常 1 つ(例:Incident のみ)です。
  • 書き込みの確認 — 権限セットライセンスを割り当てるとシートを消費し、稼働中のユーザーセッションに反映されます。書き込み前に、対象ユーザー、組織、ペルソナの permset 名を提示し、AskUserQuestion で明示的な「はい」の回答を得てください。

ワークフロー

すべての呼び出しは sf を介して実行します。<alias> は対象組織に置き換えてください。

Phase 1 — 読み取り:この組織にプロビジョニングされている Fulfiller ペルソナの permset はどれか?
  1. 既知の 3 つの Fulfiller ペルソナの DeveloperName を対象に、PermissionSet をクエリします。

    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
    

    (3 つすべての 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"(1 つ以上のペルソナが存在)⇒ Phase 2 に進みます。personasFound の一覧を AskUserQuestion でユーザーに提示し、選択されたペルソナを取得します。その Id、LicenseId、needsPsl を記録してください。これらを基に、Phase 2b/2d で PSL にアクセスするかどうかを決めます。
    • verdict:"HAND-OFF"(3 つのペルソナのいずれも存在しない)⇒ この組織では Phase 2 を実行できません。Phase 3(分岐 B の引き継ぎ)に進みます。
    • verdict:"CANNOT-CONFIRM"(クエリに失敗)⇒ CLI のエラーを一字一句そのまま提示し、処理を中止します。
フェーズ 2 — パスを割り当てる(ブランチ A)

2a. 対象ユーザーを解決します。 ID 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. 書き込み前の確認チェックポイント(必須)。 対象ユーザー、組織、ペルソナの permset 名を提示し、AskUserQuestion を通じて明示的な「yes」を求めます。「no」の場合は停止し、書き込みを行わずに現在の状態を報告します。

2d. 割り当て — 順序は選択したペルソナの needsPsl によって異なります。

  • needsPsl:true — まず /sobjects/PermissionSetLicenseAssign に PSL を POST し、その後 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 シートがないため、permset のみを割り当てるのが正しく、これで完了です。)防御的に保持: 現在、提供されているすべてのペルソナは 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" を返した場合、この組織には 3 つの Fulfiller ペルソナ用 permset がどれも存在しません。ITSM AddOn がプロビジョニングされていません。この状態では permset の割り当ては何も行いません。AskUserQuestion を通じて、次の検出結果を提示します。

    「この組織には、Fulfiller ペルソナの権限セット(Incident、Problem、Change)がプロビジョニングされていません。まだ存在しないアクションへのアクセスを permset で付与することはできません。service-itsm-agentic-setup-agentforce-studio-validate を実行して、有効化が必要な AddOn を診断しますか?」(選択肢:はい、準備状況を確認する / いいえ、ここで停止する)。

    • はいの場合:service-itsm-agentic-setup-agentforce-studio-validate に委任し、設定/バンドルデプロイ用スキルを推奨させます。
    • いいえの場合:停止し、現在の状態(ペルソナがプロビジョニングされておらず、割り当てできない)を報告します。書き込みは行いません。
フェーズ 4 — 検証
  1. 書き込みを行ったかスキップしたかにかかわらず、/actions/custom/generatePromptResponse を再読み込みし、ヘルパーを使って分類します(文章の grep による分類は行いません — 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]
    

    ヘルパーは { 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 以外のエラーが返されました。生のエラーを報告します。

ルール/制約

制約理由
権限セットへの書き込みを行う前に、3 つの固定値 PermissionSet.Name によって Fulfiller ペルソナの存在を検出します失敗時のシグネチャ(有効化時に「action does not exist」と表示される)は、AddOn が存在しない場合と権限セットが割り当てられていない場合で同一です。両者を区別できるのは事前チェックのみです。3 つのペルソナは force 名前空間に含まれているため、NamespacePrefix で絞り込んでも返されません
割り当てるペルソナをユーザーに確認します。自動選択はしませんFulfiller が必要とするペルソナは通常 1 つだけです(例:Incident)。返された最初の行を自動的に割り当てると、過剰な権限付与になります
すべての判断はヘルパースクリプトで行い、文章の解釈に頼りません割り当て/冪等性のロジックは決定的ですが、文章の解釈は決定的ではありません(A9)
選択したペルソナの needsPsl:true の場合に限り、権限セットより先に PSL を割り当てます権限セットはライセンスに紐付いているため、割り当てが反映されるには、先にライセンスシートを確保する必要があります。選択したペルソナに LicenseId がない場合、needsPsl:false となり、PSL の POST は完全に省略されます
needsPsl は選択したペルソナの LicenseId から、行ごとに読み取ります。名前空間全体の PSL クエリから取得してはいけません同じ組織内でも、ペルソナによってライセンスの構成が異なる場合があります。名前空間全体の PSL にフォールバックすると、誤った PermissionSetLicenseAssign を POST することになります
実行ユーザーの Id は scripts/resolve-target-user.mjs で解決します。identity URL を文章から解析してはいけませんidentity URL のセグメント形式(005…、15 文字または 18 文字)は厳密なルールです。分類スクリプトが検証し、安全側に失敗します
フェーズ 4 のアクション対象範囲は scripts/classify-action-surface.mjs で分類します。レスポンスを文章から grep してはいけませんVerify は SUCCESS と VERIFY-INCONCLUSIVE の報告を判定するためのゲートです。この判断は決定的でなければなりません
PSL の POST で 400 DUPLICATE_VALUE が返された場合は成功として扱いますこれは、ユーザーにすでに割り当てられていることを意味します。冪等な状態であり、エラーではありません
権限セットの作成や編集は行いませんこのスキルで行うのは、標準の Fulfiller ペルソナ権限セットの割り当てのみです。権限セットの作成は対象外です
AddOn のインストールや、組織レベルの Agentforce 機能の切り替えは行いませんこれは service-itsm-agentic-setup-agentforce-studio-validate/-configure の対象範囲です。このスキルは引き継ぎを行うものであり、有効化はしません
書き込み後は /actions/custom/generatePromptResponse で検証します。POST の戻りコードだけを信頼してはいけません割り当てが成功しても、対象のアクション範囲に Fulfiller テンプレートが必要とするものが含まれていない場合があります(ペルソナの誤り、キャッシュなど)
フェーズ 2d の前に、書き込みの確認を求めます権限セットの割り当てはライセンスシートを消費し、稼働中のユーザーセッションに反映されます
アクセストークンを取り出してはいけませんsf api request rest/sf data query/sf org assign permset を使用します。これらは CLI に保存されたセッションを使用します
CLI のレスポンスに含まれるエラーテキストを正確に報告しますサポート担当者が障害を診断できるようになります

検証チェックリスト

  • ペルソナの利用可否は、クエリ出力の文章をスキャンして判断するのではなく、scripts/classify-permset-availability.mjs を使い、固定された3つのペルソナ名に照らして分類しました。
  • personasFound[] からペルソナを選ぶようユーザーに求めました。自動選択はしていません。
  • 対象ユーザー Id は scripts/resolve-target-user.mjs で解決しました。ID URL の文章を分割して取得していません。
  • 選択されたペルソナの needsPsl に基づいて Phase 2b/2d を実施しました。値が true の場合は PSL SOQL と POST を実行し、false の場合は省略しました。
  • PSL POST に使用した permsetLicenseId は、選択されたペルソナ自身の LicenseId から取得しました。名前空間全体を対象にしたクエリからのフォールバックは使用していません。
  • Branch A:書き込みを行う前に sf data query で既存の割り当てを読み取り、scripts/classify-assignment-state.mjs で分類しました(needsPsl:false の場合は NO-PSL センチネルを使用)。
  • Branch A:Phase 2c のチェックポイントで、ユーザーが書き込みを確認しました。
  • Branch A かつ needsPsl:true:権限セットを割り当てる前に PSL を POST しました。
  • PSL POST での DUPLICATE_VALUE は失敗ではなく成功として扱いました。
  • Branch B:書き込みは試みず、service-itsm-agentic-setup-agentforce-studio-validate への引き継ぎを提示しました。
  • Phase 4 の検証は scripts/classify-action-surface.mjs で分類しました。このヘルパーが 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>

内部向けの専門用語(レコード Id、HTTP ステータスコード、FUNCTIONALITY_NOT_ENABLED、DUPLICATE_VALUE、オブジェクト名/開発者名、sf api request rest)をユーザー向けの出力に含めないでください。


参考ファイル一覧

ファイル読み込むタイミング
references/permset-topology.mdペルソナ一覧を変更するとき。Core に同梱されている3つの Fulfiller 権限セット、その AddOns/PSL/userPerms、固定検索の検出クエリについて
references/cli-invocation.mdすべてのフェーズ。sf api request rest/sf data query/sf org assign permset の正確な呼び出し形式、トークンを抽出しないルール、レスポンスのエンベロープについて
references/helper-contracts.md4つのヘルパースクリプト(classify-permset-availability.mjs、resolve-target-user.mjs、classify-assignment-state.mjs、classify-action-surface.mjs)の入力/出力形式と、各判定の解釈について

コメント