DLP API を使用した SAP のデータ保護

このドキュメントでは、ABAP SDK for Google Cloud の SAP BTP エディションCloud Data Loss Prevention(DLP)API を使用して、SAP の機密性の高い企業データを保護するためのリファレンス アーキテクチャについて説明します。

SAP に保存される個人情報(PII)などの機密性の高い企業データを保護することはきわめて重要です。SAP の機密性の高い企業データを不適切な相手やシステムと共有すると、会社の評判が損なわれ、金銭的な損失につながる可能性があります。DLP API を使用すると、強力かつ柔軟な方法でセンシティブ データに保護レイヤを追加できます。この API によって、機密情報が SAP に保存されたり SAP から送信されたりする前に、機密情報の検出、分類、匿名化を行うことができます。機密情報を事前に特定して保護することで、データ侵害のリスクを軽減し、プライバシーに関する規則を遵守できます。

このドキュメントは、データ セキュリティ、データ処理、データ分析を担当する ABAP デベロッパー、SAP ソリューション アーキテクト、クラウド アーキテクトなどを対象としています。このドキュメントは、データ処理とデータ プライバシー、Sensitive Data Protection、および関連するコンセプトInfoType と infoType 検出器など)に精通していることを前提としています。

アーキテクチャ

次の図は、SAP BTP ABAP 環境と Google Cloud のコンポーネントを含む DLP ソリューションのリファレンス アーキテクチャを示しています。

SAP のデータ保護のための DLP ソリューション

この DLP ソリューション アーキテクチャには、次のコンポーネントが含まれています。

コンポーネント サブシステム 詳細
1 入力ソース データのエントリ ポイントとして機能します。
2 クライアント サービス 他のすべてのコンポーネントとやり取りする ABAP クラス。ソースデータを受信し、ABAP SDK for Google Cloud を介して DLP API にデータを送信して処理し、処理されたデータを SAP データストアに保存します。
3 ABAP SDK for Google Cloud DLP API にアクセスするための ABAP SDK for Google Cloud の SAP BTP エディション。
4 DLP API DLP API には、PII の匿名化に使用できるさまざまな変換方法が用意されています。
5 ターゲット データストア クラウドまたはオンプレミスで実行される SAP ERP システム。PII が処理されて匿名化された後にデータが保存されます。

使用するプロダクト

このリファレンス アーキテクチャでは、次の Google Cloud プロダクトを使用します。

ユースケース

このセクションでは、DLP API を使用して SAP の機密性の高い企業データを保護できるユースケースの例を示します。

データ プライバシーに関する規則の遵守

組織は、センシティブ データの匿名化を求められることがよくあります。GDPR や DPDP など、特定の条件下で PII を保存しないことを義務付ける政府のポリシーは数多くあります。

費用

DLP API で使用される Google Cloud リソースの費用の見積もりについては、Google Cloud 料金計算ツールで事前に計算された見積もりをご覧ください。

代替案の設計

このドキュメントでは、ABAP SDK for Google Cloud の SAP BTP エディションに焦点を当てていますが、オンプレミス エディションまたはクラウド エディションの ABAP SDK for Google Cloud でも同様の結果を得ることができます。この設定では、処理され匿名化されたセンシティブ データ(PII)をオンプレミス SAP システムに保存できます。

デプロイ

このセクションでは、SAP システムでビジネス パートナー(個人)を作成するときにセンシティブ データを保護するソリューションをデプロイする方法について説明します。このソリューションは、組織で設定された構成に基づいて、データの削除、非識別化、匿名化を行うことができます。

始める前に

このリファレンス アーキテクチャに基づいてソリューションを実装する前に、次の前提条件を満たしていることを確認してください。

PII の匿名化のためにクライアント サービスを実装する

