Salesforce 指定ログイン情報: 安全な API コールアウトのための包括的ガイド

Salesforce 統合エンジニアとして、私は日々、Salesforce プラットフォームと多種多様な外部システムとの連携に取り組んでいます。セキュアで、かつメンテナンス性の高いインテグレーションを構築することは、我々の最重要課題の一つです。今回は、その鍵となる Salesforce の強力な機能、Named Credentials (指定ログイン情報) について、その仕組みからベストプラクティスまでを深く掘り下げて解説します。


背景と応用シナリオ

Salesforce から外部の Web サービスへ API (Application Programming Interface) コールアウトを行う、という要件は非常によくあります。例えば、以下のようなシナリオです。

  • 顧客の住所情報をもとに、外部の地図情報サービスの API を呼び出して緯度経度を取得する。
  • 商談が成立した際に、外部の ERP (Enterprise Resource Planning) システムに注文情報を作成する。
  • 外部の決済代行サービスの API を利用して、クレジットカード決済処理を実行する。

従来、このような連携を実装する際には、いくつかの課題がありました。最も一般的なアンチパターンは、Apex コード内にエンドポイント URL や認証情報(API キー、パスワードなど)を直接ハードコーディングしてしまう方法です。

このアプローチには、以下のような深刻な問題が潜んでいます。

  1. セキュリティリスク: 認証情報がコード内に平文で保存されるため、コードにアクセスできる誰もがそれを閲覧できてしまいます。これは重大なセキュリティホールです。
  2. メンテナンス性の低下: エンドポイント URL が変更された場合(例えば、サンドボックス環境から本番環境へ移行する際や、外部サービスのドメインが変更された場合)、あるいは認証情報が更新された場合には、コードを修正し、再テストを行い、再デプロイするという手間が発生します。

カスタムメタデータやカスタム設定に情報を保存する方法もありますが、認証情報を安全に管理するという点では、依然として課題が残ります。そこで登場するのが Named Credentials (指定ログイン情報) です。Named Credentials は、コールアウトのエンドポイント URL と、その認証情報を Salesforce プラットフォーム上で一元的に、かつ安全に管理するための仕組みです。これにより、開発者は認証情報の管理という煩雑な作業から解放され、ビジネスロジックの実装に集中できるようになります。


原理の説明

Named Credentials の核心は、「コールアウト先のエンドポイント定義」「認証プロセスの抽象化」にあります。開発者はコード内で具体的な URL や認証情報を記述する代わりに、設定された Named Credential の名前を指定するだけで、Salesforce が裏側で認証処理を含むすべてをハンドリングしてくれます。

Named Credential を設定する際には、主に以下の要素を定義します。

URL

コールアウト先となる外部サービスのベース URL を指定します。例えば、`https://api.example.com/v1` のような形式です。Apex コードからは、このベース URL に続く具体的なパス(例: `/orders`)を指定してリクエストを送信します。

Identity Type (ID 種別)

誰の権限で外部サービスにアクセスするかを定義します。主な選択肢は以下の通りです。

  • Named Principal (指定ユーザ): 最も一般的なタイプで、システム間連携に使用されます。Salesforce 組織全体で共有される一つの認証情報(例: 統合専用ユーザの ID/パスワードや API キー)を用いて、すべてのコールアウトが行われます。
  • Per User (ユーザごと): Salesforce の各ユーザが、個別に外部サービスのアカウントで認証を行います。例えば、「Google Drive と連携する」といった機能の場合、各ユーザが自身の Google アカウントで認証する必要があります。このタイプでは、主に OAuth 2.0 が利用されます。
  • Anonymous (匿名): 認証が不要な公開 API などに対して使用します。

Authentication Protocol (認証プロトコル)

外部サービスが要求する認証方式を選択します。

  • Password Authentication: ユーザ名とパスワードを用いた Basic 認証です。
  • OAuth 2.0: 現在の Web サービス連携における標準的な認証方式です。Salesforce の「認証プロバイダ」機能と連携し、アクセストークンの取得や更新といった複雑なフローを自動化してくれます。
  • JWT (JSON Web Token): JWT を用いた認証フローです。
  • JWT Token Exchange: 異なるサービス間で ID を連携するための高度な認証フローです。

これらの設定を一度行えば、Apex コードからは非常にシンプルな記述でコールアウトを実行できます。コードは `callout:My_Named_Credential_Name/some_path` という特殊な URL 形式を使用します。Salesforce はこの `callout:` プレフィックスを認識すると、指定された Named Credential の設定を読み込み、URL を解決し、必要な認証ヘッダー(例: `Authorization: Bearer ` や `Authorization: Basic `)を自動的に付与してリクエストを送信します。

この仕組みにより、認証情報がコードから完全に分離され、Salesforce のセキュアなストレージで管理されるため、セキュリティが大幅に向上します。また、本番環境とサンドボックスで異なるエンドポイントや認証情報を使用する場合でも、コードを変更することなく、各環境の Named Credential の設定値を変更するだけで対応可能となり、メンテナンス性が劇的に改善されます。


サンプルコード

ここでは、`My_Awesome_Service` という名前の Named Credential (Identity Type: Named Principal, Authentication Protocol: Password Authentication) を使用して、外部の REST API から注文情報を取得する Apex コードの例を示します。このコードは Salesforce の公式ドキュメントで紹介されている標準的な実装方法に基づいています。

// HttpRequest オブジェクトのインスタンスを作成します。
// これは、送信する HTTP リクエストのすべての要素(メソッド、エンドポイント、ヘッダー、ボディなど)をカプセル化します。
HttpRequest req = new HttpRequest();

