mcpField
S
sf-permissions

sf-permissions

github.com/clientell-ai安全2099 次安装32 周前更新
代码仓库

关于 sf-permissions

sf-permissions 是 Salesforce 权限管理与访问审计技能,面向配置权限集、检查用户访问和排查权限错误的人员。它涵盖权限集组、字段级安全、共享规则及相关查询与部署流程。

主要功能

  1. 01生成权限集和权限集组元数据
  2. 02审计用户及对象访问
  3. 03检查字段级安全设置
  4. 04诊断权限错误与记录访问
  5. 05管理自定义权限和静默权限集
  6. 06提供部署与分配命令

适用场景

  1. 01为新功能配置最小权限访问
  2. 02排查用户无法编辑记录的问题
  3. 03审计哪些用户可访问对象或 Apex 类
  4. 04将配置从 Profile 迁移到权限集

安装

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

$npx skills add https://github.com/clientell-ai/salesforce-skills --skill sf-permissions

安装后在 Claude Code 中输入/sf-permissions确认已加载。

附带文件references/permissions-reference.md

详细介绍

Salesforce 权限管理与访问审计

你是 Salesforce 权限专家。管理权限集、审计访问权限、诊断权限错误,并落实最小权限安全原则。

1. 权限模型概览

层级控制内容范围
Profiles登录时间、IP 范围、页面布局、记录类型、默认应用每位用户一个(必需)
Permission Sets对象 CRUD、FLS、Apex 类、VF 页面、选项卡、自定义权限每位用户可有多个(累加)
Permission Set GroupsPermission Sets 组合包 + 可选的静默权限每位用户可有多个(累加)

最佳实践:精简 Profile + Permission Sets。 为用户分配精简的 Profile(例如,“Minimum Access - Salesforce”),并通过 Permission Sets 和 Permission Set Groups 授予其他所有权限。

为何优先使用 Permission Sets,而非 Profiles:

  • 用户只能拥有一个 Profile,但可以拥有多个 Permission Set
  • Permission Sets 可累加且可组合
  • Profiles 会导致源代码管理中的合并冲突
  • Permission Set Groups 支持按角色打包权限,并可通过静默权限处理例外情况
  • Salesforce 正在积极转向不再基于 Profile 管理权限

2. Permission Set XML(SFDX 源格式)


<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Order Manager</label>
    <description>Full CRUD on Order__c, read on Account</description>
    <hasActivationRequired>false</hasActivationRequired>
    <license>Salesforce</license>
    <objectPermissions>
        <object>Order__c</object>
        <allowCreate>true</allowCreate>
        <allowDelete>false</allowDelete>
        <allowEdit>true</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <viewAllRecords>true</viewAllRecords>
    </objectPermissions>
    <fieldPermissions>
        <field>Order__c.Amount__c</field>
        <editable>true</editable>
        <readable>true</readable>
    </fieldPermissions>
    <tabSettings>
        <tab>Order__c</tab>
        <visibility>Visible</visibility>
    </tabSettings>
    <classAccesses>
        <apexClass>OrderService</apexClass>
        <enabled>true</enabled>
    </classAccesses>
    <pageAccesses>
        <apexPage>OrderEntryPage</apexPage>
        <enabled>true</enabled>
    </pageAccesses>
    <customPermissions>
        <name>Bypass_Validation</name>
        <enabled>true</enabled>
    </customPermissions>
    <userPermissions>
        <name>RunReports</name>
        <enabled>true</enabled>
    </userPermissions>
</PermissionSet>
  • hasActivationRequired:为 true 时,必须在会话中激活后才能生效
  • license:限制只能分配给具有相应许可证类型的用户
  • 对象权限层级:Edit 需要 Read;Delete 需要 Edit;viewAllRecords/modifyAllRecords 可覆盖共享设置

3. Permission Set Group XML


<?xml version="1.0" encoding="UTF-8"?>
<PermissionSetGroup xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Sales Team</label>
    <description>All permissions needed by sales reps</description>
    <status>Updated</status>
    <permissionSets>
        <permissionSet>Account_Reader</permissionSet>
        <permissionSet>Opportunity_Manager</permissionSet>
        <permissionSet>Report_Viewer</permissionSet>
    </permissionSets>
    <mutingPermissionSet>Sales_Team_Muting</mutingPermissionSet>
</PermissionSetGroup>
静默权限集

静默权限集会从组中移除特定权限。它只能在 Permission Set Group 中使用。

<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Sales Team Muting</label>
    <description>Removes delete access granted by Opportunity_Manager</description>
    <objectPermissions>
        <object>Opportunity</object>
        <allowDelete>true</allowDelete>
        
    </objectPermissions>
</PermissionSet>

静默权限仅对通过此组获得访问权限的用户撤销。直接分配的权限不受影响。

4. Profile 元数据

以下场景仍需要 Profiles:登录时间/IP 限制、页面布局分配、记录类型默认值、默认应用分配。

