プラットフォームの機能を使用した秘密の保護
学習の目的
この単元を完了すると、次のことができるようになります。
- 管理パッケージ内に秘密を格納するオプションと推奨方法を挙げる。
- コールアウトエンドポイントとそれに関連付けられた認証パラメーターを安全に定義するために指定ログイン情報を作成する。
- 秘密を格納するために、保護されたカスタム設定と保護されたカスタムメタデータ API 項目を活用する方法を説明する。
Salesforce でのアプリケーションの秘密の格納
最初の単元では、秘密を特定する方法と誰がアクセス権を持つべきかを学習しました。次は秘密を保護する方法を学習します。
Salesforce プラットフォームには秘密の格納と保護に使用できる機能がいくつもあるため簡単です。次のような機能があります。
- 指定ログイン情報
- カスタム設定 (保護、非保護、未管理、管理)
- カスタムメタデータ型
この単元では、機密情報が適切に制限されるように秘密を格納する各方法について説明します。
指定ログイン情報
指定ログイン情報では、1 つの定義でコールアウトエンドポイントの URL と必要な認証パラメーターを指定します。Apex コールアウトで指定ログイン情報をコールアウトエンドポイントとして指定するすべての認証が Salesforce によって管理されるため、Apex コードにさらに認証ロジックを追加する必要がありません。指定ログイン情報を定義して、このようなコールアウトを設定する、安全で便利な方法を提供できます。作成したら、コード内の URL 参照を指定ログイン情報の参照に置き換えることができます。その結果としてコードは、クリーンで、シンプルで、安全なものになります。
指定ログイン情報は、管理パッケージで参照されるコールアウトエンドポイントを定義する場合、特に便利です。指定ログイン情報がない場合、認証されたコールアウトを設定するには、開発者には次のような追加作業が求められます。
- URL をコールアウトエンドポイントとして参照する。
- リモートサイト設定に URL を登録する。
- 関連する認証タスクを処理するためのカスタムコードを追加する。
たとえば、外部サービスに定期的に接続してデータを取り込むアプリケーションがあるとします。ただし、この外部サービスでは、すべての要求に認証のための API キーを含める必要があります。開発者がこの要件を満たす一般的な方法は、ソースコードにキーをハードコードして各要求で使用できるようにすることです。次のコードの例を考えてみます。
String key = ‘supersecurepassword’; HttpRequest req = new HttpRequest(); req.setEndpoint('https://www.example.com/test?APIKEY='+key); req.setMethod('GET'); Http http = new Http(); HTTPResponse res = http.send(req); return res.getBody();
秘密のハードコード化は確かに単純な解決策ですが、このアプローチには 3 つの問題があります。
- ソースコードを表示できるユーザーは、埋め込まれた秘密も表示できる。
- 秘密が更新されると、ソースコード内の秘密のインスタンスをすべて変更する必要がある。
- この秘密をアプリケーション間でポーティングすると、その他に多くの複雑な問題が生じる可能性がある。
このような問題を解決するのが指定ログイン情報です。コードに値をハードコードするのではなく、指定ログイン情報を活用して秘密を保存すると、コード内のその他の変数と同様に、指定ログイン情報を参照して秘密の値にアクセスできます。
値自体の代わりに指定ログイン情報を使用する場合、システム管理者プロファイルを使用するユーザーと、「すべてのデータの参照」および「すべてのデータの編集」権限を持つユーザーのみが値にアクセスできます。
指定ログイン情報の利点
指定ログイン情報を使用すると、アプリケーションの秘密へのアクセスを制限する手段となるだけでなく、この秘密の管理が容易になります。指定ログイン情報を設定した後、必要な場合には設定でいつでも簡単に変更できます。こうすることで、秘密を参照するコード内のインスタンスは、指定ログイン情報を直接参照するので、古い値が保持されることはありません。
指定ログイン情報の使用が適している事例
指定ログイン情報の設定はかなり簡単にできますが、必ずしもすべての使用事例に適しているわけではありません。指定ログイン情報は、ユーザー名とパスワード、または OAuth 2.0 などの単純な認証スキーマに最適です。
指定ログイン情報は、組織のシステム管理者と開発者の仕事を簡単で安全なものにするために設計されています。とは言っても、それが常に最適な選択とは限りません。「すべてのデータの編集」または「Apex 開発」権限を持つユーザーは、指定ログイン情報を変更したり、コールアウトを実行したりできるため、指定ログイン情報で保護されているデータにもアクセスできます。または、資格情報を抽出できる可能性もあります。独自のクラウドサービスと非公開で通信する必要があるパッケージを作成する独立系ソフトウェアベンダーなど、このような使用事例に対する保護が必要な場合は、管理および保護されたカスタム設定やカスタムメタデータ型など他のオプションを使用することを検討してください。これについては、次のセクションで詳しく説明します。
配布される秘密の保護
指定ログイン情報は、関連付けられた認証の秘密にシステム管理者がアクセスすることが許可されている組織で、外部サービスへのコールアウトが実行される場合に最適です。では、システム管理者がデータを表示できないようにしたり、秘密を複数の Salesforce 組織に配布したりする場合は、どうしたらよいのでしょうか?
このような場合は、コードを管理パッケージという形式でリリースします。無料の Developer Edition 組織に簡単にサインアップし、コードのパッケージ化組織として使用できます。AppExchange パートナーの場合は、環境ハブから Developer Edition 組織を作成できます。また、Developer Edition サインアップページからでも作成できます。パッケージ化組織内で、Apex クラス、Apex トリガー、Salesforce オブジェクト、その他の一般的なメタデータの形式を管理パッケージにまとめて、他の Salesforce インスタンスや組織に簡単にリリースできます。管理パッケージは、zip ファイルを複雑化したバージョンと考えることができます。
セキュリティという観点から、未管理パッケージや疎結合コードではなく、管理パッケージを使用することには大きな利点が多数あります。
- セキュリティの脆弱性が確認された場合に、自動更新、パッチ、修正を転送するためのメカニズムが含まれています。
- 非表示にされたソースコードが含まれています (明示的に公開されたグローバル Apex クラスを除く)。つまり不注意で壊されたり、悪意のある変更を加えて再配布されたりしないように、基本的なビジネスロジックまたはプログラムロジックは改変できないようになっています。また、非表示にされたコードは、パッケージに格納されている秘密が表示されるのを防ぎます。
- 管理パッケージには一意の名前空間を定義する必要があるので、名前空間の競合問題が起こりません。また、ローカルの名前空間からパッケージが分離されるので、パッケージに格納されている秘密の保護がさらに強化されます。デフォルトで、パッケージの秘密は管理パッケージ外で実行されるコードでアクセスすることができません。
保護されたカスタム設定とカスタムメタデータ型の管理
管理パッケージ内でコードをパッケージ化するだけでもセキュリティ上の利点が多くありますが、管理パッケージを使用すると、保護されたカスタム設定と保護されたカスタムメタデータという、情報の格納と配布に使用できる 2 つの機能へのアクセス権が付与されます。
カスタム設定は、作成することでほぼどのデータでも格納でき、用途とコンテンツという点ではきわめて柔軟性に優れています。要約すると、カスタム設定ではアプリケーションキャッシュに公開されるカスタムデータセットを作成できるため、データベースへのクエリを繰り返さず、アプリケーションの効率が高くなります。たとえば、カスタム設定は、アプリケーションでユーザーエクスペリエンスをパーソナライズするために使用されるデータセットを格納するために使用できます。または、カスタム設定を作成して、すぐ簡単にアクセスできるように、さまざまなページで参照される商品名のリストを格納できます。アプリケーションのセキュリティという点では、カスタム設定を使用して機密情報や秘密を格納できます。
カスタム設定には、さまざまな表示レベルがあります。管理パッケージに含まれている保護されたカスタム設定は、Apex または API では登録組織に表示されないため、特定の種類の秘密を格納するのに適した場所です。表示が公開に設定されているか、未管理パッケージに含まれているカスタム設定は、Enterprise Web Service Description Language (WSDL) を使用して表示できます。そのため、機密情報を格納する場合、保護されたカスタム設定が管理パッケージ内でカプセル化されていることが重要です。
カスタムメタデータ項目は、カスタム設定と似たような方法で、秘密を格納する場所として利用できます。秘密を守るためには、表示を [保護] に設定し、管理パッケージ内に含めます。保護されたカスタムメタデータ API 項目は、API キーやその他の秘密鍵を格納するのに適した場所です。
表示設定では、カスタム設定とメタデータ項目の両方に、いくつかのオプションが用意されています。
- 公開 (ローカル)
- 保護 (ローカル)
- 公開 (管理)
- 保護 (管理)
一般的にデータの格納には最初の 3 つのオプションが実行可能ですが、この設定を使用すると、組織のすべてのユーザーがデータ値を表示できるようになります。このオプションは、公開されているデータを格納する場合にのみ使用します。アプリケーションの秘密のような機密データには、管理および保護された設定オプションを使用します。
非表示オプション、アクセスの容易さ、キャッシュ機能という利点があるカスタム設定とメタデータ項目は、秘密を格納する場所として、実行可能で魅力的なオプションです。
管理および保護されたカスタム設定
秘密を安全に保護するために使用する、管理および保護されたカスタム設定を作成して District Secrets という名前を付けます。[設定] の > ボックスで検索して [カスタム設定] に移動し、[新規] をクリックして保護されたカスタム設定を作成します。表示ラベル、オブジェクト名、設定種別、表示 ([保護] に設定) を定義します。[保存] をクリックすると、秘密を格納するカスタム項目の追加準備が整います。
最後に、保護されたカスタム項目に秘密を入力します。パッケージには設定の定義のみが含まれるので、パッケージが対象組織または登録者組織にインストールされたら、Apex または API スクリプトを使用して秘密を入力する必要があります。
管理および保護されたカスタム設定の使用方法
カスタム設定は、カスタムオブジェクトを参照するのと同じように参照できます。カスタム設定にアクセスするには、数式項目、Apex カスタム設定メソッド、SOAP API、入力規則、フローなどを使用できます。保護されたカスタム設定の参照は、同じ管理パッケージ (つまり同じ名前空間) 内からのみ行うことができます。カスタム設定を参照する一般的な Apex メソッドは、次のとおりです。
getAll()
getValues()
getOrgDetails()
getInstance(Profile_ID)
次に、カスタム設定コンポーネントとして格納された秘密にアクセスするために、getAll() を使用する例を示します。
Map<String, CustomSettingName__c> mcs = CustomSettingName__c.getAll();
カスタムメタデータ型
先ほどカスタム設定を定義したときと同じような方法で、保護されたカスタムメタデータ型も秘密を保持するように定義できます。すでに説明したとおり、カスタムメタデータ型を効果的に非表示にして保護するには、管理パッケージ内に含まれるように設計する必要があります。カスタム設定との主な違いは、カスタムメタデータ型に格納されるデータは、アプリケーションのメタデータを表すということです。
これが有利に働く場合が多々あります。あなたは、Developer Edition のパッケージ化組織で新しいアプリケーションを作成している開発者だとします。このアプリケーションには、example.com との外部 API インテグレーションなど、さまざまな優れた機能があります。example.com へのコールアウトを実行するには、API キーをどこかに格納する必要があります。1 つの方法は、カスタム項目内に API 秘密キーを格納することです。自分の DE 組織内では正常に動作しますが、このアプローチの問題点はなんでしょうか?
安全ではないうえに、再リリースとなると、カスタム項目内への API 秘密キーの格納には問題があります。すべてのコードとカスタマイズを本番組織に移動するとき、秘密キーの値は同時には転送されません。変更セットではデータが本番に移行されません。項目にキー値を手動で入力するか、自動入力するスクリプトを作成する必要があります。一方、カスタムメタデータ型では、API 秘密キーはその他のカスタマイズと同じように扱われ、本番環境に移動されます。このシナリオであれば、手動で再入力する必要がありません。
前述したように、カスタム設定でデータを読み込むには、なんらかの postinstall スクリプトを作成する必要があります。それに対して、保護されたカスタムメタデータ型の場合は、スクリプトを作成する必要はありません。カスタムメタデータ型に格納されたデータは、別個のメタデータとして使用できます。そしてこれをパッケージに追加できます。
カスタムメタデータ型の優れている点の 1 つは、他のカスタムオブジェクトのように、SOQL を使用して取り込めることです。唯一の違いは、メタデータ型で使用されるサフィックスが、__c ではなく、__mdt であるということです。カスタムメタデータ型を選択する場合は、次のようなクエリを作成します。
SELECT Teacher__c, Coach__c, Counselor__c , Administrator__c FROM District_Profiles__mdt
この行は、District_Profiles__mdt のすべての値を取得します。簡単ですね。
カスタム設定とカスタムメタデータ型の比較
秘密を保護するために、カスタム設定とカスタムメタデータ型のどちらでも使用できますが、この 2 つには注目すべき違いがいくつかあります。では、それぞれどのような場合に使用するのか確認しましょう。
保護されたカスタム設定は、次のような場合に使用します。
- 秘密は頻繁な更新が必要で、更新後すぐに使用可能でなければならない。メタデータ型はキューに追加してリリースされる必要があるため、メタデータ型の秘密が更新されても、すぐには使用できません。この場合はカスタム設定の使用が適しています。
- どの秘密にどのプロファイルとユーザーがアクセスできるのかを指定する必要がある。メタデータ型には、秘密にアクセスできるプロファイルまたはユーザーを指定できるカスタム設定階層のような粒度がありません。そのため、この場合はカスタム設定の使用が適しています。
カスタムメタデータ型は、次のような場合に使用します。
- 追加の設定ステップを実行せずに、一般的な秘密をリリースする必要がある。
- カスタムメタデータの秘密は、たとえば Sandbox または開発環境から本番環境に簡単に移行できます。一方、カスタム設定では、通常 Sandbox から本番環境に移行するときに、システム管理者が postinstall スクリプトかページのどちらかを作成して、新しい環境に秘密を手動で入力して格納する必要があります。