Salesforce ロール階層のマスター:安全なレコード共有のための完全ガイド

背景と応用シーン

Salesforce プロフェッショナルとして、私たちが日常的に直面する最も重要な課題の一つは、データのセキュリティとアクセス制御です。特に、規模の大きい組織や複雑な営業チームを抱える企業では、「誰がどのデータにアクセスできるべきか」という問いは、ビジネスの根幹に関わります。例えば、営業担当者は自分の担当する取引先や商談にのみアクセスでき、その上司である営業マネージャーはチーム全体の活動を把握するために、部下のすべてのデータにアクセスできる必要があります。さらに、リージョンを統括するディレクターや営業担当役員は、より広範なデータを俯瞰して戦略を立てる必要があります。

このような階層的なデータアクセス要件を実現するために Salesforce が提供する強力な機能が Role Hierarchy (ロール階層) です。Role Hierarchy は、組織の役職構造や指揮命令系統を Salesforce のデータ共有モデルに反映させるための基本的な仕組みです。これは、ユーザの役職に基づいて、階層の上位にいるユーザが下位にいるユーザのレコード(取引先、商談、カスタムオブジェクトなど)に自動的にアクセス権を持つように設定する機能です。

具体的な応用シーンとしては、以下のようなケースが挙げられます:

  • 営業部門: 営業担当者 < 営業マネージャー < リージョナルディレクター < 営業本部長 という階層を構築し、上位の役職者が管轄下のチーム全体のパイプラインや活動状況をリアルタイムで把握する。
  • サービス部門: サポート担当者 < サポートチームリーダー < カスタマーサービスマネージャー という階層で、マネージャーがチームメンバーの対応ケースの進捗を監視し、必要に応じてエスカレーションを管理する。
  • 多国籍企業: 国ごとの責任者が自国のデータのみにアクセスでき、グローバルの統括責任者はすべての国のデータを横断して分析する。

このように、Role Hierarchy は Salesforce のセキュリティモデルの根幹をなし、Organization-Wide Defaults (OWD) (組織の共有設定)Sharing Rules (共有ルール)、そして Manual Sharing (手動共有) といった他の共有設定と組み合わせて使用することで、きめ細かく、かつスケーラブルなデータアクセス制御を実現します。Salesforce 管理者として、この Role Hierarchy の原理を深く理解し、適切に設計・運用することは極めて重要です。


原理説明

Role Hierarchy の原理は非常にシンプルでありながら強力です。「上位のロールは、下位のロールが所有または共有されているレコードへのアクセス権を継承する」というものです。この「垂直共有」の考え方が基本となります。

まず、Salesforce のデータ共有の基本となる OWD から話を始めましょう。OWD は、各オブジェクトに対する最も厳格なアクセスレベルを定義します。「非公開 (Private)」、「公開/参照のみ (Public Read Only)」、「公開/参照・更新可能 (Public Read/Write)」などがあります。例えば、商談オブジェクトの OWD が「非公開」に設定されている場合、デフォルトではレコードの所有者とその上位の管理者しかそのレコードを閲覧できません。

ここで Role Hierarchy が登場します。OWD が「非公開」であっても、Role Hierarchy を有効にしている限り、ユーザのロール階層における上位者は、下位のユーザが所有するレコードに対してアクセス権を持ちます。このアクセス権には、参照、編集、削除、所有者の変更などが含まれます(具体的な権限は、そのユーザの Profile (プロファイル)Permission Set (権限セット) によって決まります)。

Grant Access Using Hierarchies (階層を使用したアクセス許可)

この Role Hierarchy の動作を制御する重要な設定が、共有設定画面にある Grant Access Using Hierarchies (階層を使用したアクセス許可) のチェックボックスです。

  • 標準オブジェクト: ほとんどの標準オブジェクト(取引先、商談、ケースなど)では、この設定はデフォルトで有効になっており、無効にすることはできません。これは、Salesforce の標準的なビジネスプロセスが階層的なアクセスを前提としているためです。
  • カスタムオブジェクト: カスタムオブジェクトを作成する際には、この「Grant Access Using Hierarchies」を有効にするか無効にするかを選択できます。例えば、人事評価や報酬情報といった非常に機密性の高い情報を格納するカスタムオブジェクトでは、直属の上司であっても自動的にアクセスできては困る場合があります。そのようなケースでは、このチェックボックスを意図的にオフにすることで、Role Hierarchy による自動的なアクセス権の継承を無効化できます。

