PCI準拠のSalesforce環境を設計する:アーキテクトのための包括的ガイド

Salesforceアーキテクトとして、堅牢でスケーラブル、そして何よりも安全なソリューションを設計することが私たちの使命です。特に、金融取引や顧客の支払い情報を扱うシステムを構築する際、PCI DSS (Payment Card Industry Data Security Standard, ペイメントカード業界データセキュリティ基準) への準拠は避けて通れない最重要課題となります。本記事では、Salesforceアーキテクトの視点から、PCI準拠を達成するためのアーキテクチャ設計の原則、ベストプラクティス、そして具体的な考慮事項について深く掘り下げていきます。


背景と適用シナリオ

PCI DSSは、クレジットカード会員データを保護し、安全な決済環境を維持するために策定された一連の技術的および運用的要件です。クレジットカード情報を保存、処理、または伝送するすべての組織は、この基準に準拠する義務があります。

Salesforceプラットフォーム上で、以下のようなシナリオを実装する場合、PCIコンプライアンスの考慮が不可欠となります。

  • Eコマース連携: Salesforce Commerce Cloudや、AppExchangeのEコマースソリューションを利用し、Salesforce内で注文と支払いを管理する場合。
  • コールセンターでの支払い受付: Service Cloudを利用しているコンタクトセンターで、顧客が電話口でクレジットカード番号を伝えて支払いを行う場合。
  • サブスクリプション管理: 定期的な支払いを伴うサブスクリプションモデルのビジネスで、Salesforceを顧客管理と請求のハブとして利用する場合。
  • イベントや寄付の受付: Experience Cloud (旧Community Cloud) 上で、イベント参加費や寄付金をクレジットカードで受け付ける場合。

これらのシナリオでアーキテクトが直面する最大の挑戦は、「いかにしてSalesforceプラットフォームをPCI DSSの監査対象範囲(スコープ)から外すか、あるいは最小限に留めるか」という点にあります。スコープが広がれば広がるほど、準拠のためのコスト、労力、そしてリスクは指数関数的に増大します。

原理説明

Salesforce環境におけるPCIコンプライアンス設計の核心は、「カード会員データ(Cardholder Data, CHD)をSalesforceプラットフォームに直接触れさせない」という原則に集約されます。これを実現するための主要な技術的アプローチは以下の通りです。

1. トークン化 (Tokenization)

トークン化は、PCIコンプライアンスアーキテクチャの基盤となる最も重要な概念です。このアプローチでは、実際のクレジットカード番号(Primary Account Number, PAN)を、トークンと呼ばれる、機密性のない一意の識別子に置き換えます。

仕組み:

  1. ユーザーは、支払い情報をWebフォーム(通常は決済代行会社が提供するiframe)に入力します。
  2. この情報は、Salesforceサーバーを経由せず、直接PCI準拠の決済代行会社(Payment Gateway)のサーバーに送信されます。
  3. 決済代行会社は、受け取ったカード情報を自社の安全な保管庫(Vault)に保存し、代わりにトークンを生成してクライアント(ブラウザ)に返します。
  4. クライアントは、このトークンをSalesforceに送信します。
  5. Salesforceは、実際のカード情報の代わりに、この安全なトークンのみを顧客レコードや取引レコードに関連付けて保存します。

このアーキテクチャにより、Salesforceは機密情報であるCHDを一切保持・処理しないため、PCI DSSのスコープを劇的に削減できます。

2. iFrameとホストされた決済ページ

トークン化を実装する具体的な方法として、決済代行会社が提供するiFrameやホストされた決済ページ(Hosted Payment Pages)の利用が一般的です。Lightning Web Components (LWC) や Visualforceページ内に決済代行会社のiFrameを埋め込むことで、カード情報の入力フィールド自体がSalesforceのドメインではなく、決済代行会社のドメインから提供されます。これにより、ユーザーのブラウザから決済代行会社へ直接データが送信され、Salesforceサーバーは一切経由しません。

3. Salesforce Shield Platform Encryptionの役割

