使用 DLP API 在 SAP 中保护数据

本文档介绍了一种参考架构,该架构将 SAP BTP 版本的 ABAP SDK for Google CloudCloud Data Loss Prevention (DLP) API 结合使用,以保护 SAP 中的敏感企业数据。

请务必保护您在 SAP 中存储的敏感企业数据,例如个人身份信息 (PII)。与不当人员或系统分享 SAP 中的敏感企业数据可能会损害贵公司的声誉并导致经济损失。DLP API 提供了一种强大且灵活的方法,可为敏感数据添加一层保护。此 API 可以在敏感信息存储在 SAP 中或从 SAP 传输之前发现、分类和去标识化敏感信息。它可帮助您主动识别和保护机密信息,降低数据泄露风险并确保遵守隐私权法规。

本文档的目标受众群体包括 ABAP 开发者、SAP 解决方案架构师和云架构师,他们的职责包括数据安全、数据处理或数据分析。本文档假定您熟悉数据处理和数据隐私、敏感数据保护以及相关概念,例如 InfoType 和 infoType 检测器

架构

下图展示了 DLP 解决方案的参考架构,其中包含 SAP BTP ABAP 环境和 Google Cloud 中的组件。

用于保护 SAP 中数据的 DLP 解决方案

此 DLP 解决方案架构包括以下组件:

组件 子系统 详细信息
1 输入来源 充当数据的入口点。
2 客户服务 与所有其他组件交互的 ABAP 类。 它会接收源数据,通过 ABAP SDK for Google Cloud 将数据发送到 DLP API 进行处理,并将处理后的数据存储在 SAP 数据存储区中。
3 ABAP SDK for Google Cloud 用于访问 DLP API 的 SAP BTP 版本的 ABAP SDK for Google Cloud。
4 DLP API DLP API 提供了各种转换方法来去标识化个人身份信息。
5 目标数据存储 在云端或本地运行的 SAP ERP 系统,用于存储在处理和去标识化个人身份信息后的数据。

使用的产品

此参考架构使用以下 Google Cloud 产品:

使用场景

本部分提供了一些用例示例,说明您可以使用 DLP API 在 SAP 中保护敏感企业数据。

遵守数据隐私权法规

组织通常需要去标识化敏感数据。许多政府政策(例如《一般数据保护条例》[GDPR] 和《数据保护和电子隐私法案》[DPDP])都规定,在特定情况下不得存储个人身份信息 (PII)。

费用

如需估算 DLP API 使用的 Google Cloud 资源的费用,请参阅 Google Cloud 价格计算器中预先计算的估算值。

设计替代方案

虽然本文档重点介绍的是 SAP BTP 版本的 ABAP SDK for Google Cloud,但您也可以使用本地版本或任何云版本的 ABAP SDK for Google Cloud 实现类似的结果。在此设置中,您可以在本地 SAP 系统中存储经过处理和去标识化的敏感数据 (PII)。

部署

本部分介绍了如何部署解决方案,以便在 SAP 系统中创建业务合作伙伴(个人)时保护敏感数据。根据贵组织设置的配置,此解决方案可以隐去、去标识化或匿名化数据。

准备工作

在根据此参考架构实现解决方案之前,请确保您已完成以下前提条件:

实现用于去标识化个人身份信息的客户端服务

系统会在您在 SAP BTP ABAP 环境中实现的客户端服务中处理来自数据源的输入。此客户端服务可以由以下子组件组成:

  • 规则配置:存储需要针对不同类型的个人身份信息相关字段应用的业务规则。
  • DLP 代理模块:通过 SAP BTP 版本的 ABAP SDK for Google Cloud 调用 DLP API。

规则配置

在 SAP BTP ABAP 环境中,您可以创建一个配置表,以维护需要针对不同类型的个人身份信息相关字段应用的转换规则。在生产环境中,您可以使用 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 服务。其主要功能是使用您之前定义的转换规则对个人身份信息进行去标识化处理。

DLP 代理模块使用 SAP BTP 版本的 ABAP SDK for Google Cloud 中 /GOOG/CL_DLP_V2 类的 DEIDENTIFY_CONTENT 方法。

以下部分展示了如何在各种场景中使用 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 调用、前端界面应用、本地文件、第三方应用或任何其他来源来传输数据。

如需了解如何构建 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 | 技术文档撰写者