重要なのは、Role Hierarchy はあくまで「垂直方向」の共有であり、「水平方向」の共有は行わないという点です。つまり、同じ階層レベルにいる営業マネージャー同士は、お互いのチームのデータにアクセスすることはできません。もしそのような部門間の共有が必要な場合は、Sharing Rules や Public Groups を使用して明示的にアクセス権を付与する必要があります。

階層構造は、[設定] > [ユーザ] > [ロール] から視覚的に設定・確認できます。ツリー構造で表示され、ドラッグアンドドロップで簡単にロールの親子関係を変更できます。


サンプルコード

Role Hierarchy は主に宣言的な設定(クリック操作による設定)で構築しますが、Apex や SOQL を使用して階層情報をプログラムで取得・操作することも可能です。これにより、動的な承認プロセスの割り当てや、カスタムコンポーネントでの階層に基づいたデータ表示などが実現できます。

以下に、Salesforce の UserRole オブジェクトを照会して、組織のロール階層構造を取得するための SOQL クエリの例を示します。これは developer.salesforce.com の公式ドキュメントで解説されているオブジェクトとフィールドに基づいています。

ロール階層の全ノードを取得する

このクエリは、組織内に定義されているすべてのロールとその親ロールの ID を取得します。これにより、ロール間の親子関係を把握できます。

// 組織内の全てのロールを取得し、その名前、ID、および親ロールのIDを問い合わせる
// ParentRoleId は、このロールが階層内でどのロールの直下にあるかを示す
// このフィールドが null の場合、そのロールは階層の最上位に位置することを示す
SELECT Name, Id, ParentRoleId 
FROM UserRole 
ORDER BY Name

特定のロール配下にあるすべての下位ロールを再帰的に取得する

より実践的な例として、特定のマネージャーロール(例:'VP of Sales')を指定し、その配下にあるすべての子・孫ロールを取得する Apex コードを示します。

public class RoleHierarchyUtil {
    
    // 特定のロールIDを基点として、その配下にある全ての下位ロールのIDを Set 形式で返すメソッド
    public static Set<Id> getSubordinateRoleIds(Id roleId) {
        
        // 取得したロールIDを格納するための Set を初期化
        Set<Id> subordinateRoleIds = new Set<Id>();
        subordinateRoleIds.add(roleId); // まず基点となるロールID自体を追加
        
        // 直下の子ロールを格納するための Set を準備
        Set<Id> childRoleIds = new Set<Id>();
        childRoleIds.add(roleId);

        // 子ロールが存在しなくなるまでループを繰り返す
        while (true) {
            // 現在の子ロールIDリストを親として持つロールを全て取得する
            List<UserRole> roles = [SELECT Id FROM UserRole WHERE ParentRoleId IN :childRoleIds];
            
            // これ以上下位のロールが見つからなければループを抜ける
            if (roles.isEmpty()) {
                break;
            }

            // 新しい子ロールのIDを格納するために Set をクリア
            childRoleIds.clear();

            // 見つかった下位ロールをループ処理
            for (UserRole r : roles) {
                // まだ subordinateRoleIds に追加されていないロールであれば追加する
                if (!subordinateRoleIds.contains(r.Id)) {
                    subordinateRoleIds.add(r.Id);
                    childRoleIds.add(r.Id);
                }
            }
        }
        
        return subordinateRoleIds;
    }
}

// 実行例:
// 1. まず基点となるロールのIDを取得する
// UserRole vpRole = [SELECT Id FROM UserRole WHERE Name = 'VP of Sales' LIMIT 1];
// 2. メソッドを呼び出して、配下の全ロールIDを取得する
// Set allRoleIds = RoleHierarchyUtil.getSubordinateRoleIds(vpRole.Id);
// 3. 取得したロールIDに属するユーザのレコードなどをクエリできる
// List teamOpps = [SELECT Id, Name FROM Opportunity WHERE Owner.UserRoleId IN :allRoleIds];