Salesforce Shield Platform Encryption (プラットフォーム暗号化) は、Salesforce内に保存されたデータを保存時(at-rest)に暗号化する強力なツールです。しかし、ここでアーキテクトとして明確に理解しておくべき重要な点があります。Shieldを使ってクレジットカード番号を暗号化して保存することは、PCI準拠のためのベストプラクティスでは「ありません」。

なぜなら、たとえデータが暗号化されていても、Salesforceプラットフォーム上でCHDを「保存」および「処理」しているという事実に変わりはなく、組織のSalesforce環境全体がPCI DSSの厳格な監査スコープに含まれてしまうからです。これには、暗号鍵の管理、アクセスログの厳格な監視、侵入検知システムの導入など、膨大な追加要件が伴います。したがって、ShieldはPII(個人識別情報)など他の機密データを保護するためには非常に有効ですが、CHDの保存を目的として使用するべきではありません。

4. 責任共有モデル (Shared Responsibility Model)

Salesforceは、サービスプロバイダとしてPCI DSSに準拠しています。これは、Salesforceのデータセンターやインフラが安全であることを意味します。しかし、その上で顧客が構築するアプリケーションやビジネスプロセスのコンプライアンスは、顧客自身の責任です。アーキテクトは、この責任共有モデルを深く理解し、自社の責任範囲において適切な設計と管理策を講じる必要があります。


サンプルコード

前述の通り、Salesforce内で直接CHDを扱うべきではありません。代わりに、フロントエンドで取得した決済トークンをApexコントローラで受け取り、決済代行会社のAPIを呼び出して決済を処理するのが正しいアプローチです。以下のサンプルコードは、LWCから渡された決済トークンと金額を使い、決済代行会社へサーバー間(server-to-server)のAPIコールを行うApexメソッドの例です。このコードは、Salesforceの公式ドキュメントにあるHTTPコールアウトの標準的な例に基づいています。

public with sharing class PaymentGatewayController {

    // LWCから呼び出されるAuraEnabledメソッド
    // @param paymentToken フロントエンドで決済代行会社から取得した非機密トークン
    // @param amount 請求金額
    // @param orderId 関連する注文のID
    @AuraEnabled
    public static String processPayment(String paymentToken, Decimal amount, String orderId) {

        // 決済代行会社のAPIエンドポイント。実際には指定ログイン情報(Named Credential)を使用すべき
        String endpoint = 'https://api.paymentgateway.com/v1/charges';

        // HttpRequestオブジェクトのインスタンスを作成
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('POST');
        
        // ヘッダーを設定。APIキーは指定ログイン情報で管理するのがベストプラクティス
        // ここでは例としてハードコードしていますが、本番環境では絶対に行わないでください。
        req.setHeader('Authorization', 'Bearer sk_test_your_api_key'); 
        req.setHeader('Content-Type', 'application/json;charset=UTF-8');

        // 送信するJSONボディを構築
        // 実際のカード情報は含まれず、安全なトークンのみを使用
        Map<String, Object> bodyMap = new Map<String, Object>{
            'amount' => amount * 100, // 金額はセント単位で指定することが多い
            'currency' => 'jpy',
            'source' => paymentToken, // ここでトークンを使用
            'description' => 'Charge for Order ID: ' + orderId
        };
        String body = JSON.serialize(bodyMap);
        req.setBody(body);

        // Httpオブジェクトを使ってリクエストを送信
        Http http = new Http();
        String transactionId = null;

        try {
            HttpResponse res = http.send(req);

            // レスポンスを処理
            if (res.getStatusCode() == 200) {
                // 成功した場合、レスポンスボディから取引IDなどを抽出
                Map<String, Object> responseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
                transactionId = (String) responseMap.get('id');
                
                // ここでSalesforceのOrderレコードなどを更新するロジックを実装
                // updateOrderStatus(orderId, transactionId, 'Success');

                return 'Payment successful. Transaction ID: ' + transactionId;
            } else {
                // エラー処理
                System.debug('Error calling payment gateway: ' + res.getStatusCode() + ' ' + res.getBody());
                // Apex例外をスローしてフロントエンドにエラーを伝える
                throw new AuraHandledException('Payment failed: ' + res.getStatus());
            }
        } catch(System.CalloutException e) {
            // コールアウト例外の処理
            System.debug('Callout error: '+ e.getMessage());
            throw new AuraHandledException('Could not connect to the payment gateway.');
        }

        return null;
    }
}