精简 Profile 策略
<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <custom>true</custom>
    <description>Minimal profile - all access via Permission Sets</description>
    <userLicense>Salesforce</userLicense>
    <loginHours>
        <mondayStart>480</mondayStart>
        <mondayEnd>1080</mondayEnd>
    </loginHours>
    <layoutAssignments>
        <layout>Account-Account Layout</layout>
    </layoutAssignments>
</Profile>

避免在 Profiles 中设置对象/字段权限。Profile 仅用于无法通过 Permission Sets 实现的功能。

5. 对象与字段级安全性(CRUD/FLS)

CRUD 权限层级
Read ─── required for ──→ Edit ─── required for ──→ Delete
 │                          │
 └── viewAllRecords         └── modifyAllRecords
     (bypasses sharing)         (bypasses sharing + ownership)
FLS(字段级安全性)

每个字段有两个标志:可读和可编辑(可编辑需要可读)。FLS 适用于 UI、报表、列表视图和 API。被 FLS 隐藏的字段在使用 WITH USER_MODE 的 SOQL 中会返回 null。

FLS 审计查询
-- Field permissions for a permission set
SELECT SobjectType, Field, PermissionsRead, PermissionsEdit
FROM FieldPermissions WHERE Parent.Name = 'Order_Manager'

-- Fields a user can edit (across all permission sets)
SELECT SobjectType, Field, PermissionsRead, PermissionsEdit
FROM FieldPermissions WHERE ParentId IN (
    SELECT PermissionSetId FROM PermissionSetAssignment
    WHERE AssigneeId = '005xx000001234AAA'
)

-- Who can edit a sensitive field?
SELECT Parent.Label, Parent.IsOwnedByProfile
FROM FieldPermissions
WHERE Field = 'Contact.SSN__c' AND PermissionsEdit = true

6. 自定义权限

自定义权限是布尔标志,可用于控制功能访问,而无需修改代码。


<?xml version="1.0" encoding="UTF-8"?>
<CustomPermission xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Can Export Data</label>
    <description>Allows user to export data from custom UI</description>
    <isLicensed>false</isLicensed>
</CustomPermission>

Apex(首选):

if (FeatureManagement.checkPermission('Can_Export_Data')) {
    // user has the custom permission
}

LWC:

import hasExportPermission from '@salesforce/customPermission/Can_Export_Data';

Flow:在决策元素中使用 $Permission.Can_Export_Data(返回 true/false)。

7. 访问审计

PermissionSetAssignment 查询
-- All users assigned a permission set
SELECT Assignee.Name, Assignee.Username, Assignee.IsActive
FROM PermissionSetAssignment WHERE PermissionSet.Name = 'Order_Manager'

-- All permission sets for a user (excluding profile-based)
SELECT PermissionSet.Label, PermissionSet.Name, PermissionSetGroupId
FROM PermissionSetAssignment
WHERE AssigneeId = '005xx000001234AAA'
AND PermissionSet.IsOwnedByProfile = false
ObjectPermissions 查询
-- Who has Delete on an object?
SELECT Parent.Label, Parent.IsOwnedByProfile,
       PermissionsDelete, PermissionsViewAllRecords, PermissionsModifyAllRecords
FROM ObjectPermissions
WHERE SobjectType = 'Account' AND PermissionsDelete = true

-- Over-privileged check: ModifyAll on any object
SELECT Parent.Label, SobjectType FROM ObjectPermissions
WHERE PermissionsModifyAllRecords = true AND Parent.IsOwnedByProfile = false
SetupEntityAccess(Apex/VF/Connected App)
-- Who has access to an Apex class?
SELECT Parent.Label FROM SetupEntityAccess
WHERE SetupEntityType = 'ApexClass'
AND SetupEntityId IN (SELECT Id FROM ApexClass WHERE Name = 'OrderService')

-- Connected App access
SELECT Parent.Label FROM SetupEntityAccess
WHERE SetupEntityType = 'ConnectedApplication'
AND SetupEntityId IN (SELECT Id FROM ConnectedApplication WHERE Name = 'DataLoader')
Permission Set Group 成员资格
-- Permission sets in a group
SELECT PermissionSetGroup.MasterLabel, PermissionSet.Label
FROM PermissionSetGroupComponent
WHERE PermissionSetGroup.MasterLabel = 'Sales Team'

-- Groups containing a permission set
SELECT PermissionSetGroup.MasterLabel FROM PermissionSetGroupComponent
WHERE PermissionSet.Name = 'Opportunity_Manager'

8. 权限问题排查

INSUFFICIENT_ACCESS_OR_READONLY

用户缺少对象或记录的 Edit 权限。检查对象级 Edit 权限、共享访问权限、记录所有权、角色层级,以及记录锁定状态(审批流程)。

SELECT Parent.Label FROM ObjectPermissions
WHERE SobjectType = 'TargetObject__c' AND PermissionsEdit = true
AND ParentId IN (
    SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId = :userId
)
INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY

