
はじめに
こんにちは。システム企画部のOです。
前回の記事では、権限管理の「個別最適」が招くブラックボックス化の問題と、まずはプロファイルから着手した現状の可視化についてお話ししました。 creators.bengo4.com
権限整理を進める中で、次なる大きな壁として立ちはだかったのが「権限セット」です。「とりあえず付与」を繰り返した結果、1人のユーザーに10個以上の権限セットがついているなんてことも...
今回は、増えすぎてしまった権限セットの実態を正確に把握するために、データローダ*1とスプレッドシートを使って「権限セットマトリックス」を作成した際の手順をご紹介します。
- はじめに
- 1. 効率的な調査のために、まずおさえておきたい「3つのオブジェクト」
- 2. 私が行ったデータ抽出のステップ
- 3. スプレッドシートで「権限マトリックス」を作成
- 4. 「残すべき権限」の判断基準
- 5. 特定の「カスタム権限」を含むセットを特定する方法
- 6. 「断捨離」の進め方
- おわりに
1. 効率的な調査のために、まずおさえておきたい「3つのオブジェクト」
Salesforceの画面上で一人ひとりの設定を確認するのは時間がかかるため、今回はデータローダを使用し、SOQL*2を実行して一括でデータを取得することにしました。 今回の棚卸しにおいて、鍵となったのは以下の3つのオブジェクトです。
| オブジェクト名 | 役割 | 私が抽出した目的 |
|---|---|---|
| PermissionSet | 権限セットの定義 | 名前やラベルの確認、プロファイル由来かの判別 |
| PermissionSetAssignment | ユーザーへの割り当て | 「誰に」「どの権限」が付与されているかの紐付け |
| User | ユーザー情報 | IDを「ユーザー名」や「部署」に変換するため |
2. 私が行ったデータ抽出のステップ
データローダを起動し、以下の手順でSOQLを実行してCSVを書き出していきました。
①:権限セットの「マスタ」を取得
SOQL例: > SELECT Id, Name, Label, LicenseId, IsOwnedByProfile, CreatedDate, Description FROM PermissionSet WHERE IsOwnedByProfile = FALSE
補足: IsOwnedByProfile = FALSE でフィルタをかけることで、プロファイル由来のデータを除外し、純粋な「権限セット」のみを抽出できます。
②:「割り当て状況」を取得(メインデータ)
SOQL例: > SELECT Id, AssigneeId, PermissionSetId FROM PermissionSetAssignment
補足: このオブジェクトには IsActive 項目はありません。無効ユーザーへの割り当てを除外したい場合は、後ほどスプレッドシート上で「ユーザーマスタ」と突合してフィルタリングするのがスムーズです。
③:照合用の「ユーザーリスト」を取得
SOQL例: SELECT Id, Name, Department, IsActive FROM User
3. スプレッドシートで「権限マトリックス」を作成
抽出したデータをスプレッドシートで突合させ、「誰が何を持っているか」を俯瞰できるように整理しました。
①:IDを名前に変換
「PermissionSetAssignment」シートをベースに、 AssigneeId(ユーザーID)をキーにして「User」シートの Name を、 PermissionSetId(権限セットID)をキーにして「PermissionSet」シートの Label を、それぞれ XLOOKUP 関数で紐付けて表示させます。
②:ピボットテーブルで「マトリックス図」を作成
全体像を把握しやすくするため、ピボットテーブルで「十字表」を作成しました。
行:
Department(所属部署)、Name(ユーザー名)列:
Label(権限セット名)値:
AssigneeId(割り当てID)- 集計方法を「合計」ではなく「個数」に設定します。これにより、権限を持っている箇所に「1」が立ち、マトリックスとして機能します。
値が入っているセルに「条件付き書式」で色を付けると、部署ごとの権限付与の傾向が明確になります。
補足:内部ID「00e」の正体
作業中、IDが「00e」から始まるレコードが混ざっていることに気づきました。Salesforceの内部構造では、プロファイルも1つの権限セットとして管理されているため、プロファイルID(接頭辞 00e)が表示されます。前述の通り IsOwnedByProfile で除外するか、IDの先頭3桁を見てフィルタリングするとリストがスッキリします。
4. 「残すべき権限」の判断基準
マトリックスが完成した後は、いよいよ「削除候補」の仕分けです。私は以下の5つの基準を参考に、「今はまだ必要」なものを判断していきました。
鮮度: 作成日が直近(2024〜2026年)で、現在の運用に関わっているもの
利用頻度: 定期的に付与依頼が発生しているもの
システム由来: 作成者が salesforce.com, inc. など、標準機能のために自動生成されたもの
構造化済み: 「権限セットグループ」に組み込まれて活用されているもの
特殊機能: 「カスタム権限」が含まれており、特定の機能制御に使われているもの
5. 特定の「カスタム権限」を含むセットを特定する方法
カスタム権限とは?
標準の「編集」「削除」といった権限ではなく、フロー、Apex(プログラム)、数式などで「特定のボタンをこの人にだけ見せる」「独自の業務ロジックを動かす」といった独自の制御を行うためのフラグです。 カスタム権限を含む権限セットを削除すると、それに関連付けられた入力規則やApex、Lightningページの表示制御が予期せず無効化され、業務停止やデータ不整合を招く恐れがあります。
今回の調査で「これ、どうすればいいんだろう?」と手が止まったのが、「カスタム権限を含む権限セット」を一括で特定する方法でした。
権限セットとカスタム権限の紐付けは SetupEntityAccess というオブジェクトで管理されていることを知り、以下の手順で抽出しました。
①:紐付けリストを抽出(SetupEntityAccess)
まず、どの権限セットに、何のカスタム機能が紐付いているかの「中間データ」を取得します。
- オブジェクト: SetupEntityAccess
- SOQL例:
SELECT ParentId, SetupEntityId FROM SetupEntityAccess WHERE SetupEntityType = 'CustomPermission' - 補足:
ParentIdは権限セットのID、SetupEntityIdはカスタム権限自体のIDを指します。
②:カスタム権限の「名前」リストを抽出(CustomPermission)
次に、IDだけでは中身がわからないため、カスタム権限のマスターリストを取得します。
- オブジェクト: CustomPermission
- SOQL例:
SELECT Id, MasterLabel FROM CustomPermission
③:マスタデータとの紐付け
「SetupEntityAccess」シートの SetupEntityId をキーにして、「CustomPermission」シートから MasterLabel を紐付ければ、どの権限セットが重要なカスタムロジックを握っているか一目瞭然です。
6. 「断捨離」の進め方
可視化が完了した後は、いよいよ実践です。すべてを一気に削除するのはリスクがあるため、現在はチーム内で以下のステップを踏んで着実に整理を進めています。
- まずは判断しやすいところから着手
- 「利用者が0人のもの」や「無効ユーザーだけに付与されているもの」など、明らかに不要なものを優先的に削除
- 利用者がいる場合の慎重なプロセス
- いきなり削除はせず、まずはユーザーの割り当てを解除
- 一定期間、現場から不具合の連絡がないか「確認期間」を設ける
- 業務に支障がないことを確かめた上で、最終的な削除を行う
- 現場の責任者と協力して標準化へ
- 権限セットが5つ以上付与されているユーザーと所属部署を抽出し、責任者に要否を整理してもらう
- バラバラだった権限を「権限セットグループ」に集約し、スッキリした運用へ移行
おわりに
今後はこの棚卸しを一度きりで終わらせず、定期的な手順として仕組み化していく方針です。
「もっと楽な方法があるかも……」と試行錯誤しながらも、現時点での最適解としてこの形にまとめました。まだ改善の余地はあるかと思いますので、より効率的な手法があれば柔軟に取り入れていきたいと考えています。
同じように権限整理で悩む方にとって、この記事が少しでも参考になれば嬉しいです。最後までお付き合いいただき、ありがとうございました!