注釈:このコードは、決済代行会社へのAPIコールアウトの基本的な構造を示しています。アーキテクトとして重要なのは、APIキーのような機密情報をコードにハードコードせず、Salesforceの指定ログイン情報 (Named Credential) を使用して安全に管理・参照する設計を徹底することです。


注意事項

PCI準拠のシステムを設計・維持する上で、以下の点に特に注意が必要です。

  • データセキュリティの徹底: CHDを保存しない場合でも、顧客名や住所などのPIIは保護対象です。項目レベルセキュリティ、プロファイル、権限セットを適切に設定し、最小権限の原則を遵守してください。必要に応じてSalesforce Shieldを利用してPIIを暗号化します。
  • 安全なインテグレーション: 決済代行会社とのAPI連携では、必ずTLS 1.2以上の暗号化通信を使用します。また、前述の通り、認証情報は指定ログイン情報で管理し、外部システムの証明書を適切に管理してください。
  • ヒューマンエラーの防止: 最も脆弱なのは「人」です。ユーザーが誤ってクレジットカード番号を「説明」や「活動」などの標準項目に入力してしまうリスクがあります。データ損失防止(DLP)の仕組みを検討したり、入力規則やトリガで特定のパターン(例:16桁の数字)を検知して警告する仕組みを導入したり、そして何よりも定期的なユーザートレーニングが不可欠です。
  • サンドボックスのデータ管理: 本番環境のデータをサンドボックスにコピーする際は、データマスキングツールを使用して、PIIや決済トークンなどの機密情報をマスクまたは匿名化するプロセスを確立してください。
  • 監査と監視: セットアップ監査証跡、項目履歴管理、そして可能であればShieldのイベントモニタリングを活用し、重要なオブジェクトや設定へのアクセスと変更を継続的に監視する体制を整えることが重要です。
  • AppExchangeアプリの評価: 決済処理に関わるAppExchangeアプリを導入する際は、そのアプリがPCIに準拠しているか、どのようなセキュリティ対策を講じているかをベンダーに確認し、慎重に評価する必要があります。

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

SalesforceアーキテクトとしてPCI準拠のソリューションを設計する際のゴールは、テクノロジーを駆使してコンプライアンスの負担とリスクを最小化することです。以下に、そのためのベストプラクティスをまとめます。

  1. スコープ削減を最優先せよ: 何よりもまず、Salesforceプラットフォーム上でクレジットカード会員データ(CHD)を保存、処理、伝送しないアーキテクチャを選択します。トークン化がこの原則を実現するための業界標準です。

  2. 決済代行会社を最大限に活用せよ: 決済代行会社が提供するiFrameやホストされた決済ページを積極的に利用し、CHDがSalesforceサーバーに到達する経路を完全に遮断します。

  3. 多層防御(Defense-in-Depth)を実装せよ: トークン化という主要な対策に加え、厳格なアクセス制御、安全なインテグレーションパターン(指定ログイン情報)、ユーザー教育、継続的な監視を組み合わせ、多層的なセキュリティを構築します。

  4. 責任共有モデルを理解し、啓蒙せよ: Salesforceが提供する安全な基盤と、自社が実装するアプリケーションの安全性は別物であることを、開発チームやビジネス関係者に明確に伝え、組織全体のセキュリティ意識を高めます。

  5. コンプライアンスを継続的なプロセスと捉えよ: PCI準拠は一度達成すれば終わりではありません。定期的なアーキチャレビュー、脆弱性スキャン、監査を通じて、システムの安全性を継続的に維持・改善していくプロセスを設計に組み込みます。

最終的に、優れたPCI準拠アーキテクチャは、規制要件を満たすだけでなく、企業のブランド価値を守り、顧客からの信頼を勝ち取るための重要な基盤となります。私たちの役割は、その基盤を技術的に正しく、かつビジネス価値を最大化する形で設計することにあるのです。

コメント