Salesforce Experience Cloudの初心者が「Salesforce Experience Cloudデータ セキュリティ ルール ブック」を読んで解説してみた
こんにちは、遠藤です。
「ゆるっとSalesforce #23」では「Experience Cloud権限設定入門」と銘打って「Salesforce Experience Cloudデータ セキュリティ ルール ブック」の読み合わせを行いました。
この「Salesforce Experience Cloudデータ セキュリティ ルール ブック」については、Dreamforce '23のセッション「Best Practices for Data Security in Experience Cloud」にて著者のSavio Joseさん自身が発表しています。
このルールブックではExperience Cloud上でデータをセキュアに公開するための12のルールとしてまとめています。
以下、日本語にわかりやすく訳してみました。
イベントでは、時間の関係で各ルールについての詳細は話せませんでしたが、以下ひとつひとつ解説していきます。
基本的に原文を読まなくても雰囲気をつかめるようにまとめているつもりですが、足りないところは元記事も参照してみてください。
また、Experience Cloudの権限設定について馴染みのない方は、Trailheadモジュール「パートナーとの CRM データの共有 | Salesforce Trailhead」を一度試しておくと良いかと思います。
ルール1: 細かく役割ごとのペルソナを定義する
原文のCapabilityを日本語に訳するのが難しいですが、まずは実装に入る前に「サイトの利用者のペルソナ(役割)を定義し、ペルソナごとに必要な機能を洗い出す。」ということかと思います。
ペルソナとそれが利用する機能を整理することによって、実装ではそれらを権限セットにマッピングしていくことになると思われます。
原文ではルール3で取り上げていますが、この分析に基づいて以下のように整理します。
ルール2: ゲストユーザーアクセスを精査する
つまり、ゲストユーザーが必要だった場合は、ゲストユーザの権限はより気をつけて設計しなければならないという話です。
ここ数年、ゲストユーザーの権限を制限する機能が次々とリリースされセキュリティが強化されてきました。
ゲストユーザーの権限を制限する各機能についてはヘルプの「ゲストユーザーのセキュリティポリシーとタイムライン」にまとまっています。こちらのドキュメントは一度は目を通しておくと良さそうです。
その中からルールブックでは以下の機能をピックアップしています
ゲストユーザーはレコードの所有者にはなれない
共有ルールによってゲストユーザーに付与できる最大の権限は「参照」アクセス権
オブジェクト権限「すべて表示」および「すべて変更」を付与することができない
オブジェクト権限「編集」、「削除」を付与することができない
「公開グループ」「キュー」のメンバーにはなれない
ゲストユーザーによるフローの実行はサポートされなくなった
Winter '21 より前に作成したSalesforce組織の場合、ゲストユーザーのセキュリティ強化がデフォルトでは無効なので改めてレビューする必要があります。
以下、セキュリティ強化機能のなかからいくつかを画面で確認してみましょう。
共有ルールによってゲストユーザーに付与できる最大の権限は参照アクセス権
ゲストユーザーの共有ルールの設定は、「共有設定」の各オブジェクト設定で「ルールタイプ」「条件に基づくゲストユーザーアクセス」を選択します。
「ルールタイプ」「条件に基づくゲストユーザーアクセス」を選択した場合、選択可能な権限は確かに「参照のみ」となっています。
参照
オブジェクト権限「編集」、「削除」、「すべて表示」および「すべて変更」を付与することができない
ゲストユーザープロファイルは以下の手順で開くことができます。
1. ワークスペースの「ビルダー」を開き設定アイコンをクリック
2. 「<サイト名>プロファイル」をクリック
以下、ゲストユーザープロファイルのオブジェクト権限の設定です。
設定可能なのは、「参照」と「作成」のみとなっています。
では、ゲストユーザーがレコードを更新または削除可能するユースケースが必要な場合にどうするかというと、システムモードで実装します。詳しくはルール12を参照ください。
参照: ゲストユーザープロファイルの設定
「Authenticated and Guest User Access Report and Monitoring」アプリを活用する
記事中で紹介されているSalesforce Labアプリの「Authenticated and Guest User Access Report and Monitoring」を使って、ゲストユーザーのアクセス権の変更をプロアクティブに監視することができるそうです。
こちらのアプリはヘルプでも紹介されています。
参照: ゲストユーザーが使用可能なレコードの検出
使い方は、アプリをインストールした後に、チェックしたいユーザーにVisualforce「uar.UserAccessReport」とそのApexコントローラー「uar.UserAccessReportController」の権限を付与します。
ゲストユーザーでチェックしたい場合はゲストユーザープロファイルに付与する必要があります。
権限を付与したらコミュニティのURLにパス「/apex/uar__useraccessreport」を付けて開きます。
例: https://sea-goldengate-1955-dev-ed.scratch.my.site.com/UrsaMajor/apex/uar__useraccessreport
以下実際にゲストユーザーで出力したレポートになります。
このアプリの使い方については Authenticated and Guest User Access Report and Monitoring | George Abboud | Substack に詳しい説明がありますので、実際に運用する際はこちらのドキュメントを読む必要がありそうです。
サイトはページごとに公開する
こちらは、読んでいただいたとおりですが、ゲストユーザーへの公開はサイト単位ではなくなるべくページ単位にしましょうという話です。
個別ページの公開を設定するには、サイトの「ビルダー」 の上部のページのプルダウンからページの「ページの設定」を開きます。
「プロパティ」タブの「ページアクセス」で「公開」選択します。
サイト全体の公開設定は、サイトの「ビルダー」 の「設定」を開き「全般」にあります。
ゲストユーザー用のページまたはコンポーネントのオーディエンス バリエーションを活用する
サイトのページまたはコンポーネントのバリエーションを作成し、それをゲストユーザー向けとしてオーディエンスを設定することができます。
各バリエーションの作成方法とオーディエンスの設定方法は以下を参照ください。
LWRサイトはオーディエンスによる切り替えとは仕組みが異なりますが同様のことができるようです。
ゲストユーザーアクセスのテスト
以下は、ゲストユーザーアクセスをテストする箇所について、ルールブックにはありませんが、Dreamforce のセッションで紹介されていたものです。
ブラウザのシークレットウィンドウを利用してサイトを参照する
各公開ページを参照してアクセスレベルを検証する
オブジェクトページを参照する
グローバル検索をテストする
各オブジェクト詳細ページへの直リンクにアクセスする
ルール3: 権限セットと権限セットグループでユーザーのアクセス権限を管理する
これは、Experience Cloud固有の話ではないですが、プロファイルによるオブジェクト権限の設定はSpring ‘26でサポートされなくなります。
今から構築するサイトでは、プロファイルによる権限設定はやめましょうという話です。
参照: Permissions Updates | Learn MOAR Spring '23 - Salesforce Admins
実装面でもプロファイルはモノリシックで運用管理が権限セットより劣ります。レコードタイプの割り当てが必要など特別な理由がない場合は権限セットを利用しましょう。
またルールブックでは権限セットを便利に利用するための2つの機能についても紹介されています。
まだベータですが、権限セットおよび権限セットグループなどを自動で割り当てる設定が可能になります。
試すには、「ユーザー管理設定」で「ユーザーアクセスポリシー(ベータ)」を有効化します。
参照: Enable User Access Policies (Beta)
以下のような画面で、ユーザーの作成または更新をトリガーに権限セット、権限セットグループ、キュー、グループ、パッケージライセンスを割り当てることができます。
項目作成時に項目レベルセキュリティを権限セットで設定可能に
オブジェクトの項目作成ウィザードで、今までは項目レベルセキュリティの設定はプロファイルに対して行っていましたが、この機能を有効化すると権限セットに項目レベルセキュリティを設定することができるようになります。
余談ですが、この記事を執筆している現在では、パッケージ開発で2GPはプロファイルを追加できなくなっていますし、パッケージ開発に含まれる権限設定は権限セットに指定する必要があります。パッケージ開発用のスクラッチ組織では常にこの機能をOnにしておくほうが便利かもしれません。
ルール4: 個人を特定できる情報(PII)を定義し保護する
こちらは、この通りでSalesforceには個人情報(PII)を保護する機能があるので、活用しましょうという話ですね。
「ユーザー管理設定」を開き「拡張個人情報管理」を有効化すると、個人情報項目を非表示にできます
オブジェクトマネージャーで「ユーザー」を開くと項目セット「PersonalInfo_EPIM」が確認できます。こちらの項目セットに含まれるフィールドがPIIとして認識されます。
以下、デフォルトの選択状態から「会社名」と「役職」を外して動作を確認してみます。
以下のように、サイトでユーザーを表示してみると「役職(Title)」と「会社名(Company Name)」が参照可能になりました。
「PersonalInfo_EPIM」に追加されている項目(赤枠)は非表示になっています。「名前」はニックネームが表示されます。
カスタム処理が必要なケース
ところで「OOBコンポーネント」とは、Out-of-the-Boxコンポーネントの頭文字で、標準で提供されるコンポーネントのことらしいです。
で、EPIM設定を利用しても、以下の注意が必要です。
EPIM設定はApexでは強制されない
EPIMはユーザーオブジェクトしかサポートされていない
ルール5: グローバル設定とサイトごとの設定を把握し、点検する
標準コンポーネントを使用するために必要なオプションがすぐに探せない場合、とりあえずすべてのオプションを有効化してしまうケースが見受けられるということです。
グローバル設定
1.デジタルエクスペリエンス > 設定
「ロールとユーザー設定」に含まれる以下の設定は、理由がない限りデフォルトのままにしたほうが良いとのことです。
これらのオプションについては、ヘルプの「ロールとユーザー設定の定義」に解説があります。
「パートナー取引先またはカスタマー取引先で有効になっていない取引先責任者の表示をユーザーに許可」
この設定は、検証してみましたがわかりませんでした。ヘルプ「ロールとユーザー設定の定義」には以下の説明があります。
しかし、このオプションが無効のままでも「ユーザーが参照アクセス権を持つ非公開取引先の取引先責任者」は参照できました。共有設定的には問題ないような気がしますが、機能の理解が間違っているのか。こちらは要調査検証です。
参照: サイトで有効になっていない取引先責任者をサイトユーザが表示できない
「セルフ登録、ユーザー作成、およびログインで標準外部プロファイルの使用を許可」
「標準の外部プロファイル」とは、一般的に、「Partner Community User」や「Customer Community User」など、コミュニティやポータルにアクセスする外部ユーザーに付与するプロファイルのことです。
基本的にはこれらは使わずコピーして使うものらしいです。そもそも今後は権限セットを使うようにするべきとのこと。
余談ですが、今回発表するにあたって、トレイルヘッド モジュール「パートナーとの CRM データの共有 | Salesforce Trailhead」を改めて試してみましたが、こちらは標準のプロファイルを使用しているので、このオプションを有効化する必要がありました。
「エクスペリエンスビルダーサイトのゲストユーザーにはバッジを非表示にする」
レコグニションバッジ という機能があるらしく、このバッジの表示非表示
2.ユーザー表示設定
「ポータルユーザー表示」と「サイトユーザー表示」の2つのオプションがあります。
「ユーザー表示設定」が無効な場合、共有設定上参照できないユーザーを表示しようとすると「Page not available」が表示されます。
参照: Experience Cloud サイトでのユーザー表示設定の制御
「ポータルユーザー表示」を有効にすると「デフォルトの外部アクセス権」に関係なく、同じカスタマー/パートナーポータル取引先に属するポータルユーザーは互いに参照することができるようになります。
以下の図では取引先「Edge Communications」と「Express Logistics and Transport」があり、それぞれにパートナー マネージャーとパートナー ユーザー ロールのユーザーが居ます。
取引先「Edge Communications」のローズは、共有設定では上位のロール階層のショーンは参照できませんが、「ポータルユーザー表示」を有効にすると参照可能になります。
「サイトユーザー表示」を有効にすると「デフォルトの外部アクセス権」に関係なく、サイト内の他の取引先に属するポータルユーザーも参照することができるようになります。
ただし、この設定は、サイトごとの設定の「このサイトの他のメンバーを表示」を併せて有効化する必要があります。
以下の場合、取引先「Edge Communications」のローズは、他の取引先「Express Logistics and Transport」のパートナーユーザー バーバラとデイビスも参照可能になります。
サイトごとの設定
サイトごとの設定は「サイトのワークスペース > 管理 > 詳細」で行います。
各オプションを利用するかどうかは、サイトのユースケースに依るかと思いますので、このセクションで挙げられているオプションの説明の翻訳だけ載せておきます。
「ニックネーム表示」については、ルール4で確認済みです。PIIとして設定している場合はニックネームを表示します。
ログインユーザー向けの設定
「このサイトの他のメンバーを表示」
前述しましたが、共有設定「ユーザー表示設定」の「サイトユーザー表示」を有効にする必要があります。
ゲストユーザー向けの設定
ゲストユーザー向けの設定は、原文の説明のとおりだと思いますので翻訳だけ載せています。
「ゲストユーザーがサイトで使用可能なアセットファイル、ライブラリファイル、CMS コンテンツを表示できるようにする」
「公開 Chatter API 要求へのアクセス権をゲストユーザーに付与」
「ゲストユーザーがこのサイトの他のメンバーを表示できるようにする」
ルール6: 適切なクリックジャック保護を有効にする
参照: Experience Cloud サイトのクリックジャック保護の有効化
ルール7: 適切なコンテンツセキュリティポリシー(CSP)を有効にする
参照: Lightning コミュニティのコンテンツセキュリティポリシー | Lightning コミュニティ開発者ガイド | Salesforce Developers
ルール8: 外部ユーザーアクセスの組織全体のデフォルトを制限する
組織全体のデフォルトとは「共有設定」の「デフォルトの外部アクセス権」のことです。
ちなみに、現在はこの「デフォルトの外部アクセス権」はゲストユーザーには付与されませんが、Winter '20より古い組織では適用されてしまうので気をつける必要があります。
共有設定によるレコードレベルセキュリティの概念自体については、以下のヘルプに掲載されている動画がわかりやすいです。
参照: Experience Cloud サイトでの CRM データの共有
余談ですが、Dreamforceのセッションではルール6〜8までは時間の関係上割愛されていました。セッションではルール9がルール6として紹介されています。
また、以降は開発者向けのルールとなっています。
ルール9: Apexコントローラのアクションでは、オブジェクトアクセス(CRUD),項目レベルセキュリティ(FLS)を強制する
カスタムのLightningコンポーネントなどを配置しているケースの話です。コンポーネントでUI上操作不可となっている操作もコンポーネントから呼び出されるApexコントローラのAuraEnabledアクションでCURD・FLS のチェックをしていない場合、開発者が意図しない操作を直にAPI叩いて可能です。Apexは、必ずユーザーモードでクエリー・DML操作を記述しましょう。
ルールブックでは具体的に、ブラウザの開発コンソールを開いて、AuraEnabledアクションのパラメータを解析し、実際にPOSTMANから開発者が意図しないDML操作ができる例を解説しています。
SOQLの場合は「WITH USER_MODE」をつけます。
Account[] accounts = [SELECT Id FROM Account WITH USER_MODE];
オブジェクトの参照権限や項目レベルセキュリティ違反があれば例外がスローされます。
DML操作の場合は「as user」をつけるのが最も簡単な方法です。
insert as user account;
ルール 10: 画面(UI)とAPIからのデータアクセスは一貫させなければならない
これは、数年前によく事故ってたやつですね。
オブジェクトの共有設定上公開されているものは、画面に表示しなくても公開されているので注意が必要です。
ルールブックでは、UI APIを介してレコードの情報を簡単に取得するデモを説明しています。
ルール 11: 暗黙的な共有を点検する
そもそも「暗黙的な共有」とはなにか?については、開発者ガイドの「暗黙的な共有 | 企業の規模に応じたレコードアクセス権の作成 | Salesforce Developers」に説明があります。
具体的には取引先の親子関係にともなうアクセス権限などがあります。
このルールもDreamforceのセッションでは割愛されていました。
ルール 12: 「Without Sharing」の使用は控える、必要な場合は適切な保護措置を行う
「without sharing」を指定したApexについては「ゲストレコードのデフォルト所有者の使用に関するベストプラクティスと考慮事項」の「Apex without sharing」に同様の言及があります。
オブジェクトの共有設定は非公開のまま、Apexはシステムモードでオブジェクト権限を無視して更新、削除を実装することになるため、最深の注意を払ってApexとそのテストを記述する必要があります。
Apexの場合は、Crypto クラスを使用して実装できそうですが、ベストプラクティスを知りたいところです。
SalesforceのExperience Cloudの学習サイトの記事「Article: Guest User Record Access Development Best Practices | Learn Experience Cloud」にユースケースごとの実装パターンが掲載されています。Cryptoクラスを使用したレコードIDの暗号化の例もあるので参考になりそうです。
まとめ
ルールブックをひととおり目を通してきましたが、Experience Cloudの権限には様々な設定があり、実際に構築・運用をしていないとすべてを把握するのは難しそうな印象でした。
また、このルールブックの内容だけでは把握しきれない内容もあり、各種参考リンクも一読、検証しておきたいところです。
AppExchangeベンダーとしては、ルール12の「非公開 & without sharing」パターンをパッケージに含めてもセキュリティレビューに通るのかは気になるところです。(なかなか実際にレビューに出す勇気はもてませんが)
以上、時間の都合上すべては検証できないない箇所もありましたが、多くは解説できたのではないかと思います。あくまで私はExperience Cloudの経験は浅いため実戦経験を伴う解説ではありませんが参考になれば幸いです。