進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

プラットフォーム機能を使用した秘密の保護

学習の目的

この単元を完了すると、次のことができるようになります。

  • 管理パッケージ内に秘密を格納するオプションと推奨方法を挙げる。
  • コールアウトエンドポイントおよび関連付けられた認証パラメータを安全に定義するために指定ログイン情報を作成する。
  • 保護されたカスタム設定保護されたカスタムメタデータ API 項目を、秘密を格納するためにどのように活用できるのかを説明する。

Salesforce でのアプリケーションの秘密の格納

最初の単元で、秘密を特定する方法および誰がアクセス権を持つべきかを学習しました。次のステップでは、秘密を保護する方法を学習します。

幸い、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 つの問題があります。

  1. ソースコードを表示できるユーザは、埋め込まれた秘密も表示できる。
  2. 秘密が更新されると、ソースコード内の秘密のインスタンスをすべて変更する必要がある。
  3. この秘密をアプリケーション間でポーティングすると、その他に多くの複雑な問題が生じる可能性がある。

これらの問題を解決するのが指定ログイン情報です。コードに値をハードコードするのではなく、指定ログイン情報を活用して秘密を保存すると、コード内のその他の変数と同様に、指定ログイン情報を参照して秘密の値にアクセスできます。

値自体の代わりに指定ログイン情報を使用する場合、システム管理者プロファイルを使用するユーザと、「すべてのデータの参照」および「すべてのデータの編集」権限を持つユーザのみが値にアクセスできます。

指定ログイン情報の利点

指定ログイン情報は、アプリケーションの秘密へのアクセスを制限する手段となるだけでなく、これらの秘密の管理を容易にします。指定ログイン情報を設定した後、必要な場合には設定でいつでも簡単に変更できます。そうすると、秘密を参照するコード内のインスタンスは、指定ログイン情報を直接参照するので、古い値が保持されることはありません。

さらに、指定ログイン情報は、数回クリックするだけで [設定] から作成できます。では、実際に試してみましょう。

指定ログイン情報の使用

Kingdom Management 組織には、外部サービスと通信するアプリケーションがあります。この通信を保護するために、指定ログイン情報を作成します。

  1. Kingdom Management 組織にログインして、Secret Storage アプリケーションを選択します。

  2. [Named Credentials Demo (指定ログイン情報デモ)] タブをクリックします。

    learn-about-platform-secret-protection

  3. 王国の民は、このアプリケーションを使用して、ひっそりとした場所にある「不老の泉」につながる魔法のポータルを開きます。ただし、このポータルは魔法で守られており、正しい秘密のパスワードを持っている者のみがポータルを通過できます。王族のみがポータルをいつでも安全に通過できるようにするために、彼らが使用する指定ログイン情報を設定しましょう。

  4. [Setup (設定)] の [Home (ホーム)] タブから、[Quick Find (クイック検索)] ボックスに「Named Credentials」(指定ログイン情報) と入力し、[Named Credentials (指定ログイン情報)] を選択します。

  5. [New Named Credential (新規ログイン情報)] をクリックします。

  6. 次のパラメータを使用して、魔法のポータルのアクセスコードを格納する指定ログイン情報を作成します。

  7. Label (表示ラベル)
    MagicPortal
    Name (名前)
    MagicPortal
    URL
    https://secret-storage.herokuapp.com/
    Certificate (証明書)
    空白
    Identity Type (ID 種別)
    Named Principal (指定ユーザ)
    Authentication Protocol (認証プロトコル)
    Password Authentication (パスワード認証)
    Username (ユーザ名)
    MagicWords
    Password (パスワード)
    hocus-pocus

    指定ログイン情報のスクリーンショット

  8. [Save (保存)] をクリックします。


指定ログイン情報を設定したので、それをアプリケーションに追加できます。

  1. [Named Credentials (指定ログイン情報)] タブに移動します。
  2. ページ下部にある [Apex Controller (Apex コントローラ)] リンクをクリックします。
  3. 新しく設定した指定ログイン情報を使用するように getOpenPortal 関数を更新します。

  public void getOpenPortal() { 
    HttpRequest req = new HttpRequest(); 
    req.setEndpoint('callout:MagicPortal'); 
    req.setMethod('GET'); Http http = new Http(); 
    HTTPResponse res = http.send(req); 
    portalStatus res.getBody(); 
  }