// setEndpoint メソッドを使用して、リクエストの送信先を指定します。
// 'callout:My_Awesome_Service/orders/12345' という形式に注目してください。
// 'callout:' は、これが Named Credential を介したコールアウトであることを Salesforce プラットフォームに伝えます。
// 'My_Awesome_Service' は、設定画面で定義した Named Credential の API 参照名です。
// '/orders/12345' は、Named Credential に設定されたベース URL に追加されるパスです。
// 例えば、ベース URL が 'https://api.example.com/v1' であれば、
// 実際のエンドポイントは 'https://api.example.com/v1/orders/12345' となります。
req.setEndpoint('callout:My_Awesome_Service/orders/12345');

// HTTP メソッドを 'GET' に設定します。
// これは、リソースを取得するための標準的なメソッドです。
req.setMethod('GET');

// Http オブジェクトのインスタンスを作成します。
// このオブジェクトが、実際にリクエストを送信し、レスポンスを受信する役割を担います。
Http http = new Http();

// send メソッドを実行して、作成した HttpRequest を外部サービスに送信します。
// このメソッドは同期的に動作し、レスポンスが返ってくるまで実行をブロックします。
// レスポンスは HttpResponse オブジェクトとして返されます。
// Salesforce はこの send が実行されるタイミングで、Named Credential の設定に基づき、
// 認証ヘッダー(例: 'Authorization: Basic ...')を自動的にリクエストに追加します。
HttpResponse res = http.send(req);

// レスポンスのステータスコードを確認します。
// 200 は成功(OK)を意味します。
if (res.getStatusCode() == 200) {
    // getBody メソッドでレスポンスのボディ(通常は JSON や XML 形式のデータ)を文字列として取得します。
    // 取得したデータは、後続の処理(例: JSON のパース、Salesforce オブジェクトへのマッピング)で使用します。
    System.debug('成功: レスポンスボディ -> ' + res.getBody());
} else {
    // 200 以外のステータスコードは、何らかのエラーを示しています(例: 404 Not Found, 500 Internal Server Error)。
    // エラーハンドリングをここで行います。
    System.debug('エラー: ステータスコード -> ' + res.getStatusCode());
    System.debug('エラー: レスポンスボディ -> ' + res.getBody());
}

このコードからわかるように、認証情報を扱うための記述は一切ありません。ユーザ名、パスワード、アクセストークンといった機密情報はコードから完全に排除されています。開発者は、どの Named Credential を使うかを指定するだけでよいのです。


注意事項

Named Credentials を利用する際には、以下の点に注意する必要があります。

権限 (Permissions)

  • Named Credentials を作成・編集するには、「アプリケーションのカスタマイズ」権限を持つ管理者である必要があります。
  • Identity Type が「Per User」の場合、ユーザがその Named Credential を利用したコールアウトを実行するためには、プロファイルまたは権限セットを通じて、該当する External Credential Principal Access (外部ログイン情報プリンシパルアクセス) へのアクセス権が付与されている必要があります。

API 制限 (API Limits)

Named Credentials を使用しても、Salesforce の Governor Limits (ガバナ制限) が免除されるわけではありません。1 トランザクションあたりのコールアウト回数(最大 100 回)、コールアウトのタイムアウト(最大 120 秒)、ヒープサイズなどの制限は、通常通り適用されます。大量のコールアウトを行う場合は、非同期処理(@future, Queueable, Batch Apex)の利用を検討してください。

エラー処理 (Error Handling)

外部システムとの連携では、ネットワークの問題や相手先システムのエラーなど、予期せぬ事態が発生する可能性があります。コールアウト処理は、必ず `try-catch` ブロックで囲み、`System.CalloutException` などの例外を捕捉するようにしてください。また、レスポンスを受け取った後は、`HttpResponse.getStatusCode()` を確認し、成功(2xx)以外のステータスコードに応じた適切なエラー処理を実装することが不可欠です。

管理パッケージでの利用

管理パッケージに Named Credential を含める場合、Apex コードから参照する際には名前空間プレフィックスが必要になります(例: `callout:my_namespace__My_Credential/path`)。インストール先の組織で URL などの設定を上書き変更できるため、柔軟な構成が可能です。


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

Named Credentials は、現代の Salesforce インテグレーション開発において、もはや必須の機能と言えるでしょう。その主な利点を再確認します。

  • セキュリティの向上: 認証情報をコードから分離し、プラットフォーム上で安全に管理します。
  • メンテナンス性の向上: エンドポイントや認証情報の変更を、コードの修正なしに設定だけで対応できます。
  • コードの簡素化: 認証ロジックを自前で実装する必要がなくなり、Apex コードがシンプルかつクリーンになります。

最後に、Salesforce 統合エンジニアとして推奨するベストプラクティスをいくつか挙げます。

  1. 常に Named Credentials を使用する: 新規のインテグレーション開発では、ハードコーディングやカスタム設定の利用を避け、必ず Named Credentials を採用してください。
  2. 適切な Identity Type を選択する: システム間連携なら「Named Principal」、ユーザ個別の認証が必要なら「Per User」を正しく使い分けましょう。
  3. 環境ごとの設定を活用する: サンドボックスではテスト用エンドポイントを、本番組織では本番用エンドポイントを設定することで、コードの共通化とデプロイの簡素化を実現します。
  4. 外部サービス (External Services) との組み合わせを検討する: OpenAPI (Swagger) 仕様が提供されている REST API であれば、「外部サービス」機能と Named Credentials を組み合わせることで、Apex コードを一行も書かずにインテグレーションを実装できる場合があります。
  5. 最小権限の原則: 「Named Principal」で利用する統合ユーザの認証情報は、連携に必要な最小限の権限のみを外部システム側で付与するようにしてください。

Named Credentials を正しく理解し、活用することで、あなたの Salesforce インテグレーションはよりセキュアで、堅牢で、そして未来の変化に対応しやすいものになるはずです。

コメント