Loading...
Loading...
Grant a user the runtime permissions an activated ITSM agent's actions need so the actions do not fail on permission errors. After a Fulfiller or Employee agent is activated, this skill detects which platform feature permission sets are provisioned (Prompt Templates, Data Cloud, Unified Catalog), lets you pick a tier (user/agent vs admin) per feature and which user(s) to assign, then assigns them (license first when license-gated). It also creates a custom "Agent Access" permission set granting the activated agents you choose and assigns it to the user — all via the Salesforce CLI. Use to grant a user access to an activated agent, to assign prompt-template, data-cloud, or unified-catalog access, or to create an Agent Access permission set. DO NOT TRIGGER for enabling Agentforce for IT Service toggles, creating or activating an agent, the Fulfiller activation action-surfacing gap (service-itsm-agentic-setup-itsm-agentforce-permset-assign), CMDB access, or generic permission-set assignment.
npx skill4agent add forcedotcom/sf-skills service-itsm-agentic-setup-agent-runtime-access-assignSetupEntityAccessreferences/permset-topology.mdsfAgent_AccessSetupEntityAccessAgent_Accessservice-itsm-agentic-setup-agentforce-studio-configureservice-itsm-agentic-setup-employee-agent-configureservice-itsm-agentic-setup-fulfiller-agent-configureservice-itsm-agentic-setup-itsm-agentforce-permset-assignservice-itsm-agentic-setup-cmdb-access-assignBashreferences/helper-contracts.mdscripts/classify-platform-permset-availability.mjspresentneedsPslscripts/resolve-target-user.mjsidentityscripts/rank-candidate-users.mjsscripts/gate-unified-catalog-tiers.mjsscripts/classify-activated-agents.mjsInternalCopilotActivescripts/classify-agent-access-state.mjsAgent_Accessscripts/classify-assignment-state.mjsNO-PSLneedsPsl:falsesfsf org display -o <alias>--target-org <alias>nodesf401403404sfsf config get target-orgAskUserQuestionAskUserQuestionsf<alias>references/cli-invocation.mdsf data query \
-q "SELECT Id, Name, Label, LicenseId FROM PermissionSet WHERE Name IN ('EinsteinGPTPromptTemplateUser','EinsteinGPTPromptTemplateManager','GenieUserEnhancedSecurity','GenieAdmin','UnifiedCatalogCommunityUser','UnifiedCatalogAdmin')" \
--target-org <alias> --json > /tmp/itsm-platform-permsets.json 2>/tmp/itsm-platform-permsets.err || true
node "<skill_dir>/scripts/classify-platform-permset-availability.mjs" /tmp/itsm-platform-permsets.json{ features, provisionedFeatures, absentFeatures, verdict }verdict:"ASSIGNABLE"verdict:"NONE-PROVISIONED"verdict:"CANNOT-CONFIRM"sf data query \
-q "SELECT Id, DeveloperName, MasterLabel, (SELECT Status FROM BotVersions WHERE Status='Active') FROM BotDefinition WHERE Type='InternalCopilot'" \
--target-org <alias> --json > /tmp/itsm-agents.json 2>/tmp/itsm-agents.err || true
node "<skill_dir>/scripts/classify-activated-agents.mjs" /tmp/itsm-agents.jsonverdict:"AGENTS-FOUND"activatedAgents[]verdict:"NONE-ACTIVE"Agent_AccessNONE-PROVISIONEDsf 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
sf data query -q "SELECT Name, Profile.Name, Profile.UserLicense.Name FROM User WHERE Id='<userId>'" --target-org <alias> --json > /tmp/itsm-running-user.json 2>/dev/null || true
sf data query -q "SELECT Id, Name, Username, Profile.Name, Profile.UserLicense.Name FROM User WHERE IsActive = true ORDER BY LastLoginDate DESC NULLS LAST LIMIT 25" --target-org <alias> --json > /tmp/itsm-candidate-users.json 2>/dev/null || true
node "<skill_dir>/scripts/rank-candidate-users.mjs" /tmp/itsm-candidate-users.json <audience> <userId>verdict:"RESOLVED"userIdName/tmp/itsm-running-user.jsonCANNOT-CONFIRM<audience>fulfilleremployeeanyrank-candidate-users.mjsAskUserQuestionUsernamereferences/cli-invocation.mdAskUserQuestion{ name, Id, LicenseId, needsPsl }scripts/gate-unified-catalog-tiers.mjsoffer[]omitAgent_AccessAskUserQuestionAgent_AccessBotDefinition/tmp/agent-access.json/tmp/sea.jsonreferences/cli-invocation.mdnode "<skill_dir>/scripts/classify-agent-access-state.mjs" /tmp/agent-access.json <sea.json|NO-PERMSET> "<chosenAgentIds-csv>"NO-PERMSETAgent_Access{ permsetExists, permsetId, missingAgentIds, needsCreate, needsGrants, verdict }Agent_AccessPermissionSetAssignmentPermissionSetLicenseAssignneedsPsl:truereferences/cli-invocation.mdAgent_AccessneedsPsl:falseNO-PSLneedsPslAgent_AccessneedsCreate:truePermissionSetAssignmentNEEDS-WRITEAgent_AccesspermsetIdnode "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa.json </tmp/psla.json|NO-PSL>Agent_AccessAskUserQuestionneedsCreate/sobjects/PermissionSet{"Name":"Agent_Access","Label":"Agent Access"}idmissingAgentIds/sobjects/SetupEntityAccess{"ParentId":"<permsetId>","SetupEntityId":"<agentId>"}SetupEntityType0XxDUPLICATE_VALUENEEDS-WRITEneedsPslneedsPsl:true/sobjects/PermissionSetLicenseAssignLicenseIdsf org assign permset --name <tierName>--on-behalf-of--on-behalf-of "<username>"needsPsl:falsesf org assign permsetsf org assign permset --name Agent_Access--on-behalf-of--on-behalf-of "<username>"NEEDS-WRITE--on-behalf-ofUsername005$USERNAMEreferences/cli-invocation.mdDUPLICATE_VALUEalready hasINSUFFICIENT_ACCESSreferences/cli-invocation.mdPermissionSetAssignmentPermissionSetLicenseAssignSetupEntityAccessAgent_Access| Constraint | Rationale |
|---|---|
| Detect provisioned features before assigning; report absent features as "not provisioned", never fail on them | No org has all three; an absent permset errors and masks real state |
| Ask the tier (user/agent vs admin) per provisioned feature — never auto-select | The lighter tier suffices to use the feature; admin over-grants |
| Offer standard-license users for a Fulfiller agent, Unified Employee for an Employee agent; the ranker drops service/bot accounts | The wrong cohort offers users who can't run that agent |
Offer a Unified Catalog tier only to a user who can hold it (Community User → Unified Employee; Admin → System Administrator), else omit for that user — via | UC PSLs are license-shape gated; an ineligible tier is a hard write-time failure, not a seat shortage |
| All availability / idempotency / activation decisions are made by helper scripts, never by prose | They gate writes/success; scripts are deterministic, prose is not (A9) |
| Different orgs carry different license shapes; a wrong |
Assign the PSL before the permission set when | The permset is license-backed; hold the seat first |
| Access is granted like Apex-class access — one grant row per agent |
POST | Not createable — derived from the |
Create | Createable over the data API with just |
| One consolidated confirm-to-write before ANY write | The full plan (seats consumed, live-session effect) must be approved once |
Treat | Re-running must be safe; a duplicate means the state already holds |
| Verify by read-back before reporting ASSIGNED | A POST return code alone doesn't prove the row is present |
| Never extract the access token; never use an MCP dispatcher | Extracting a token leaks a bearer credential |
| Report exact error text from the CLI response | Enables support to diagnose failures |
scripts/classify-platform-permset-availability.mjsscripts/gate-unified-catalog-tiers.mjsscripts/classify-activated-agents.mjsAskUserQuestionscripts/rank-candidate-users.mjsscripts/resolve-target-user.mjsUsernameAgent_Accessscripts/classify-agent-access-state.mjsSetupEntityAccessParentIdSetupEntityIdscripts/classify-assignment-state.mjsLicenseIdneedsPsl:trueDUPLICATE_VALUEalready hasITSM Agent Runtime-Access Assignment (via service-itsm-agentic-setup-agent-runtime-access-assign)
Org: <org-alias> (API v67.0)
Target user(s): <username> (<userId>)[, ...]
Runtime action permissions:
Prompt Templates ...... <tier chosen: User | Manager | skipped | not provisioned> -> <assigned | already-had | FAILED>
Data Cloud ............ <tier chosen | skipped | not provisioned> -> <assigned | already-had | FAILED>
Unified Catalog ....... <tier chosen | skipped | not provisioned> -> <assigned | already-had | FAILED>
Agent Access permission set:
Permission set ........ <created | already existed>
Agents granted ........ <comma-separated agent names, or none>
Assigned to user(s) ... <assigned | already-had | FAILED>
Verdict: ASSIGNED | ALREADY-ASSIGNED | PARTIAL | NONE-PROVISIONED | FAILED
Reason: <plain-language explanation, or empty on success>
Next steps:
- <If ASSIGNED / ALREADY-ASSIGNED: "The user can now open and exercise the agent(s) in Agentforce Studio — action calls should no longer fail on missing permissions.">
- <If PARTIAL: list which assignments succeeded and which failed, verbatim.>
- <If NONE-PROVISIONED: nothing to assign — create/activate an agent and enable its features first.>
- <If FAILED: list the observed error(s) verbatim + remediation.>DUPLICATE_VALUE| File | When to read |
|---|---|
| Any change to the feature/tier matrix — the six platform permsets, their tiers, PSLs, and the |
| Every phase — exact |
| The input/output shapes of all seven helper scripts and how to interpret each verdict |