本文档介绍了一种参考架构,用于通过 SAP BTP 版本的 ABAP SDK for Google Cloud 使用 Cloud Data Loss Prevention (DLP) API 来保护 SAP 中的敏感企业数据。
保护您在 SAP 中存储的敏感企业数据(例如个人身份信息 [PII])至关重要。与不当人员或系统共享 SAP 中的敏感企业数据可能会损害贵公司的声誉并导致经济损失。DLP API 提供了一种强大且灵活的方式,可为敏感数据添加一层保护。此 API 可在敏感信息存储到 SAP 或从 SAP 传输之前发现、分类和去标识化处理敏感信息。它可帮助您主动识别和保护机密信息,降低数据泄露风险,并确保遵守隐私权法规。
本文档的目标受众群体包括 ABAP 开发者、SAP 解决方案架构师和云架构师,他们负责数据安全、数据处理或数据分析。本文档假定您熟悉数据处理和数据隐私权、Sensitive Data Protection 以及相关概念,例如 InfoType 和 infoType 检测器。
架构
下图展示了 DLP 解决方案的参考架构,其中包含来自 SAP BTP ABAP 环境的组件和 Google Cloud。
此 DLP 解决方案架构包含以下组件:
组件 | 子系统 | 详细信息 |
---|---|---|
1 | 输入来源 | 充当数据的入口点。 |
2 | 客户端服务 | 与所有其他组件进行互动的 ABAP 类。 它会接收源数据,通过 ABAP SDK for Google Cloud 将数据发送到 DLP API 进行处理,并将处理的数据存储在 SAP 数据存储区中。 |
3 | ABAP SDK for Google Cloud | SAP BTP 版本的 ABAP SDK for Google Cloud,用于访问 DLP API。 |
4 | DLP API | DLP API 提供了各种转换方法,用于对个人身份信息进行去标识化。 |
5 | 目标数据存储区 | 在云或本地运行的 SAP ERP 系统,在个人身份信息经过处理和去标识化后,数据会存储到该系统中。 |
使用的产品
此参考架构使用以下 Google Cloud 产品:
使用场景
本部分提供了一些应用场景示例,您可以使用 DLP API 来保护 SAP 中的敏感企业数据。
遵守数据隐私权法规
组织通常需要对敏感数据进行去标识化处理。许多政府政策(例如 GDPR 和 DPDP)规定,在某些情况下不得存储个人身份信息。
费用
如需估算 DLP API 使用的 Google Cloud 资源的费用,请参阅 Google Cloud 价格计算器中预先计算的估算值。
设计替代方案
虽然本文档主要介绍 SAP BTP 版本的 ABAP SDK for Google Cloud,但您也可以使用本地或任何云版本的 ABAP SDK for Google Cloud 来实现类似的结果。在此设置中,您可以在本地 SAP 系统中存储经过处理和去标识化的敏感数据 (PII)。
部署
本部分介绍了如何部署一个解决方案,以便在 SAP 系统中创建业务合作伙伴(人员)时保护敏感数据。根据贵组织设置的配置,此解决方案可以对数据进行隐去、去标识或匿名化处理。
准备工作
在根据此参考架构实现解决方案之前,确保您已完成以下前提条件:
您拥有一个 Google Cloud 账号和项目。
您的项目已启用结算功能。如需了解如何确认您的项目是否已启用结算功能,请参阅验证项目的结算状态。
已设置用于访问 Google Cloud API 的身份验证。如需了解如何设置身份验证,请参阅为 SAP BTP 版本的 ABAP SDK for Google Cloud 设置身份验证。
您的 Google Cloud 项目中已启用 DLP API。
实现用于对个人身份信息进行去标识化的客户端服务
您在 SAP BTP ABAP 环境中实现的客户端服务会处理来自数据源的输入。此客户端服务可以包含以下子组件:
规则配置
在 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 替换为通用值,请执行以下步骤:
为
/GOOG/CL_DLP_V2
类创建客户端对象。使用配置表确定要应用的转换类型。
如需遮盖邮件 ID,请将其替换为替换值,例如
EMAIL_ID@EXAMPLE.COM
。调用 DLP API。
使用
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
。
隐去:删除检测到的全部或部分敏感值
如需删除检测到的全部或部分敏感值,请执行以下步骤:
为
/GOOG/CL_DLP_V2
类创建客户端对象。使用配置表确定要应用的转换类型。
指定删除检测到的全部或部分敏感值。
调用 DLP API。
使用
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
替换为为身份验证而配置的客户端密钥。
遮盖:将敏感值中的若干字符替换为指定的字符(例如井号 (#) 或星号 (*))。
如需将值替换为指定的字符,请执行以下步骤:
为
/GOOG/CL_DLP_V2
类创建客户端对象。使用配置表确定要应用的转换类型。
根据配置表设置要遮盖的字符和字符数。
调用 DLP API。
使用
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
替换为为身份验证而配置的客户端密钥。
基于加密的标记化:使用加密密钥加密原始敏感数据值。
对于基于加密的标记化,您需要创建加密密钥和已封装的密钥。 本指南使用保留格式加密。此方法会创建一个与原始输入值具有相同长度和字符的令牌。
如需使用加密哈希映射对敏感数据值进行去标识化,请执行以下步骤:
为
/GOOG/CL_DLP_V2
类创建客户端对象。使用配置表确定要应用的转换类型。
设置之前创建的加密密钥和已封装的密钥。
调用 DLP API。
使用
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 问题时需要帮助,请执行以下操作:
- 参阅 ABAP SDK for Google Cloud 问题排查指南。
- 在 Cloud 论坛上提出问题并与社区讨论 ABAP SDK for Google Cloud。
- 收集所有可用的诊断信息,并与 Cloud Customer Care 联系。 如需了解如何与 Customer Care 联系,请参阅获取 Google Cloud上的 SAP 支持。
贡献者
作者:Sanchita Mohta | SAP 应用工程师
其他贡献者:Vikash Kumar | 技术文档工程师