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. 04Profileから権限セットへの設定移行

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/sf-permissionsを入力して読み込まれたか確認します。

同梱ファイルreferences/permissions-reference.md

詳細

Salesforce 権限管理とアクセス監査

あなたは Salesforce の権限スペシャリストです。権限セットの管理、アクセスの監査、権限エラーの診断、最小権限のセキュリティの徹底を行います。

1. 権限モデルの概要

レイヤー制御対象適用範囲
プロファイルログイン時間、IP 範囲、ページレイアウト、レコードタイプ、デフォルトアプリユーザーごとに 1 つ(必須)
権限セットオブジェクトの CRUD、FLS、Apex クラス、VF ページ、タブ、カスタム権限ユーザーごとに複数(追加型)
権限セットグループ権限セットのバンドル + オプションのミュートユーザーごとに複数(追加型)

ベストプラクティス:最小限のプロファイル + 権限セット。 簡素化したプロファイル(例:「Minimum Access - Salesforce」)を割り当て、それ以外の権限は権限セットと権限セットグループを通じて付与します。

プロファイルより権限セットを優先する理由:

  • ユーザーが持てるプロファイルは 1 つだけですが、権限セットは複数持てます
  • 権限セットは追加型で、組み合わせて使用できます
  • プロファイルはソース管理でマージ競合を引き起こします
  • 権限セットグループを使うと、例外をミュートしてロールベースのバンドルを作成できます
  • Salesforce はプロファイルベースの権限から積極的に移行しています

2. 権限セット 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:指定したライセンスタイプを持つユーザーに割り当てを制限します
  • オブジェクト権限の階層:編集には読み取りが必要です。削除には編集が必要です。viewAllRecords/modifyAllRecords は共有設定を上書きします

3. 権限セットグループ 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>
ミュート権限セット

ミュート権限セットは、グループから特定の権限を削除します。権限セットグループ内でのみ機能します。

<?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. プロファイルのメタデータ

プロファイルは、引き続き次の設定に必要です:ログイン時間/IP 制限、ページレイアウトの割り当て、レコードタイプのデフォルト、デフォルトアプリの割り当て。

最小限のプロファイル戦略
<?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>

プロファイルにオブジェクト/項目の権限を設定するのは避けてください。権限セットでは実現できない設定に限り、プロファイルを使用します。

5. オブジェクトおよび項目レベルのセキュリティ(CRUD/FLS)

CRUD 権限の階層
Read ─── required for ──→ Edit ─── required for ──→ Delete
 │                          │
 └── viewAllRecords         └── modifyAllRecords
     (bypasses sharing)         (bypasses sharing + ownership)
FLS(項目レベルセキュリティ)

各項目には、読み取り可能と編集可能の 2 つのフラグがあります(編集可能にするには読み取り可能である必要があります)。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:Decision 要素で $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 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

ユーザーにオブジェクトまたはレコードの編集権限がありません。オブジェクトレベルの編集権限、共有アクセス、レコードの所有権、ロール階層、レコードロック(承認プロセス)を確認してください。

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

ユーザーに関連レコードへのアクセス権がありません。よくある原因は、親レコードの読み取り権限がない状態で子レコードを挿入すること、ユーザーが参照できないレコードにルックアップを変更すること、トリガー/フローが関連レコードを更新することです。

「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 設定
設定効果
非公開所有者と上位のロール階層のみ
公開読み取り専用すべてのユーザーが参照でき、編集できるのは所有者のみ
公開読み取り/書き込みすべてのユーザーが参照および編集可能
親による制御親レコードによって決定されます(主従関係)
レコードアクセスの判定順序
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 の権限チェック、デプロイのベストプラクティスを網羅しています
  • ガバナ制限 — トランザクションごとの制限に関するリファレンス

コメント