設定を行う場合と同様、指定ログイン情報はこのように簡単に使用できます。HTTP エンドポイントとして callout:MagicPortal を含めるだけで、Apex コードは事前設定されたログイン情報を外部システムへ送信します。システム管理者 (もしくは「すべてのデータの編集」権限を持つユーザ) がシステム内に指定ログイン情報を作成したら、開発者は、Apex コードでその指定ログイン情報を参照するために秘密の値を知っておく必要がなくなります。
必要なのは、これらの値が含まれている指定ログイン情報の名前のみです。

  1. [Named Credentials Demo (指定ログイン情報デモ)] タブに移動します。

  2. [Cast Spell (魔法をかける)] をクリックします。

ポータルが泉につながることを示すスクリーンショット

すばらしいですね。指定ログイン情報を使用してポータルを開きました。これで王族と忠実な従者のみが永遠の若さを手に入れることができます。

指定ログイン情報を使用する場合と使用しない場合

指定ログイン情報の設定はかなり簡単にできますが、必ずしもすべての使用事例に適しているわけではありません。指定ログイン情報は、ユーザ名とパスワード、または OAuth 2.0 などの単純な認証スキーマに最適です。

指定ログイン情報は、組織のシステム管理者と開発者の作業を簡単で安全にします。とは言っても、それが常に最適な選択とは限りません。「すべてのデータの編集」または「Apex 開発」権限を持つユーザは、指定ログイン情報を変更したり、コールアウトを実行したりできるので、指定ログイン情報で保護されているデータにもアクセスできます。または、高度なユーザであれば、資格情報を抽出できる可能性があります。独自のクラウドサービスと非公開で通信する必要があるパッケージを作成する ISV など、このような使用事例に対する保護が必要な場合は、管理および保護されたカスタム設定やカスタムメタデータ型など他のオプションを使用することを検討してください。詳細は以下を参照してください。

配布される秘密の保護

指定ログイン情報は、関連付けられた認証の秘密にシステム管理者がアクセスすることが許可されている組織で、外部サービスへのコールアウトが実行される場合に最適です。では、システム管理者がデータを表示できないようにしたり、秘密を複数の Salesforce 組織に配布したりする場合は、どうしたらよいのでしょうか?

このような場合は、コードを管理パッケージという形式でリリースします。無料の Developer Edition 組織に簡単にサインアップし、コードのパッケージ化組織として使用できます。AppExchange パートナーの場合、DE 組織は環境ハブで作成できます。また、Developer Edition サインアップページからでも作成できます。パッケージ化組織内で、Apex クラス、Visualforce ページ、Apex トリガ、Salesforce オブジェクト、およびその他の一般的なメタデータの形式を管理パッケージにまとめて、他の Salesforce インスタンスおよび組織に簡単にリリースできます。管理パッケージは、zip ファイルを複雑化したバージョンと考えることができます。

セキュリティという観点から、未管理パッケージまたは疎結合コードではなく、管理パッケージを使用することには大きな利点が多数あります。

  • セキュリティの脆弱性が確認された場合に、自動更新、パッチ、修正を転送するためのメカニズムが含まれています。
  • 非表示にされたソースコードが含まれています (明示的に公開されたグローバル Apex クラスを除く)。つまり不注意で壊されたり、悪意のある変更を加えて再配布されたりしないように、基本的なビジネスまたはプログラムロジックは改変できないようになっています。また、非表示にされたコードは、パッケージに格納されている秘密が表示されるのを防ぎます。
  • 管理パッケージには一意の名前空間を定義する必要があるので、名前空間の競合問題が起こりません。また、ローカルの名前空間からパッケージが分離されるので、パッケージに格納されている秘密の保護がさらに強化されます。デフォルトで、パッケージの秘密は、管理パッケージ外で実行されるコードでアクセスすることはできません。

アプリケーションとメタデータのパッケージ化についての詳細は「AppExchange アプリケーション開発」モジュールを参照してください。

管理および保護されたカスタム設定とカスタムメタデータ型

