プラットフォームの機能を使用した秘密の保護
学習の目的
この単元を完了すると、次のことができるようになります。
- 管理パッケージ内に秘密を格納するオプションと推奨方法を挙げる。
- コールアウトエンドポイントとそれに関連付けられた認証パラメーターを安全に定義するために指定ログイン情報を作成する。
- 保護されたカスタム設定とメタデータ API 項目を活用した秘密の格納方法を説明する。
Salesforce でのアプリケーションの秘密の格納
前の単元では、秘密を特定する方法と誰がアクセス権を持つべきかを学習しました。次は秘密を保護する方法を学習します。
Salesforce Platform には、秘密の格納と保護に使用できる次のようなさまざまな機能があります。
- 指定ログイン情報
- カスタム設定 (保護、非保護、未管理、管理)
- カスタムメタデータ型
この単元では、機密情報が適切に制限されるように秘密を格納する各方法について学習します。
指定ログイン情報
指定ログイン情報は、外部のプロバイダーやサービスに対する認証値を安全に管理するためのメカニズムです。指定ログイン情報によって、安全で管理可能なエンティティ間で、標準認証の実装プロセスが実現します。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、AWS 署名バージョン 4、署名付き JWT などの標準認証プロトコルに最適です。
指定ログイン情報は、組織のシステム管理者と開発者の仕事を簡単で安全なものにするために設計されています。とは言っても、それが常に最適な選択とは限りません。「Modify All Data (すべてのデータの編集)」または「Author Apex (Apex 開発)」権限を持つユーザーは、指定ログイン情報を変更したり、コールアウトを実行したりできるため、指定ログイン情報で保護されているデータにもアクセスできます。あるいは、ログイン情報そのものを抽出できる可能性もあります。クラウドサービスと非公開で通信する必要があるパッケージを作成する独立系ソフトウェアベンダーなど、このような使用事例に対する保護が必要な場合は、管理および保護されたカスタム設定やカスタムメタデータ型など他のオプションを使用することを検討してください。これについては、次のセクションで詳しく説明します。
新たな指定/外部ログイン情報機能
Salesforce の新しい指定/外部ログイン情報機能は、セキュリティを強化し、外部インテグレーションを効率化する設計になっています。外部ログイン情報は、Salesforce の認証プロトコルを使った外部システムとの認証方法の詳細であり、権限セット、プロファイル、カスタムヘッダー (省略可能) にリンクします。必要な権限を持つユーザーは、外部ログイン情報を表示、作成、編集、削除できます。
指定ログイン情報は、外部システムへの論理接続として機能します。そのため、Apex コードへの物理 URL の埋め込みや、暗号化されていないデータストアでの認証トークンの管理は必要ありません。指定ログイン情報では、1 つの定義でコールアウトエンドポイントの URL と必要な認証パラメーターを指定します。SecuredEndpoint、PrivateEndpoint、Legacy (非推奨) など、さまざまな型がサポートされます。
指定ログイン情報と外部ログイン情報とを対応させるには、まず外部ログイン情報を作成します。認証プロトコルと権限セットまたはプロファイルを指定して作成します。次に、外部サービスのコールアウトエンドポイントの役割を果たす指定ログイン情報を作成します。外部ログイン情報の認証の詳細が指定ログイン情報にリンクされることで、安全な認証済みコールアウトが可能になります。
権限セットは、外部サービスへのアクセス制御において重要な役割を果たします。外部ログイン情報がユーザーを認証するのに対し、権限セットはユーザーを認可します。外部ログイン情報のプリンシパルがユーザー権限にマッピングされ、リモートシステムへのアクセスに必要な認可がユーザーに事前に付与されます。ユーザーの外部ログイン情報には暗号化されたトークンが保存されるため、ユーザーごとの認可を安全に管理できます。
カスタムヘッダーは、指定ログイン情報と外部ログイン情報の両方に追加できます。カスタムヘッダーによって、Salesforce からリモートシステムへのコールに、要求への応答に必要なカスタムパラメーターを含むことができます。このカスタマイズにより柔軟性が高まり、さまざまな使用事例やセキュリティ要件に対応できます。
指定ログイン情報と外部ログイン情報の作成および編集は、メタデータ API、Tooling API、および Connect REST API を使っても可能ですが、Salesforce プラットフォームでは Salesforce UI の使用を推奨しています。全般として、指定/外部ログイン情報機能は、認証済みの安全な外部インテグレーションを堅牢かつカスタマイズ可能な方法で管理できます。
配布される秘密の保護
指定ログイン情報は、関連付けられた認証の秘密にシステム管理者がアクセスできる組織での、外部サービスへのコールアウトに最適です。では、システム管理者がデータを表示できないようにしたり、秘密を複数の Salesforce 組織に配布したりする場合は、どうしたらよいのでしょうか?
このような場合は、コードを管理パッケージとしてリリースします。無料の Developer Edition 組織に簡単にサインアップし、コードのパッケージ化組織として使用できます。AppExchange パートナーの場合は、環境ハブから Developer Edition 組織を作成できます。また、Developer Edition サインアップページからでも作成できます。パッケージ化組織内で、Apex クラス、Apex トリガー、Salesforce オブジェクト、その他の一般的なメタデータの形式を管理パッケージにまとめて、他の Salesforce インスタンスや組織に簡単にリリースできます。管理パッケージは、zip ファイルを複雑化したバージョンと考えることができます。
セキュリティという観点から、未管理パッケージや疎結合コードではなく、管理パッケージを使用することには大きな利点が多数あります。
- 管理パッケージには、セキュリティの脆弱性が確認された場合に、自動更新、パッチ、修正を転送するためのメカニズムが含まれています。
- 非表示にされたソースコードが含まれています (明示的に公開されたグローバル Apex クラスを除く)。つまり不注意で壊されたり、悪意のある変更を加えて再配布されたりしないように、基本的なビジネスロジックまたはプログラムロジックは改変できないようになっています。また、非表示にされたコードは、パッケージに格納されている秘密が表示されるのを防ぎます。
- 管理パッケージには一意の名前空間を定義する必要があるので、名前空間の競合問題が起こりません。また、ローカルの名前空間からパッケージが分離されるので、パッケージに格納されている秘密の保護がさらに強化されます。デフォルトで、パッケージの秘密は管理パッケージ外で実行されるコードでアクセスすることができません。
保護されたカスタム設定とカスタムメタデータ型の管理
管理パッケージ内でコードをパッケージ化するだけでもセキュリティ上の利点が多くありますが、管理パッケージを使用すると、保護されたカスタム設定と保護されたカスタムメタデータという、情報の格納と配布に使用できる 2 つの機能へのアクセス権が付与されます。
[Custom settings (カスタム設定)] は、作成することでほぼどのデータでも格納でき、用途とコンテンツという点ではきわめて柔軟性に優れています。要約すると、カスタム設定ではアプリケーションキャッシュに公開されるカスタムデータセットを作成できるため、データベースへのクエリを繰り返さず、アプリケーションの効率が高くなります。たとえば、カスタム設定は、アプリケーションでユーザーエクスペリエンスをパーソナライズするために使用されるデータセットを格納するために使用できます。または、カスタム設定を作成して、すぐ簡単にアクセスできるように、さまざまなページで参照される商品名のリストを格納できます。アプリケーションのセキュリティという点では、カスタム設定を使用して機密情報や秘密を格納できます。
カスタム設定には、さまざまな表示レベルがあります。管理パッケージに含まれている保護されたカスタム設定は、Apex または API では登録組織に表示されないため、特定の種類の秘密を格納するのに適した場所です。表示が公開に設定されているか、未管理パッケージに含まれているカスタム設定は、Enterprise Web Service Description Language (WSDL) を使用して表示できます。そのため、機密情報を格納する場合、保護されたカスタム設定が管理パッケージ内でカプセル化されていることが重要です。
[Custom metadata (カスタムメタデータ)] 項目は、カスタム設定と似たような方法で、秘密を格納する場所として利用できます。秘密を守るためには、表示を [Protected (保護)] に設定し、管理パッケージ内に含めます。保護されたカスタムメタデータ API 項目は、API キーやその他の秘密鍵を格納するのに適した場所です。
表示設定では、カスタム設定とメタデータ項目の両方に、いくつかのオプションが用意されています。
- 公開 (ローカル)
- 保護 (ローカル)
- 公開 (管理)
- 保護 (管理)
一般的にデータの格納には最初の 3 つのオプションが実行可能ですが、この設定を使用すると、組織のすべてのユーザーがデータ値を表示できるようになります。このオプションは、公開されているデータを格納する場合にのみ使用します。アプリケーションの秘密のような機密データには、管理および保護された設定オプションを使用します。
非表示オプション、アクセスの容易さ、キャッシュ機能という利点があるカスタム設定とメタデータ項目は、秘密を格納する場所として、実行可能で魅力的なオプションです。
管理および保護されたカスタム設定
秘密を安全に保護するために使用する、管理および保護されたカスタム設定を作成して District Secrets という名前を付けます。[Setup (設定)] の [Quick Find (クイック検索)] ボックスで検索して [Custom Settings (カスタム設定)] に移動し、[New (新規)] をクリックして保護されたカスタム設定を作成します。表示ラベル、オブジェクト名、設定種別、表示 ([Protected (保護)] に設定) を定義します。[Save (保存)] をクリックすると、秘密を格納するカスタム項目の追加準備が整います。
最後に、保護されたカスタム項目に秘密を入力します。パッケージには設定の定義のみが含まれるので、パッケージが対象組織または登録者組織にインストールされたら、Apex または API スクリプトを使用して秘密を入力する必要があります。
管理および保護されたカスタム設定の使用方法
カスタム設定は、カスタムオブジェクトを参照するのと同じように参照できます。カスタム設定にアクセスするには、数式項目、Apex カスタム設定メソッド、SOAP API、入力規則、フローなどを使用できます。保護されたカスタム設定の参照は、同じ管理パッケージ (つまり同じ名前空間) 内からのみ行うことができます。カスタム設定を参照する一般的な Apex メソッドは、次のとおりです。
-
getInstance()
-
getInstance(userId)
-
getInstance(profileId)
-
getOrgDefaults()
-
getValues(userId)
-
getValues(profileId)
次に、カスタム設定コンポーネントとして格納された秘密にアクセスするために、getInstance()
を使用する例を示します。
CustomSettingName__c cmcs=CustomSettingName__c.getInstance();
カスタムメタデータ型
カスタム設定を定義するのと同様の方法で、保護されたカスタムメタデータ型も秘密を保持するように定義できます。カスタムメタデータ型を効果的に非表示にして保護するには、管理パッケージ内に含まれるように設計する必要があります。カスタム設定との主な違いは、カスタムメタデータ型に格納されるデータは、アプリケーションのメタデータを表すということです。
多くの場合、これは利点となります。あなたは、Developer Edition のパッケージ化組織で新しいアプリケーションを作成している開発者だとします。このアプリケーションには、example.com との外部 API インテグレーションなど、さまざまな優れた機能があります。example.com へのコールアウトを実行するには、API キーをどこかに格納する必要があります。1 つの方法は、カスタム項目内に API 秘密鍵を格納することです。自分の DE 組織内では正常に動作しますが、このアプローチには問題があります。
安全ではないうえに、再リリースとなると、カスタム項目内への API 秘密鍵の格納には問題があります。すべてのコードとカスタマイズを本番組織に移動するとき、秘密鍵の値は同時には転送されません。変更セットではデータが本番に移行されません。項目に鍵値を手動で入力するか、自動入力するスクリプトを作成する必要があります。一方、カスタムメタデータ型では、API 秘密鍵はその他のカスタマイズと同じように扱われ、本番環境に移動されます。このシナリオであれば、手動で再入力する必要がありません。
前述したように、カスタム設定でデータを読み込むには、インストール後スクリプトを作成する必要があります。それに対して、保護されたカスタムメタデータ型の場合は、スクリプトを作成する必要はありません。カスタムメタデータ型に格納されたデータは、別個のメタデータとして使用できます。そしてこれをパッケージに追加できます。素晴らしいと思いませんか?
カスタムメタデータ型の優れている点の 1 つは、他のカスタムオブジェクトのように、SOQL を使用して取り込めることです。唯一の違いは、メタデータ型で使用されるサフィックスが、__c
ではなく、__mdt
であるということです。カスタムメタデータ型を選択する場合は、次のようなクエリを作成します。
SELECT Teacher__c, Coach__c, Counselor__c , Administrator__c FROM District_Profiles__mdt
この行は、District_Profiles__mdt
のすべての値を取得します。簡単ですね。
カスタム設定とカスタムメタデータ型の比較
秘密を保護するために、カスタム設定とカスタムメタデータ型のどちらでも使用できますが、この 2 つには注目すべき違いがいくつかあります。では、それぞれどのような場合に使用するのか確認しましょう。
保護されたカスタム設定は、次のような場合に使用します。
- 秘密は頻繁な更新が必要で、更新後すぐに使用可能でなければならない。メタデータ型はキューに追加してリリースされる必要があるため、メタデータ型の秘密が更新されても、すぐには使用できません。この場合はカスタム設定の使用が適しています。
- どの秘密にどのプロファイルとユーザーがアクセスできるのかを指定する必要がある。メタデータ型には、秘密にアクセスできるプロファイルまたはユーザーを指定できるカスタム設定階層のような粒度がありません。そのため、この場合はカスタム設定の使用が適しています。
カスタムメタデータ型は、次のような場合に使用します。
- 追加の設定ステップを実行せずに、一般的な秘密をリリースする必要がある。
- カスタムメタデータの秘密は、たとえば Sandbox または開発環境から本番環境に簡単に移行できます。一方、カスタム設定では、通常 Sandbox から本番環境に移行するときに、システム管理者がインストール後スクリプトかページのどちらかを作成して、新しい環境に秘密を手動で入力して格納する必要があります。
リソース
-
Salesforce 開発者ブログ: Apex Developer Guide: Named Credentials as Callout Endpoints (Apex 開発者ガイド: コールアウトエンドポイントとしての指定ログイン情報)
-
Salesforce 開発者ブログ: How to use custom metadata types to save years of development on app configurations (カスタムメタデータ型を使用してアプリケーション設定の長年の開発を保存する方法)
-
Salesforce 開発者ブログ: Apex Developer Guide: Custom Settings Methods (Apex 開発者ガイド: カスタム設定メソッド)
-
Salesforce ヘルプ: カスタム設定の定義