データソースからの入力は、SAP BTP ABAP 環境内に実装するクライアント サービスで処理されます。このクライアント サービスは、次のサブコンポーネントで構成できます。

  • ルールの構成: さまざまな種類の PII 関連フィールドに適用する必要があるビジネスルールを保存します。
  • DLP プロキシ モジュール: ABAP SDK for Google Cloud の SAP BTP エディションを介して DLP API を呼び出します。

ルールの設定

SAP BTP ABAP 環境で構成テーブルを作成し、さまざまな種類の PII 関連フィールドに適用する必要がある変換ルールを維持します。本番環境では、SAP Fiori などのツールを使用して、このテーブルのデータを維持できます。

次のサンプルルールを実装できます。

  • メールアドレスを含むフィールドをすべてダミー値に置き換える。
  • 電話番号を含むフィールドをすべてマスクする。
  • コメント、メモ、備考が記載されているフィールドには、メールアドレスに関連する情報を含めない。
  • 銀行口座情報が含まれるすべてのフィールドを、暗号ベースの匿名化方法を使用してトークン化する。

サンプルの構成テーブルの定義を次に示します。

define table zgoog_dlp_config {
 key client         : abap.clnt not null;
 key keyword        : abap.char(60) not null;
 key infotype       : abap.char(60) not null;
 surrogate_infotype : abap.char(60);
 common_alphabhet   : abap.char(20);
 masking_char       : abap.char(1);
 number_to_mask     : int4;
}

次の例は、変換ルールのサンプルを示しています。

   lt_dlp_config = VALUE #(
      ( client = sy-mandt keyword  = 'EMAIL' infotype = 'EMAIL_ADDRESS'  )
      ( client = sy-mandt keyword  = 'PHONE NUMBER' infotype = 'PHONE_NUMBER' number_to_mask = 5 masking_char = '*' )
      ( client = sy-mandt keyword  = 'REMARKS' infotype = 'EMAIL_ADDRESS'  )
      ( client = sy-mandt keyword  = 'REMARKS' infotype = 'PHONE_NUMBER'  )
      ( client = sy-mandt keyword  = 'BANK ACCOUNT' infotype = 'FINANCIAL_ACCOUNT_NUMBER' surrogate_infotype = 'ACCOUNT' common_alphabhet = 'ALPHA_NUMERIC' )
    ).

DLP プロキシ モジュール

DLP プロキシ モジュールという名前の専用サブコンポーネントを作成できます。このモジュールは、ABAP クラスまたは REST サービスにすることができます。主な機能は、前の手順で定義した変換ルールを使用して PII を匿名化することです。

DLP プロキシ モジュールは、ABAP SDK for Google Cloud の SAP BTP エディション内の /GOOG/CL_DLP_V2 クラスの DEIDENTIFY_CONTENT メソッドを使用します。

以降のセクションでは、さまざまなシナリオで PII の匿名化に DLP プロキシ モジュールを使用する方法について、実装のサンプルを示します。

置換: 検出された機密値を指定されたサロゲート値に置換します

検出されたメール ID を汎用値に置き換える手順は次のとおりです。

  1. /GOOG/CL_DLP_V2 クラスのクライアント オブジェクトを作成します。

  2. 構成テーブルを使用して、適用する変換のタイプを決定します。

  3. メール ID をマスキングするには、EMAIL_ID@EXAMPLE.COM などの置換値に置き換えます。

  4. DLP API を呼び出します。

  5. 置換値を含むすべての関連パラメータで DEIDENTIFY_CONTENT メソッドを使用し、出力をクライアント サービスに返します。

次のコードサンプルは、上記の手順を示しています。

DATA:    ls_input           TYPE /goog/cl_dlp_v2=>ty_055,
         ls_transformations TYPE /goog/cl_dlp_v2=>ty_100.