管理パッケージ内でコードをパッケージ化するだけでも多くのセキュリティ上の利点が多くありますが、管理パッケージを使用すると、保護されたカスタム設定と保護されたカスタムメタデータという、情報の格納と配布に使用できる 2 つの機能へのアクセス権が付与されます。

カスタム設定は、作成することでほぼどのデータでも格納でき、用途とコンテンツという点ではきわめて柔軟性に優れています。要約すると、カスタム設定ではアプリケーションキャッシュに公開されるカスタムデータセットを作成できるため、データベースへのクエリを繰り返さず、アプリケーションの効率が高くなります。たとえば、カスタム設定は、アプリケーションでユーザエクスペリエンスをパーソナライズするために使用されるデータセットを格納するために使用できます。または、カスタム設定を作成して、すぐ簡単にアクセスできるように、さまざまなページで参照される商品名のリストを格納できます。アプリケーションのセキュリティという点では、カスタム設定を使用して機密情報や秘密を格納できます。

カスタム設定には、さまざまな表示レベルがあります。管理パッケージに含まれている保護されたカスタム設定は、Apex または API では登録組織に表示されないため、特定の種類の秘密を格納するのに適した場所です。表示が公開に設定されている、または未管理パッケージに含まれているカスタム設定は、Enterprise WSDL を使用して表示できます。そのため、機密情報を格納する場合、保護されたカスタム設定が管理パッケージ内でカプセル化されていることが重要です。

カスタムメタデータ項目は、カスタム設定と似たような方法で、秘密を格納する場所として利用できます。秘密を守るためには、表示を ‘protected’ に設定し、管理パッケージ内に含めます。保護されたカスタムメタデータ API 項目は、API キーやその他の秘密キーを格納するのに適した場所です。


表示設定では、カスタム設定とメタデータ項目の両方に、いくつかのオプションが用意されています。

  1. 公開 (ローカル)
  2. 保護 (ローカル)
  3. 公開 (管理)
  4. 保護 (管理)

一般的にデータの格納には最初の 3 つのオプションが実行可能ですが、これらの設定を使用すると、組織のすべてのユーザがデータ値を表示できるようになります。これらのオプションは、公開されているデータを格納する場合にのみ使用します。アプリケーションの秘密のような機密データには、管理および保護された設定オプションを使用します。 

非表示オプション、アクセスの容易さ、キャッシュ機能という利点があるカスタム設定とメタデータ項目は、秘密を格納する場所として、実行可能で魅力的なオプションです。

管理および保護されたカスタム設定

秘密を安全に保護するために使用する、管理および保護されたカスタム設定を作成して Kingdom Secrets という名前を付けます。[Setup (設定)] の [Quick Find (クイック検索)] ボックスで検索して [Custom Settings (カスタム設定)] に移動し、[New (新規)] をクリックして保護されたカスタム設定を作成します。Label (表示ラベル)、Object Name (オブジェクト名)、Setting Type (設定種別)、Visibility (表示) ([Protected (保護)] に設定) を定義します。これらのデータ型についての詳細は、こちらを参照してください。[Save (保存)] をクリックすると、秘密を格納するカスタム項目の追加準備が整います。

カスタム設定のスクリーンショット

最後に、保護されたカスタム項目に秘密を入力します。パッケージには設定の定義のみが含まれるので、パッケージが対象組織または登録者組織にインストールされたら、Apex または API スクリプトを使用して秘密を入力する必要があります。

管理および保護されたカスタム設定の使用方法

カスタム設定は、カスタムオブジェクトを参照するのと同じように参照できます。カスタム設定にアクセスするには、数式項目、Apex カスタム設定メソッド、SOAP API、入力規則、フローなどを使用できます。保護されたカスタム設定の参照は、同じ管理パッケージ (つまり同じ名前空間) 内からのみ行うことができます。カスタム設定を参照する一般的な Apex メソッドは、次のとおりです。

  • getAll()
  • getValues()
  • getOrgDetauls()
  • getInstance(Profile_ID)

次に、カスタム設定コンポーネントとして格納された秘密にアクセスするために、getAll() を使用する例を示します。

Map<String_dataset_name, CustomSettingName__c> mcs = CustomSettingName__c.getAll();