用户无权访问某条关联记录。常见原因:插入子记录时缺少对父记录的 Read 权限;将查找关系更改为用户无法查看的记录;触发器/Flow 更新了关联记录。

“Insufficient Privileges”错误

通用错误,表示可能缺少以下任一权限:Apex 类访问权限、VF 页面访问权限、Lightning 组件访问权限、选项卡可见性、Connected App 访问权限,或未激活基于会话的权限集。

# Quick CLI diagnosis
sf data query -q "SELECT PermissionSet.Label, PermissionSet.Name \
  FROM PermissionSetAssignment \
  WHERE Assignee.Username = '[email protected]' \
  AND PermissionSet.IsOwnedByProfile = false" --target-org myOrg

9. 共享与权限

权限(CRUD/FLS)和共享是相互独立的层:

层问题范围
CRUD用户能否创建/读取/编辑/删除此对象类型?整个对象
FLS用户能否查看/编辑此特定字段?整个字段
共享用户能访问哪些特定记录?记录级别

用户必须同时具备相应的 CRUD/FLS 权限和共享访问权限。

OWD 设置
设置效果
Private仅所有者及其上级角色可访问
Public Read Only所有用户均可读取,只有所有者可以编辑
Public Read/Write所有用户均可读取和编辑
Controlled by Parent由父记录决定(主从关系)
记录访问权限判定顺序
1. Record owner? → Full access
2. Above owner in role hierarchy? → Access per OWD
3. Sharing rules? → Read or Read/Write
4. Apex managed sharing? → Read or Read/Write
5. View All / Modify All on object? → Bypasses sharing
6. View All Data / Modify All Data? → Full access
关键区别
  • viewAllRecords/modifyAllRecords 会绕过该对象的共享规则
  • Apex 中的 with sharing 会强制执行共享规则,但不会强制执行 CRUD/FLS
  • SOQL 中的 WITH USER_MODE 会同时强制执行共享规则和 CRUD/FLS

10. 注意事项

  • 权限集组会异步重新计算 — 变更可能需要几分钟才生效。检查 PermissionSetGroup.Status,确认其状态为 Updated 而非 Outdated。
  • 配置文件会导致合并冲突 — 配置文件 XML 文件非常庞大,且条目顺序可能以非确定性方式变化。优先使用权限集。
  • FLS 默认不会限制 API 访问 — Apex 以系统模式运行。请使用 WITH USER_MODE 或 Security.stripInaccessible()。
  • 自定义权限会被缓存 — 分配变更可能要等用户重新进行身份验证后才会生效。
  • 权限屏蔽集仅在组内有效 — 直接分配给用户不会产生任何效果。
  • 权限集许可证 — 有些权限集需要特定许可证。将其分配给没有相应许可证的用户时,可能会静默失败。
  • 基于会话的权限集 — hasActivationRequired=true 需要通过 Flow 或 SessionPermSetActivation 激活,不会自动激活。
  • viewAllRecords 不会授予字段访问权限 — 用户可以看到记录,但无法看到受 FLS 限制的字段(在强制执行 FLS 时)。
  • IsOwnedByProfile — 每个配置文件都有一个隐藏权限集。查询时使用 PermissionSet.IsOwnedByProfile = false 进行筛选。
  • 分配数量限制 — 每位用户最多可分配 1,000 个权限集(包括通过组分配的权限集)。

11. 工作流

为新功能设置权限
  1. 确定所需访问权限:列出对象、字段、Apex 类、VF 页面、选项卡和自定义权限。
  2. 创建权限集:生成 .permissionset-meta.xml,并遵循最小权限原则。
  3. 创建自定义权限(如有需要):为功能开关生成 .customPermission-meta.xml。
  4. 添加到权限集组(如适用):更新 .permissionsetgroup-meta.xml。
  5. 创建权限屏蔽集(如有需要):仅当组授予某些用户过多权限时才创建。
  6. 部署:
    sf project deploy start -d force-app/main/default/permissionsets \
      -d force-app/main/default/permissionsetgroups \
      -d force-app/main/default/customPermissions --target-org myOrg
    
  7. 分配:
    sf org assign permset --name Order_Manager --target-org myOrg
    sf org assign permsetgroup --name Sales_Team --target-org myOrg
    
  8. 审计:
    sf data query -q "SELECT Assignee.Name, PermissionSet.Label \
      FROM PermissionSetAssignment \
      WHERE PermissionSet.Name = 'Order_Manager'" --target-org myOrg
    
从配置文件迁移到权限集
  1. 查询配置文件上所有非默认权限
  2. 为每个功能领域创建对应的权限集
  3. 创建一个与该配置文件角色相匹配的权限集组
  4. 将该组分配给受影响的用户
  5. 从配置文件中移除权限(仅保留布局、记录类型和登录时间)
  6. 使用第 7 节中的审计查询进行验证

参考资料

  • 权限参考 — 完整的权限集 XML、审计查询、Apex/LWC/Flow 权限检查以及部署最佳实践
  • 治理限制 — 每笔事务的限制参考

评论

支持 Markdown