TRY.
   DATA(lo_client) = NEW /goog/cl_dlp_v2( iv_key_name = 'CLIENT_KEY' ).
   DATA(lv_p_projects_id) = CONV string( lo_client->gv_project_id ).

   "As a developer, you need to read the configuration into mt_dlp_config
   TRY.
   "As a developer, you need to read the configuration
    DATA(ls_dlp_config) = mt_dlp_config[ keyword = iv_input_type ].
        "Populate the input parameters to DLP API for replacement
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_input-inspect_config-info_types.ls_transformations-primitive_transformation-replace_config-new_value-string_value  = 'REPLACEMENT_VALUE'.
INSERT ls_transformations INTO TABLE ls_input-deidentify_config-info_type_transformations-transformations.
        ls_input-item-value = iv_input_value.
        "Call DLP API client stub
        TRY.
            lo_client->deidentify_content(
               EXPORTING
                   iv_p_projects_id = lv_p_projects_id
                   is_input         = ls_input
               IMPORTING
                   es_output        = DATA(ls_output)
                   ev_ret_code      = DATA(lv_ret_code)
                   ev_err_text      = DATA(lv_err_text)
                ).
        CATCH /goog/cx_sdk INTO DATA(lx_sdk_exception).
             ev_message = lx_sdk_exception->get_text( ).
        ENDTRY.
        IF lo_client->is_success( lv_ret_code ).
             ev_message = lv_err_text.
        ELSE.
            ev_output_value = ls_output-item-value.
        ENDIF.
    CATCH cx_sy_itab_line_not_found INTO DATA(lx_not_found).
        ev_output_value = iv_input_value.
    ENDTRY.
"Close the http client
lo_client->close_http_client( ).
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
   ev_message = lx_sdk->get_text(  ).
ENDTRY.

次のように置き換えます。

  • CLIENT_KEY: 認証用に構成されたクライアント キー。
  • REPLACEMENT_VALUE: 置換値(EMAIL_ID@EXAMPLE.COM など)。
削除: 検出された機密値のすべてまたは一部を削除します

検出された機密値のすべてまたは一部を削除する手順は次のとおりです。

  1. /GOOG/CL_DLP_V2 クラスのクライアント オブジェクトを作成します。

  2. 構成テーブルを使用して、適用する変換のタイプを決定します。

  3. 検出された機密値のすべてまたは一部を削除するように指定します。

  4. DLP API を呼び出します。

  5. すべての関連パラメータで DEIDENTIFY_CONTENT メソッドを使用し、出力をクライアント サービスに返します。

DATA:    ls_input           TYPE /goog/cl_dlp_v2=>ty_055,
         ls_transformations TYPE /goog/cl_dlp_v2=>ty_100,
 lo_redact          TYPE REF TO data.

   DATA(lo_client) = NEW /goog/cl_dlp_v2( iv_key_name = 'CLIENT_KEY' ).
   DATA(lv_p_projects_id) = CONV string( lo_client->gv_project_id ).

   "As a developer, you need to read the configuration into mt_dlp_config
   TRY.
        "Read the configuration
DATA(ls_dlp_config) = mt_dlp_config[ keyword = iv_input_type ].
        "Populate the input parameters to DLP API for redaction
CREATE DATA lo_redact TYPE REF TO string.
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_input-inspect_config-info_types.
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_transformations-info_types.
        ls_transformations-primitive_transformation-redact_config = lo_redact.
INSERT ls_transformations INTO TABLE ls_input-deidentify_config-info_type_transformations-transformations.
        ls_input-item-value = iv_input_value.
        "Call DLP API client stub
        TRY.
lo_client->deidentify_content(
                        EXPORTING
                                iv_p_projects_id = lv_p_projects_id
                            is_input         = ls_input
                        IMPORTING
                            es_output        = DATA(ls_output)
                            ev_ret_code      = DATA(lv_ret_code)
                            ev_err_text      = DATA(lv_err_text)
                 ).