簡単でしょう? カスタム設定とその設定方法についての詳細は『Apex 開発者ガイド』を参照してください。

カスタムメタデータ型

カスタム設定で定義したときと同じような方法で、保護されたカスタムメタデータ型も秘密を保持するように定義できます。すでに説明したとおり、カスタムメタデータ型を効果的に非表示にして保護するには、管理パッケージ内に含まれるように設計する必要があります。その名のとおり、カスタム設定との主な違いは、カスタムメタデータ型に格納されるデータは、アプリケーションのメタデータを表すということです。このセクションで説明するように、これが有利に働く場合が多々あります。

あなたは、Developer Edition のパッケージ化組織で新しいアプリケーションを作成している開発者だとします。このアプリケーションには、example.com との外部 API インテグレーションなど、さまざまな優れた機能があります。Example.com へのコールアウトを実行するには、API キーをどこかに格納する必要があります。1 つの方法は、カスタム項目内に API 秘密キーを格納することです。自分の DE 組織内では正常に動作しますが、このアプローチの問題点はなんでしょうか? 安全ではないうえに、再リリースに関する問題があります。すべてのコードとカスタマイズを本番組織に移動するとき、秘密キーの値は同時には転送されません。「変更管理」モジュールを修了した方はすでに学習したとおり、変更セットでは、データは本番組織に移動されません。項目にキー値を手動で入力するか、自動入力するスクリプトを作成する必要があります。一方、カスタムメタデータ型では、API 秘密キーはその他のカスタマイズと同じように扱われ、本番環境に移動されます。そのため、手動で再入力する必要がありません。

前述したように、カスタム設定でデータを読み込むには、なんらかの postinstall スクリプトを作成する必要があります。それに対して、保護されたカスタムメタデータ型の場合は、スクリプトを作成する必要はありません。カスタムメタデータ型に格納されたデータは、別個のメタデータとして使用できます。これをパッケージに追加できます。すばらしいですね。

カスタムメタデータ型の優れている点の 1 つは、他のカスタムオブジェクトのように、SOQL を使用して取り込めることです。唯一の違いは、メタデータ型で使用されるサフィックスが、__c ではなく、__mdt であるということです。カスタムメタデータ型を選択する場合は、次のようなクエリを作成します。

SELECT Cavalry__c, Infantry__c, Weapon__c , Armor__c FROM Secret_Defenses__mdt 

この行は、Secret_Defenses__mdt のすべての値を取得します。非常に簡単です。


管理パッケージでのカスタムメタデータ型の実装についての詳細は「カスタムメタデータ型」モジュールを参照してください。

カスタム設定とカスタムメタデータ型の比較

秘密を保護するための選択肢として、カスタム設定とカスタムメタデータ型とが使用できますが、これら 2 つには注目すべき違いがいくつかあります。

保護されたカスタム設定は、次のような場合に使用します。

  1. 頻繁に秘密が更新され、更新後すぐに使用可能である必要がある。メタデータ型はキューに追加してリリースされる必要があるので、メタデータ型の秘密が更新されても、すぐには使用できません。この場合はカスタム設定の使用が適しています。
  2. どの秘密にどのプロファイルとユーザがアクセスできるのかを指定する必要がある。メタデータ型には、秘密にアクセスできるプロファイルまたはユーザを指定できるカスタム設定階層のような粒度がありません。そのため、この場合はカスタム設定の使用が適しています。

カスタムメタデータ型は、次のような場合に使用します。

  1. 追加の設定ステップを実行せずに、一般的な秘密をリリースする必要がある。
  2. カスタムメタデータの秘密は、Salesforce の変更管理を使用して、たとえば Sandbox または開発環境から本番環境に簡単に移行できます。カスタム設定では、通常 Sandbox から本番環境に移行するときに、システム管理者が postinstall スクリプトか Visualforce ページのどちらかを作成して、新しい環境に秘密を手動で入力して格納する必要があります。

リソース

Apex 開発者ガイド: コールアウトエンドポイントとしての指定ログイン情報

Salesforce 開発者ブログ: How to use custom metadata types (カスタムメタデータ型の使用方法) 

Apex 開発者ガイド: カスタム設定メソッド