このコードは、指定されたロールIDを起点に、SOQLクエリをループ内で繰り返し実行して、階層を一段ずつ下っていきます。最終的に、起点となったロールとその配下にあるすべてのロールのIDを含むSetを返します。これにより、「VP of Sales」チーム全体の商談を取得する、といった複雑なクエリを簡潔に記述できます。


注意事項

Role Hierarchy は非常に便利な機能ですが、設計・運用にあたってはいくつかの注意点があります。

  1. パフォーマンスへの影響: ロール階層が非常に深い(例:10階層以上)または広い(一つのロール配下に多数のロールが存在する)場合、レコード共有の再計算に時間がかかり、パフォーマンスに影響を与える可能性があります。特に、所有者の変更、ロールの変更、共有ルールの変更などが発生した際に、共有テーブルの更新が遅延することがあります。これは Ownership SkewRole Hierarchy Skew と呼ばれる問題につながる可能性があります。
  2. ロールは「データアクセス」のため、プロファイルは「機能権限」のため: これは Salesforce の基本原則です。Role Hierarchy は「どのレコードが見えるか」を定義し、Profile や Permission Set は「そのレコードに対して何ができるか(参照、作成、編集、削除)」を定義します。この二つを混同しないように設計することが重要です。役職が同じでも、職務内容が異なる場合は、同じロールを割り当て、異なるプロファイルや権限セットを割り当てるべきです。
  3. HR 組織図との違い: Role Hierarchy は、必ずしも人事部門が管理する組織図と完全に一致させる必要はありません。重要なのは「データアクセスの階層」です。例えば、プロジェクトベースで他部署のメンバーを一時的に管理するマネージャーがいる場合、そのデータアクセス要件を Role Hierarchy で実現しようとすると複雑になります。このような場合は、Public Groups や共有ルールを利用する方が柔軟に対応できます。
  4. 共有の再計算: ユーザを新しいロールに割り当てたり、ロール階層の構造を変更したりすると、Salesforce はバックグラウンドで共有の再計算を実行します。データ量が多い組織では、この処理に数分から数時間かかることがあります。変更が完全に反映されるまでタイムラグがあることをユーザに周知しておく必要があります。
  5. API とガバナ制限: 前述の Apex コード例のように、プログラムでロール階層を扱う場合、SOQL クエリのガバナ制限(1トランザクションあたり100回など)に注意が必要です。深い階層を処理する際は、ループ内でのクエリ発行回数が制限を超えないように設計する必要があります。

まとめとベストプラクティス

Role Hierarchy は、Salesforce の共有とセキュリティモデルの基礎となる、強力で不可欠な機能です。組織の階層構造に基づいて、直感的かつ自動的にデータへのアクセス権を付与することができます。

Salesforce 管理者として Role Hierarchy を最大限に活用するためのベストプラクティスは以下の通りです。

  • 現実のアクセス要件をモデル化する:

    人事組織図をそのままコピーするのではなく、実際のデータアクセス要件に基づいた階層を設計します。誰が誰のデータを見る必要があるのか、という観点から構築しましょう。
  • 階層をフラットに保つ:

    パフォーマンスを最適化し、管理を容易にするため、可能な限りロール階層を浅く、シンプルに保つことを目指します。複雑なマトリックス型の共有要件には、共有ルールやテリトリー管理など、他の機能の利用を検討します。
  • 一人のユーザに一つのロール:

    一人のユーザは一つのロールにしか所属できません。複数の役割を兼務するユーザのアクセス権は、ロールに加えて権限セットや共有ルールで補完することを検討してください。
  • 定期的な見直し:

    組織の成長や変化に伴い、Role Hierarchy が現状にそぐわなくなることがあります。四半期に一度など、定期的に階層構造がビジネス要件と一致しているかを確認し、必要に応じてメンテナンスを行いましょう。
  • 他の共有機能との組み合わせ:

    Role Hierarchy は万能ではありません。OWD を基本とし、Role Hierarchy で垂直方向の共有を、Sharing Rules や Public Groups で水平方向や例外的な共有を、Manual Sharing で一時的な共有を行う、というように、各機能の特性を理解し、組み合わせて使用することで、堅牢で柔軟なセキュリティモデルを構築できます。

以上の点を踏まえ、慎重に Role Hierarchy を設計・運用することで、Salesforce 内のデータを安全に保ちながら、ビジネスの効率を最大化することが可能になります。

コメント