CATCH /goog/cx_sdk INTO lx_sdk_exception.
              ev_message = lx_sdk_exception->get_text( ).
        ENDTRY.
     IF lo_client->is_success( lv_ret_code ).
           ev_message = lv_err_text.
        ELSE.
          ev_output_value = ls_output-item-value.
        ENDIF.
  CATCH cx_sy_itab_line_not_found INTO lx_not_found.
      ev_output_value = iv_input_value.
  ENDTRY.

  "Close the http client
     lo_client->close_http_client( ).
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
   ev_message = lx_sdk->get_text(  ).
ENDTRY.

CLIENT_KEY は、認証用に構成されたクライアント キーに置き換えます。

マスキング: 機密値の文字列をハッシュ(#)やアスタリスク(*)などの指定された文字に置き換えます

値を指定された文字に置き換える手順は次のとおりです。

  1. /GOOG/CL_DLP_V2 クラスのクライアント オブジェクトを作成します。

  2. 構成テーブルを使用して、適用する変換のタイプを決定します。

  3. 構成テーブルに従って、マスキング文字とマスキングする文字数を設定します。

  4. DLP API を呼び出します。

  5. 置換値を含むすべての関連パラメータで DEIDENTIFY_CONTENT メソッドを使用し、出力をクライアント サービスに返します。

DATA:    ls_input           TYPE /goog/cl_dlp_v2=>ty_055,
         ls_transformations TYPE /goog/cl_dlp_v2=>ty_100.
TRY.
   DATA(lo_client) = NEW /goog/cl_dlp_v2( iv_key_name = 'CLIENT_KEY' ).
   DATA(lv_p_projects_id) = CONV string( lo_client->gv_project_id ).

   "As a developer, you need to read the configuration into mt_dlp_config
   TRY.
"Read the configuration
        DATA(ls_dlp_config) = mt_dlp_config[ keyword = iv_input_type ].
    "Populate the input parameters to DLP API for masking
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_input-inspect_config-info_types.
ls_transformations-primitive_transformation-character_mask_config-number_to_mask =  ls_dlp_config-number_to_mask.
ls_transformations-primitive_transformation-character_mask_config-masking_character = ls_dlp_config-masking_char.
INSERT ls_transformations INTO TABLE ls_input-deidentify_config-info_type_transformations-transformations.
        ls_input-item-value = iv_input_value.
        "Call DLP API client stub
         TRY.
                   lo_client->deidentify_content(
                       EXPORTING
                         iv_p_projects_id = lv_p_projects_id
                         is_input         = ls_input
                       IMPORTING
                         es_output        = DATA(ls_output)
                         ev_ret_code      = DATA(lv_ret_code)
                         ev_err_text      = DATA(lv_err_text)
                     ).
              CATCH /goog/cx_sdk INTO lx_sdk_exception.
                   ev_message = lx_sdk_exception->get_text( ).
              ENDTRY.
              IF lo_client->is_success( lv_ret_code ).
                 ev_message = lv_err_text.
              ELSE.
                 ev_output_value = ls_output-item-value.
              ENDIF.
      CATCH cx_sy_itab_line_not_found INTO lx_not_found.
         ev_output_value = iv_input_value.
      ENDTRY.
   "Close the http client
     lo_client->close_http_client( ).
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
   ev_message = lx_sdk->get_text(  ).
ENDTRY.

CLIENT_KEY は、認証用に構成されたクライアント キーに置き換えます。

暗号ベースのトークン化: 元のセンシティブ データの値を暗号鍵を使用して暗号化します

暗号ベースのトークン化では、暗号鍵とラップされた鍵を作成する必要があります。このガイドでは、フォーマット保持暗号化を使用します。この方法では、元の入力値と同じ長さと文字のトークンが作成されます。

暗号ハッシュ マッピングを使用してセンシティブ データ値を匿名化するには、次の操作を行います。

  1. /GOOG/CL_DLP_V2 クラスのクライアント オブジェクトを作成します。

  2. 構成テーブルを使用して、適用する変換のタイプを決定します。

  3. 前に作成した暗号鍵とラップされた鍵を設定します。

  4. DLP API を呼び出します。

  5. 暗号化に関連するすべてのパラメータで DEIDENTIFY_CONTENT メソッドを使用し、出力をクライアント サービスに返します。

DATA:    ls_input               TYPE /goog/cl_dlp_v2=>ty_055,
         ls_transformations     TYPE /goog/cl_dlp_v2=>ty_100,
         ls_kms_wrapped_key     TYPE /goog/cl_dlp_v2=>ty_123,
         ls_crypto_key          TYPE /goog/cl_dlp_v2=>ty_040,
         ls_crypto_hash_config  TYPE /goog/cl_dlp_v2=>ty_039.

TRY.
   DATA(lo_client) = NEW /goog/cl_dlp_v2( iv_key_name = 'CLIENT_KEY' ).
   DATA(lv_p_projects_id) = CONV string( lo_client->gv_project_id ).

   "As a developer, you need to read the configuration into lt_dlp_config
   "As a developer, you need to populate the crypto key name and wrapped key

   ls_kms_wrapped_key-crypto_key_name = 'CRYPTO_KEY_NAME'. "Crypto_key_name.
   ls_kms_wrapped_key-wrapped_key = 'WRAPPED_KEY_NAME'. "Wrapped_key.
   ls_crypto_key-kms_wrapped = ls_kms_wrapped_key.
   ls_crypto_hash_config-crypto_key = ls_crypto_key.
   TRY.
"Read the configuration
        DATA(ls_dlp_config) = mt_dlp_config[ keyword = iv_input_type ].
    "Populate the input parameters to DLP API for cryptographic encryption
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_input-inspect_config-info_types.
INSERT VALUE #( name = ls_dlp_config-infotype ) INTO TABLE ls_transformations-info_types.             ls_transformations-primitive_transformation-crypto_replace_ffx_fpe_config-crypto_key-kms_wrapped = ls_kms_wrapped_key.             ls_transformations-primitive_transformation-crypto_replace_ffx_fpe_config-surrogate_info_type-name = ls_dlp_config-surrogate_infotype.          ls_transformations-primitive_transformation-crypto_replace_ffx_fpe_config-common_alphabet = ls_dlp_config-common_alphabhet.
INSERT ls_transformations INTO TABLE ls_input-deidentify_config-info_type_transformations-transformations.
        ls_input-item-value = iv_input_value.
    "Add the info type identification string to map the subsequent value to relevant infotype
CONCATENATE 'Bank Account' ls_input-item-value INTO ls_input-item-value SEPARATED BY space.
"Call DLP API client stub
TRY.
                lo_client->deidentify_content(
                        EXPORTING
                            iv_p_projects_id = lv_p_projects_id
                            is_input         = ls_input
                        IMPORTING
                            es_output        = DATA(ls_output)
                            ev_ret_code      = DATA(lv_ret_code)
                            ev_err_text      = DATA(lv_err_text)
                 ).
CATCH /goog/cx_sdk INTO DATA(lx_sdk_exception).
                        ev_message = lx_sdk_exception->get_text( ).
                ENDTRY.
         IF lo_client->is_success( lv_ret_code ).
            ev_message = lv_err_text.
         ELSE.
"Removing the info type identification string added earlier and keeping only the encrypted value
    REPLACE ALL OCCURRENCES OF SUBSTRING 'Bank Account' IN ls_output-item-value WITH ''.
    REPLACE ALL OCCURRENCES OF SUBSTRING 'ACCOUNT(10):' IN ls_output-item-value WITH ''.
        ev_output_value  = ls_output-item-value.
        ENDIF.
      CATCH cx_sy_itab_line_not_found INTO lx_not_found.
         ev_output_value = iv_input_value.
      ENDTRY.
 "Close the http client
   lo_client->close_http_client( ).
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
   ev_message = lx_sdk->get_text(  ).
ENDTRY.

次のように置き換えます。

  • CLIENT_KEY: 認証用に構成されたクライアント キー。
  • CRYPTO_KEY_NAME: 暗号鍵の名前。
  • WRAPPED_KEY_NAME: ラップされた鍵の名前。

入力データをクライアント サービスに送信する

入力ソースシステムからクライアント サービスにデータを送信します。データを送信するには、API 呼び出し、フロントエンド UI アプリケーション、ローカル ファイル、サードパーティ アプリケーション、その他のソースを使用します。

SAP Fiori アプリをビルドする方法については、ABAP RESTful アプリケーション プログラミング モデルを使用して SAP Fiori アプリをビルドするをご覧ください。

DLP プロキシ モジュールを呼び出す

ソース入力を受け取るクライアント サービスから DLP プロキシ モジュールを呼び出します。

次のコードサンプルは、クライアント サービスから DLP プロキシ モジュールを呼び出す方法を示しています。

 DATA : lv_input  TYPE string,
            lv_output TYPE String.

"As a developer, you need to populate input data into relevant fields
"Redaction: Deletes all or part of a detected sensitive value
" - Remarks
lv_input = lv_email_address.
zgoog_cl_dlp_proxy=>call_dlp( EXPORTING iv_input_value  = lv_input iv_input_type = 'EMAIL'
                              IMPORTING ev_output_value = lv_output ev_message = ev_message ).
ls_bupa_email_address-email_address = lv_output.

"Masking: Replaces a number of characters of a sensitive value with a specified surrogate character, such as a hash (#) or asterisk (*).
" - Phone Number
lv_input = lv_phone_number.
zgoog_cl_dlp_proxy=>call_dlp( EXPORTING iv_input_value = lv_input iv_input_type = 'PHONE NUMBER'
                              IMPORTING ev_output_value = lv_output ev_message = ev_message ).
ls_bupa_phone_number-phone_number = lv_output.

"Replacement: Replaces a detected sensitive value with a specified surrogate value.
" - Email ID
lv_input = lv_address_comm_remarks.
zgoog_cl_dlp_proxy=>call_dlp( EXPORTING iv_input_value  = lv_input iv_input_type = 'REMARKS'
                              IMPORTING ev_output_value = lv_output ev_message = ev_message ).
ls_bupa_email_address-address_comm_remarks = lv_output.

"Crypto-based tokenization: Encrypts the original sensitive data value by using a cryptographic key. Sensitive Data Protection supports several types of tokenization,
"including transformations that can be reversed, or "re-identified."
" - Bank account number
lv_input = lv_bank_account.
zgoog_cl_dlp_proxy=>call_dlp( EXPORTING iv_input_value  = lv_input iv_input_type = 'BANK ACCOUNT'
                              IMPORTING ev_output_value = lv_output ev_message = ev_message ).
ls_bupa_bank_details-bank_account = lv_output.

データを SAP ERP システムに保存する

関連するフィールドの匿名化が完了したら、クライアント サービスで、データをターゲット ストレージに保存するロジックを実装します。ターゲット ストレージには、Cloud Storage サービスまたはオンプレミスの SAP システムを利用できます。

次のステップ

  • このガイドで説明するサンプル ソリューションを最小限の労力でデプロイするには、GitHub で提供されているコードサンプルを使用します。

  • DLP API で利用可能なさまざまな変換方法を調べて、特定のビジネスニーズに最適なものを見つけてください。

  • ABAP SDK for Google Cloud の詳細については、ABAP SDK for Google Cloud の概要をご覧ください。

  • ABAP SDK for Google Cloud の問題を解決するには、次の方法があります。

寄稿者

著者: Sanchita Mohta 氏 | SAP アプリケーション エンジニア

その他の寄稿者: Vikash Kumar 氏 | テクニカル ライター