diff --git a/guides/security/_menu.md b/guides/security/_menu.md index 00050967e2..9b34f8f580 100644 --- a/guides/security/_menu.md +++ b/guides/security/_menu.md @@ -8,8 +8,8 @@ # [Data Privacy](data-privacy) ## [Personal Data](dpp-annotations) ## [Audit Logging](dpp-audit-logging) -## [Personal Data Manager](dpp-pdm) - +## [Information reporting](dpp-pdm) +## [Retention management](dpp-drm) # [Product Security](data-protection) # [SAP Security Standards](../../../guides/security/product-standards) diff --git a/guides/security/assets/data-privacy/dpi_ng_launchpad.png b/guides/security/assets/data-privacy/dpi_ng_launchpad.png new file mode 100644 index 0000000000..722ed28959 Binary files /dev/null and b/guides/security/assets/data-privacy/dpi_ng_launchpad.png differ diff --git a/guides/security/assets/data-privacy/dpi_ng_retention_group.png b/guides/security/assets/data-privacy/dpi_ng_retention_group.png new file mode 100644 index 0000000000..f3d38a785a Binary files /dev/null and b/guides/security/assets/data-privacy/dpi_ng_retention_group.png differ diff --git a/guides/security/data-privacy.md b/guides/security/data-privacy.md index 3e4925f55b..45596fd0bd 100644 --- a/guides/security/data-privacy.md +++ b/guides/security/data-privacy.md @@ -39,8 +39,8 @@ The most essential requests you have to answer are those in the following table. | Question / Request | Obligation | Solution | | ------------------------------------------- | ----------------------------------------------- | ----------------------------------- | -| *What data about me do you have stored?* | [Right of access](#right-of-access) | [Personal Data Mgmt](dpp-pdm.md) | -| *Delete all personal data about me!* | [Right to be forgotten](#right-to-be-forgotten) | [Data Retention Mgmt](dpp-drm.md) | +| *What data about me do you have stored?* | [Right of access](#right-of-access) | [Information reporting](dpp-pdm.md) | +| *Delete all personal data about me!* | [Right to be forgotten](#right-to-be-forgotten) | [Retention management](dpp-drm.md) | | *When was personal data stored/changed?* | [Transparency](#transparency) | [Audit Logging](dpp-audit-logging.md) | @@ -75,7 +75,7 @@ The [**Right of Access** to personal data](https://en.wikipedia.org/wiki/Right_o The [SAP Personal Data Manager](https://help.sap.com/docs/personal-data-manager) allows you to inform individuals about the data you have stored regarding them. -[Learn more in the *Personal Data Management* guide](dpp-pdm) {.learn-more} +[Learn more in the *Information reporting* guide](dpp-pdm) {.learn-more} diff --git a/guides/security/dpp-annotations.md b/guides/security/dpp-annotations.md index 6a329ee15c..edc36b3b5c 100644 --- a/guides/security/dpp-annotations.md +++ b/guides/security/dpp-annotations.md @@ -200,5 +200,5 @@ annotate my.Customers with { Having annotated your data model with `@PersonalData` annotations, you can now go on to the respective tasks that leverage these annotations to automate as much as possible: - [*Automated Audit Logging*](dpp-audit-logging) -- [*Personal Data Management*](dpp-pdm) -- [*Data Retention Management*](dpp-drm) +- [*Information reporting*](dpp-pdm) +- [*Retention management*](dpp-drm) diff --git a/guides/security/dpp-drm.md b/guides/security/dpp-drm.md index 06e4b19779..d380087abc 100644 --- a/guides/security/dpp-drm.md +++ b/guides/security/dpp-drm.md @@ -1,52 +1,524 @@ --- synopsis: > - The Data Retention Management (DRM) guide is under construction. It will cover concepts and implementation details for managing the retention and deletion of personal data in compliance with data privacy regulations. -# status: released + The Retention Management guide explains how to integrate your CAP application with the SAP Data Privacy Integration NG service to create retention rules and ensure timely & compliant deletion of personal data in your application. --- -# Data Retention Management +# Retention Management -Under construction. +{{ $frontmatter.synopsis }} +:::warning To follow this cookbook hands-on you need an enterprise account. +The SAP Data Privacy Integration NG service is currently only available for [enterprise accounts](https://discovery-center.cloud.sap/missiondetail/3019/3297/). An entitlement in trial accounts is not possible. +::: +SAP BTP provides the [*SAP Data Privacy Integration Next Gen (DPI)*](https://help.sap.com/docs/data-privacy-integration/end-user-information/what-is-data-privacy-integration-nextgen) service, whose module "Retention Management" allows administrators to configure retention policies which block and destruct personal identifiable information. To do that, the DPI service needs to access the application via a REST API. That endpoint is provided by the @cap-js/data-privacy plugin and configured as follows. - +For these ILM objects the Retention Manager allows you to configure retention policies, which causes personal data to be blocked and deleted, or, non data-privacy specific, data to be archived and destructed. + +Within CDS you would indicate an ILM Object, by annotating it with `@PersonalData.EntitySemantics : 'Other'`. + +```cds +annotate Incidents with @( + description: 'A raised incident by a customer' // Shown in the Retention Manager UI + PersonalData: { + EntitySemantics : 'Other', + DataSubjectRole: 'Customer' + }, +) { + customer @PersonalData.FieldSemantics : 'DataSubjectID'; + resolvedAt @PersonalData.FieldSemantics : 'EndOfBusinessDate'; + company @PersonalData.FieldSemantics : 'DataControllerID'; +}; +``` + +Any ILM Object must have two properties: One that contains the end of business date, and one that is the ID for the data controller. + +For ILM Objects related to personal data, they also must have a property pointing to the data subject. + +::: info +If your current domain model does not have these properties directly on the root, you can refer to [Extending the Retention service](#extending-the-retention-service-optional) to include all required properties in the service interface. +::: + +#### Conditions + +Retention policies might differ not just based on the data controller, e.g. organizational attribute, but further attributes. These are called conditions and can be used to narrow down retention policies to a subset of data. + +```cds +annotate Incidents with { + type @PersonalData.FieldSemantics : 'PurposeID'; + category @ILM.FieldSemantics : 'ProcessOrganizationID'; +}; +``` + +Conditions are generated for properties marked with `@PersonalData.FieldSemantics : 'PurposeID'` or `@ILM.FieldSemantics : 'ProcessOrganizationID'`. The field help logic is the same as for Organizational attributes. + +#### Dynamic ILM Object enablement + +You can dynamically enable or disable ILM Objects, which is useful for SaaS Providers when specific entities are put behind a feature flag. Enablement can be toggled via `@ILM.BlockingEnabled` and it accepts, static true/false values, CQN expressions or CQN expression strings. + +```cds +annotate Incidents with @( + ILM.BlockingEnabled : '(SELECT isBlockingEnabled FROM sap.capire.incidents.Configuration)' +); +``` + +#### Customize ILM Object name + +By default the ILM Object name is the name of the entity. You can customize that name with the `@ILM.ObjectName` annotation. + +```cds +annotate Incidents with @( + ILM.ObjectName : 'CustomIncidents' +); +``` + + +### Organizational attributes + +Organizational attributes are the main differentiator to know which retention policy is relevant for which ILM Object. Each ILM Object must have one and only one property marked as such. `@PersonalData.FieldSemantics : 'DataControllerID'` or `@ILM.FieldSemantics : 'LineOrganizationID'` can be used and both annotations have the same effect. + +::: code-group +```cds [DPP specific] +annotate Incidents with { + company @PersonalData.FieldSemantics : 'DataControllerID'; +}; +``` + +```cds [ILM generic] +annotate Incidents with { + company @ILM.FieldSemantics : 'LineOrganizationID'; +}; +``` +::: + +For organizational attributes a field help is generated by the plugin that when creating the retention policy in the Retention Manager, the administrator can choose for which Organizational attribute the policy applies. + +The logic for the field help generation is as follows: + 1. Consider the `@Common.ValueList` annotation. If the property marked as the organizational attribute has a ValueList annotated, the entity specified as the `@Common.ValueList.CollectionPath` is considered to be the source for the field help. + +```cds + annotate Incidents with { + company @PersonalData.FieldSemantics : 'DataControllerID' @Common.ValueList : { + CollectionPath: 'Companies', + Parameters : [ + { + $Type: 'Common.ValueListParameterInOut', + ValueListProperty : 'ID', + LocalDataProperty : company_ID, + }, + { + $Type : 'Common.ValueListParameterDisplayOnly', + ValueListProperty : 'name', + }, + ] + }; + }; +``` + If multiple `Common.ValueListParameterDisplayOnly` parameters are specified they are concatenated together. + + 2. If no value list is specified, but the property is an association, the associated entity is used for the field help. + + For the name shown in the field help 1. the path from `@Common.Text` is used. If that is not given the path specified via `@UI.HeaderInfo.Title.Value` would be used. + +```cds + annotate Incidents with { + company @PersonalData.FieldSemantics : 'DataControllerID' @Common.Text : company.name; + }; + + annotate Companies with @( + UI.HeaderInfo : { + Title : { + Value : name + }, + } + ) { + + }; +``` + + 3. If the property is not an association, a field help is created by building a SELECT distinct query on that column. + + +### Dynamic data subject role assignments + +In some scenarios an ILM Object or a data subject might have a dynamic data subject role. Imagine a business partner entity, which has a type property specifying the data subject role. + +```cds +@PersonalData : { + EntitySemantics : 'DataSubject', + DataSubjectRole : type +} +entity BusinessPartners : cuid { + type : String enum { + Customer = 'Customer', + Employee = 'Employee', + Debtor = 'Debtor' + } +} +``` + +For dynamic data subject roles to work, the data subject role property must have an enum detailing all possible values. With that the plugin will correctly generate the configuration and handle requests from the Retention Manager. + +## Blocking personal data + +Personal data usually needs to be blocked after their end of business date is meet, starting the retention period where it can only be accessed by auditors. + +The plugin implements it by automatically injecting two aspects into every ILM Object and Data Subject base entity and its composed entities: + +```cds +aspect destruction { + ilmEarliestDestructionDate : Date @UI.HiddenFilter @PersonalData.FieldSemantics: 'EndOfRetentionDate'; + ilmLatestDestructionDate : Date @UI.HiddenFilter; +} + +aspect blocking { + dppBlockingDate : Date @UI.HiddenFilter @PersonalData.FieldSemantics: 'BlockingDate'; +} +``` + +This means ILM Objects and Data Subjects will have three additional columns on the database. To support brownfield approaches, you can mark existing fields with the following annotations and the plugin will skip adding the respective fields to the entity. + +```cds +annotate Incidents with { + destroyAt @PersonalData.FieldSemantics: 'EndOfRetentionDate'; + blockedAt @PersonalData.FieldSemantics: 'BlockingDate'; +} +``` + +The fields are necessary for the Retention Manager to safely orchestrate personal data blocking and destruction. + +The approach of storing blocked data within the same table instead of having it in a different data store was made to ensure auditors can use the same UI to access active and blocked data. + +### Restricting access to blocked data + +Blocked data no longer should be used for regular purposes. To ensure custom application code cannot by accident select blocked data, the plugin implements access restrictions against blocked data on a database adapter and database level. + +#### Restricting access to views +CAP generates two different [Analytic Privileges](https://help.sap.com/docs/SAP_HANA_PLATFORM/b3ee5778bc2e4a089d3299b82ec762a7/db08ea0cbb571014a386f851122958b2.html) for restricting access to views when the database is HANA Cloud. + +1. An analytic privilege for business object entities, where the `blockingDate` property is checked. If this property is null or in the future access is granted. +2. A second analytic privilege with a dummy restriction `1 = 1` to grant access independent of the blocked state. + +The two analytic privileges are assigned to two different database roles, which are generated by the plugin as well. +1. The analytic privileges of the first kind are assigned to the role `sap.dpp.RestrictBlockedDataAccess`. +2. The analytic privileges, which grant access to all data are assigned to `sap.dpp.DPPNoRestrictions`. + +`sap.dpp.RestrictBlockedDataAccess` is assigned to the [`default_access_role`](https://help.sap.com/docs/SAP_HANA_PLATFORM/4505d0bdaf4948449b7f7379d24d0f0d/9235c9dd8dbf410f915ffe305296a032.html), from the HDI container, so the database user used by the application layer can access the views with blocked data, while the restriction is enforced. + +`sap.dpp.DPPNoRestrictions` is generated as a quality of life role, so applications can easily assign it to support users if blocked data must be accessed. + +#### Restricting access to tables +Because analytic privileges cannot be assigned to tables, another solution is necessary. + +You can configure the table restrictions via `cds.env.requires['sap.ilm.RetentionService'].tableRestrictions: "srv" | "db"`. The default is 'srv'. + +##### Database based table restrictions + +The first option is to strip the HDI user of its schema SELECT privileges and instead only assign SELECT privileges to tables which do not contain any blocked data. +While this is the preferred solution to restrict access by design, it has severe implications for much of an application as direct table access is no longer possible. As such the application layer restrictions are the default. + +##### Application layer based table restrictions (default) + +Thus the default is application layer table restrictions, meaning for all queries targeting a table, a where clause is added. The where clause is added via a before handler in CAPs Database service. This means all CAP requests send via the CAP database service are covered. However three limitations exists with this approach, of which applications must be aware: + +1. Plain SQLs send via CAPs database service are not covered as only CQN queries can be safely enhanced with the where clause. +2. The restrictions are not enforced for other consumers like SAP Analytics Cloud, Business Data Cloud or Enterprise Search. +3. The restrictions are not enforced within database native objects, e.g. when applications leverage HANA Cloud procedures. + +Furthermore application layer access restrictions are skipped if the application layer user has the "privileged" flag from CAP. This is done to offer applications still a way to access all data. (The privileged flag cannot be set via HTTP and can only be set CAP internally when CAP services call other CAP services within the same process) + +### Access restrictions on other databases + +For other databases the application layer table restrictions are applied to views as well. Meaning the three limitations mentioned in [the section above](#application-layer-based-table-restrictions-default) also apply for views for other databases apart from HANA Cloud. + +### Auditor access +A key requirement when considering how auditors should have access to blocked data, is that auditors should be able to open a regular app, like 'Manage Sales Orders' and see regular and blocked data. It should not be needed for auditors to open a separate app, to avoid confusion and to show the business data within the designed environment. + +::: details Implementation of auditor access + +The implementation is, that the application layer sets a session context variable of type string, where all roles assigned to the user are appended as a single string, separated by a comma. + +The Analytic Privileges on HANA have an additional condition, which checks whether the session context variable contains any of the configured roles, which should have access to the blocked data. The roles are configured during design time and cannot dynamically be modified during runtime (or would require a redeployment). + +The session context variable is cleared after the request was completed, to avoid session context spillage. + +For application layer based restrictions, the role check is implemented as part of the before handler. Only if the required role is not assigned to the user, the where condition, to prohibit access to blocked data, is assigned. + +::: + +By default the role against which the check runs is the 'Auditor' role, hence when a user has an XSUAA scope or Cloud Identity Service group called 'Auditor' assigned, they can access blocked data. +You can override this by annotating + +```cds +annotate bookshop.Customers with @( + Auditing.AuditorScopes : [ + 'CUSTOMER_AUDITOR' + ] +) +``` + +or + +```cds +@Auditing.DefaultAuditorScopes : [ + 'CATALOG_AUDITOR' +] +service CatalogService {} +``` + +The first sample sets a custom auditor role for just the 'Customers' entity. The second sample sets a custom auditor role for the whole catalog service and all ILM objects and data subjects within. When an entity within the service annotated with `@Auditing.DefaultAuditorScopes` is annotated with `Auditing.AuditorScopes`, `Auditing.AuditorScopes` takes precedence and the auditing default is ignored. + +## Miscellaneous + +### Audit logging + +The retention service leverages CAPs inbuilt audit logging capabilities to ensure all queries done by the Retention Manager DPI module against the database are properly logged. + +### Troubleshooting + +The logger component is `data-privacy` and extensive debug logs are written to allow you to understand what is happening behind the scenes of the plugin. + +### Extending the Retention service (optional) + +You can extend the `sap.ilm.RetentionService` yourself and manually expose entities if you want to rename files or adjust annotations for the exposed entity. + +The plugin checks which entities are already exposed and then won't expose them another time. Extending the retention service can be useful. For example if the data controller ID is not stored directly on the entity itself it can still be added to the service interface without migrating the base tables. + +```cds +using {sap.ilm.RetentionService} from '@sap/cds-dpi'; +using {sap.capire.bookshop as db} from '../db/schema'; + +extend service RetentionService with { + entity Orders as projection on db.Orders { + ID, + legalEntity.company @PersonalData.FieldSemantics : 'DataControllerID', + endOfWarrantyDate as aliasEndOfBusiness, + Customer, + Items + } +} +``` + +## Archiving + +The archiving capabilities of the Retention Management application are currently not supported by the plugin but are planned to be added throughout 2026 by leveraging HANA Cloud Native Storage Extensions and HANA Cloud Data Lake as the archive's persistence. + +## Connecting SAP Data Privacy Integration + +Next, we will briefly detail the integration to Retention Management application of SAP DPI. +For further details, see the [SAP Data Privacy Integration - Developer Guide](https://help.sap.com/docs/data-privacy-integration/development/getting-started-data-privacy-integration-nextgen). + +### Subscribe to SAP Data Privacy Integration + +[Subscribe to the service](https://help.sap.com/docs/data-privacy-integration) from the _Service Marketplace_ in the SAP BTP cockpit. + +![A screenshot of the tile in the cockpit for the SAP Data Privacy Integration service.](./assets/data-privacy/dpiCockpit.png){width="300"} + +Follow the wizard to create your subscription. + +### Prepare for Deployment + +The SAP DPI NG service cannot connect to your application running locally. Therefore, you need to deploy your application. Here is what you need to do in preparation. + +1. Add SAP HANA Cloud configuration, authentication configuration, and an _mta.yaml_ to your project: + + ```sh + cds add hana,xsuaa,mta + ``` + +[Learn more about authorization in CAP using Node.js.](/@external/node.js/authentication#jwt){.learn-more} + +### Add deployment configuration for SAP DPI + +Add the deployment configuration for SAP DPI: + +```sh +cds add data-privacy +``` + +::: details What the command adds + +The command add the configuration for the SAP DPI NG instance configuring the Retention Management application, the connection to the CAP application and the XSUAA scope assigned to the SAP DPI NG instance. + +::: code-group + +```yaml [mta.yaml] +modules: + - name: incidents-srv + ... + requires: + ... + - name: incidents-retention # [!code ++] +... +resources: + ... + - name: incidents-retention # [!code ++] + type: org.cloudfoundry.managed-service # [!code ++] + requires: # [!code ++] + - name: srv-api # [!code ++] + parameters: # [!code ++] + service-name: incidents-retention # [!code ++] + service: data-privacy-integration-service # [!code ++] + service-plan: data-privacy-internal # [!code ++] + config: # [!code ++] + xs-security: # [!code ++] + xsappname: incidents-retention-${org}-${space} # [!code ++] + authorities: # [!code ++] + - $ACCEPT_GRANTED_AUTHORITIES # [!code ++] + dataPrivacyConfiguration: # [!code ++] + configType: retention # [!code ++] + applicationConfiguration: # [!code ++] + applicationName: incidents-retention # [!code ++] + applicationDescription: bookshop-retention # [!code ++] + applicationDescriptionKey: APPLICATION_NAME # [!code ++] + applicationBaseURL: ~{srv-api/srv-url} # [!code ++] + applicationTitle: incidents # [!code ++] + enableAutoSubscription: true # [!code ++] + translationConfiguration: # [!code ++] + textBundleEndPoint: /dpp/retention/i18n-files/i18n.properties # [!code ++] + defaultLanguage: en # [!code ++] + supportedLanguages: # [!code ++] + - de # [!code ++] + - fr # [!code ++] + - es # [!code ++] + - en # [!code ++] + retentionConfiguration: # [!code ++] + applicationConfiguration: # [!code ++] + applicationType: TransactionMaster # [!code ++] + iLMObjectDiscoveryEndPoint: /dpp/retention/iLMObjects # [!code ++] + ... + - name: incidents-auth + type: org.cloudfoundry.managed-service + parameters: + service: xsuaa + service-plan: application + config: + xsappname: incidents-${org}-${space} + tenant-mode: dedicated + scopes: + - name: $XSAPPNAME.DataRetentionManagerUser # [!code ++] + description: Technical scope to restrict access to retention endpoint # [!code ++] + grant-as-authority-to-apps: # [!code ++] + - $XSSERVICENAME(incidents-retention) # [!code ++] + +``` + +::: + +::: + +::: warning More configuration is being added to the mta.yaml file during `cds build` + +Retention Management has three important objects: 1. Data Subjects, 2. ILM Objects, 3. Organization attributes. +While ILM Objects can be dynamically supplied to Retention Management via an endpoint, data subjects and organization attributes must be provided during deploy time. However as data subjects and organizational attributes depend on your CDS annotated data model, they are added late during `cds build`, where the plugin will analyse the model and add the correct data subjects and organization attributes configuration. + +::: + +### Build and Deploy Your Application + +:::details MT-scenario + +```sh +cds add multitenancy +npm update --package-lock-only +npm update --package-lock-only --prefix mtx/sidecar +``` + +For multi-tenancy, the "enableAutoSubscription" parameter in the `mta.yaml` file is false. + +::: + +The general deployment is described in detail in [Deploy to Cloud Foundry guide](/@external/guides/deploy/to-cf). Here's for short what you need to do. + +```sh +cds up +``` + +### Assign Role Collections + +SAP Data Privacy Integration comes with the following role collections for retention management: + +- DPI_NextGen_Retention_DataManagement_Administrator +- DPI_NextGen_Retention_DataManagement_Configuration_Administrator +- DPI_NextGen_Retention_DataPrivacy_Administrator +- DPI_NextGen_Retention_DataPrivacy_Configuration_Administrator + +[Learn more about Assigning Role Collections to Users or User Groups](https://help.sap.com/docs/btp/sap-business-technology-platform/assigning-role-collections-to-users-or-user-groups){.learn-more} + +## Using the SAP DPI NG Retention Management application + +Open the SAP DPI NG service from the _Instances and Subscriptions_ page in the SAP BTP cockpit. + +![To open the DPI NG launchpad, open the three dot menu and select "Go to Application".](./assets/data-privacy/dpingCockpit.png){width="500"} + + +> TODO: Add instructions / screenshots for how to configure data controllers, retention policies and then delete the actual data \ No newline at end of file diff --git a/guides/security/dpp-pdm.md b/guides/security/dpp-pdm.md index bd84c95a59..a68d4249b5 100644 --- a/guides/security/dpp-pdm.md +++ b/guides/security/dpp-pdm.md @@ -1,20 +1,19 @@ --- synopsis: > - The Personal Data Management (PDM) guide explains how to integrate your CAP application with the SAP Personal Data Manager service to respond to data subject requests about their personal data stored in your application. -status: released + The Information Reporting guide explains how to integrate your CAP application with the SAP Data Privacy Integration NG service to respond to data subject requests about their personal data stored in your application. --- -# Personal Data Management +# Information Reporting {{ $frontmatter.synopsis }} :::warning To follow this cookbook hands-on you need an enterprise account. -The SAP Personal Data Manager service is currently only available for [enterprise accounts](https://discovery-center.cloud.sap/missiondetail/3019/3297/). An entitlement in trial accounts is not possible. +The SAP Data Privacy Integration NG service is currently only available for [enterprise accounts](https://discovery-center.cloud.sap/missiondetail/3019/3297/). An entitlement in trial accounts is not possible. ::: -SAP BTP provides the [*SAP Personal Data Manager (PDM)*](https://help.sap.com/docs/PERSONAL_DATA_MANAGER) which allows administrators to respond to the question "What data of me do you have?". To answer this question, the PDM service needs to fetch all personal data using an OData endpoint. That endpoint has to be provided by the application as follows. +SAP BTP provides the [*SAP Data Privacy Integration Next Gen (DPI)*](https://help.sap.com/docs/data-privacy-integration/end-user-information/what-is-data-privacy-integration-nextgen) service, whose module "Information Reporting" allows administrators to respond to the question "What data of me do you have?". To answer this question, the DPI service needs to fetch all personal data using an OData endpoint. That endpoint has to be provided by the application as follows. [[toc]] @@ -24,266 +23,231 @@ First identify entities and elements (potentially) holding personal data using ` > We keep using the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app). -## Provide a Service Interface to SAP Personal Data Manager +## Install the DPI plugin -SAP Personal Data Manager needs to call into your application to read personal data so you have to define a respective service endpoint, complying to the interface required by SAP Personal Data Manager. -Following the CAP principles, we recommend adding a new dedicated CAP service that handles all the personal data manager requirements for you. This keeps the rest of your data model clean and enables reuse, just as CAP promotes it. - - - -### CAP Service Model for SAP Personal Data Manager - -Following the [best practice of separation of concerns](../domain/index#separation-of-concerns), we create a dedicated service for the integration with SAP Personal Data Manager: - -::: code-group -```cds [srv/pdm-service.cds] -using {sap.capire.incidents as db} from '../db/schema'; - -@requires: 'PersonalDataManagerUser' // security check -service PDMService @(path: '/pdm') { - - // Data Privacy annotations on 'Customers' and 'Addresses' are derived from original entity definitions - entity Customers as projection on db.Customers; - entity Addresses as projection on db.Addresses; - entity Incidents as projection on db.Incidents - - // create view on Incidents and Conversations as flat projection - entity IncidentConversationView as - select from Incidents { - ID, - title, - urgency, - status, - key conversation.ID as conversation_ID, - conversation.timestamp as conversation_timestamp, - conversation.author as conversation_author, - conversation.message as conversation_message, - customer.ID as customer_ID, - customer.email as customer_email - }; - - // annotate new view - annotate PDMService.IncidentConversationView with @(PersonalData.EntitySemantics: 'Other') { - customer_ID @PersonalData.FieldSemantics: 'DataSubjectID'; - }; - - // annotations for Personal Data Manager - Search Fields - annotate Customers with @(Communication.Contact: { - n : { - surname: lastName, - given : firstName - }, - bday : dateOfBirth, - email: [{ - type : #preferred, - address: email}] - }); +```sh +npm install @cap-js/data-privacy +``` - }; +The plugin for the DPI service automatically generates the OData service interface necessary for the DPI service to read the personal data, based on your annotated data model. The `sap.dpp.InformationService` service is provided at the path `/dpp/information` and requires the `PersonalDataManagerUser` role to access it. +## Which entities are exposed by the plugin -``` -::: +- All entities annotated with `@PersonalData.EntitySemantics` are automatically included in the Information service +- Compositions of said entities are exposed as well and inherit the entity semantics from their parent +- Compositions of data subjects (`@PersonalData.EntitySemantics: DataSubject`) are expected to be annotated with `@PersonalData.EntitySemantics: DataSubjectDetails` ::: tip Make sure to have [indicated all relevant entities and elements in your domain model](dpp-annotations). ::: +## How to customize the DPI Information retrieval user interface +With `@UI.LineItem` and `@UI.FieldGroup` you can customize how the table representation of an entity set or the form of an entity looks. If you did not provide your own line item or field group, the plugin will automatically generate one including all fields. -### Provide Flat Projections - -As an additional step, you have to create flat projections on the additional business data, like transactional data. - -In our model, we have `Incidents` and `Conversations`, which are connected via a composition. Since SAP Personal Data Manager needs flattened out structures, we define a helper view `IncidentConversationView` to flatten this out. - -We have to then add data privacy-specific annotations to this new view as well. The `IncidentConversationView` as transactional data is marked as `Other`. In addition, it is important to tag the correct field, which defines the corresponding data subject, in our case that is `customer_ID @PersonalData.FieldSemantics: 'DataSubjectID';` - - - -### Annotating Search Fields - -In addition, the most important search fields of the data subject have to be annotated with the corresponding annotation `@Communication.Contact`. - -To perform a valid search in the SAP Personal Data Manager application, you will need _Surname_, _Given Name_, and _Email_ or the _Data Subject ID_. Details about this annotation can be found in -[Communication Vocabulary](https://github.com/SAP/odata-vocabularies/blob/main/vocabularies/Communication.md). - -Alternatively to the tuple _Surname_, _Given Name_, and _Email_, you can also use _Surname_, _Given Name_, and _Birthday_ (called `bday`), if available in your data model. Details about this can be found in -[SAP Personal Data Manager - Developer Guide](https://help.sap.com/docs/personal-data-manager/4adcd96ce00c4f1ba29ed11f646a5944/v4-annotations?q=Contact&locale=en-US). - - - -### Restrict Access Using the `@requires` Annotation - -To restrict access to this sensitive data, the `PDMservice` is protected by the `@requires: 'PersonalDataManagerUser'` annotation. Calling the `PDMservice` externally without the corresponding permission is forbidden. The Personal Data Manager service calls the `PDMservice` with the needed role granted. This is configured in the _xs-security.json_ file, which is explained later. +```cds +@UI.LineItem : [ + { + Value : ID, + }, + { + Value : OrderNo, + }, +] +@UI.FieldGroup : { + Data: [ + { + Value : ID, + }, + { + Value : OrderNo, + }, + ] +} +entity Orders as projection on db.Orders; +``` -[Learn more about security configuration and the SAP Personal Data Manager.](https://help.sap.com/docs/PERSONAL_DATA_MANAGER/620a3ea6aaf64610accdd05cca9e3de2/4ee5705b8ded43e68bde610223722971.html#loio8eb6d9f889594a2d98f478bd57412ceb){.learn-more} +Use `@title` to add labels to fields and entities to specify readable names within the Information Reporting UI. +All possible annotations used by SAP DPI are listed in the [SAP Data Privacy Integration - Developer Guide](https://help.sap.com/docs/data-privacy-integration/development/odata-v4-data-privacy-integration-nextgen-c16fbaf659b6444ebb1a880503688162). +## Annotating the data subject +In addition, the data subject must be annotated with the `@Communication.Contact`. -At this point, you are done with your application. Let's set up the SAP Personal Data Manager and try it out. +To perform a valid search in the "Manage Personal Data" application, you will need _Surname_, _Given Name_, and _Email_ or the _Data Subject ID_. Details about this annotation can be found in the [Communication Vocabulary](https://github.com/SAP/odata-vocabularies/blob/main/vocabularies/Communication.md). +Alternatively to the tuple _Surname_, _Given Name_, and _Email_, you can also use _Surname_, _Given Name_, and _Birthday_ (called `bday`), if available in your data model. Details about this can be found in the [SAP Data Privacy Integration - Developer Guide](https://help.sap.com/docs/data-privacy-integration/development/odata-v4-data-privacy-integration-nextgen-c16fbaf659b6444ebb1a880503688162?q=Contact&locale=en-US). - +At this point, you are done with your application. Let's set up the SAP Data Privacy Integration service and try it out. -## Connecting SAP Personal Data Manager +## Extending the Information service (optional) -Next, we will briefly detail the integration to SAP Personal Data Manager. -A more comprehensive guide, incl. tutorials, is currently under development. -For further details, see the [SAP Personal Data Manager Developer Guide](https://help.sap.com/docs/personal-data-manager/4adcd96ce00c4f1ba29ed11f646a5944/what-is-personal-data-manager). +You can extend the `sap.dpp.InformationService` yourself and manually expose entities if you want to rename entities or properties or adjust annotations for the exposed entity. -### Activate Access Checks in _xs-security.json_ +The plugin checks which entities are already exposed and then won't expose them another time. -Because we protected the `PDMservice`, we need to establish the security check properly. In particular, you need the _xs-security.json_ file to make the security check active. The following _xs-security.json_ is from our sample. +```cds +using {sap.dpp.InformationService} from '@sap/cds-dpi'; +using {sap.capire.incidents as db} from '../db/schema'; -```json -{ - "xsappname": "incidents-mgmt", - "tenant-mode": "shared", - "scopes": [ - { - "name": "$XSAPPNAME.PersonalDataManagerUser", - "description": "Authority for Personal Data Manager", - "grant-as-authority-to-apps": [ - "$XSSERVICENAME(pdm)" - ] +extend service InformationService with { + entity Incidents as projection on db.Incidents { + ID, + legalEntity, + incidentResolvedDate as aliasEndOfBusiness, + customer, + conversations } - ] } ``` -Here you define that your personal data manager service instance, called `pdm`, is allowed to access your CAP application granting the `PersonalDataManagerUser` role. +## Connecting SAP Data Privacy Integration +Next, we will briefly detail the integration to Information Reporting module of SAP DPI. +For further details, see the [SAP Data Privacy Integration - Developer Guide](https://help.sap.com/docs/data-privacy-integration/development/getting-started-data-privacy-integration-nextgen). +### Subscribe to SAP Data Privacy Integration -### Add `@sap/xssec` Library +[Subscribe to the service](https://help.sap.com/docs/data-privacy-integration) from the _Service Marketplace_ in the SAP BTP cockpit. -To make the authentication work, you have to enable the security strategy by installing the `@sap/xssec` package: +![A screenshot of the tile in the cockpit for the SAP Data Privacy Integration service.](./assets/data-privacy/dpiCockpit.png){width="300"} -```sh -npm install @sap/xssec -``` +Follow the wizard to create your subscription. -[Learn more about authorization in CAP using Node.js.](../../node.js/authentication#jwt){.learn-more} +### Prepare for Deployment -### Build and Deploy Your Application +The SAP DPI service cannot connect to your application running locally. Therefore, you need to deploy your application. Here is what you need to do in preparation. -The Personal Data Manager can't connect to your application running locally. Therefore, you first need to deploy your application. In our sample, we added two manifest files using `cds add cf-manifest` and SAP HANA configuration using `cds add hana`. +1. Add SAP HANA Cloud configuration, authentication configuration, and an _mta.yaml_ to your project: -The general deployment is described in detail in [Deploy Using Manifest Files](../deploy/to-cf). + ```sh + cds add hana,xsuaa,mta + ``` -Make a production build: +[Learn more about authorization in CAP using Node.js.](/@external/node.js/authentication#jwt){.learn-more} -```sh -cds build --production -``` +### Add deployment configuration for SAP DPI -Deploy your application: +Add the deployment configuration for SAP DPI: ```sh -cf create-service-push +cds add data-privacy ``` +::: details What the command adds +The command add the configuration for the SAP DPI instance configuring the Information Reporting application, the connection to the CAP application and the XSUAA scope assigned to the SAP DPI instance. -### Subscribe to SAP Personal Data Manager Service - -[Subscribe to the service](https://help.sap.com/docs/PERSONAL_DATA_MANAGER/620a3ea6aaf64610accdd05cca9e3de2/ef10215655a540b6ba1c02a96e118d66.html) from the _Service Marketplace_ in the SAP BTP cockpit. - -![A screenshot of the tile in the cockpit for the SAP Personal Data Manager service.](assets/data-privacy/pdmCockpitCreate.png){width="300"} - -Follow the wizard to create your subscription. - - - -### Create Role Collections +::: code-group -SAP Personal Data Manager comes with the following roles: +```yaml [mta.yaml] +modules: + - name: incidents-srv + ... + requires: + ... + - name: incidents-information # [!code ++] +... +resources: + ... + - name: incidents-information # [!code ++] + type: org.cloudfoundry.managed-service # [!code ++] + requires: # [!code ++] + - name: srv-api # [!code ++] + parameters: # [!code ++] + service-name: incidents-information # [!code ++] + service: data-privacy-integration-service # [!code ++] + service-plan: data-privacy-internal # [!code ++] + config: # [!code ++] + xs-security: # [!code ++] + xsappname: incidents-information-${org}-${space} # [!code ++] + authorities: # [!code ++] + - $ACCEPT_GRANTED_AUTHORITIES # [!code ++] + dataPrivacyConfiguration: # [!code ++] + configType: information # [!code ++] + applicationConfiguration: # [!code ++] + applicationName: incidents-information # [!code ++] + applicationDescription: DPI NextGen Incidents CAP Reference Application # [!code ++] + applicationTitle: DPI NextGen Incidents # [!code ++] + enableAutoSubscription: true # [!code ++] + informationConfiguration: # [!code ++] + applicationConfiguration: # [!code ++] + dataSubjectDeletionAgent: retention-manager # [!code ++] + retentionApplicationName: incidents-retention # [!code ++] + disableDataSubjectCorrection: true # [!code ++] + cacheControl: no-cache # [!code ++] + components: # [!code ++] + - componentName: incidents-srv # [!code ++] + componentBaseURL: ~{srv-api/srv-url} # [!code ++] + serviceEndPoints: # [!code ++] + - serviceName: dpi-service # [!code ++] + serviceFormat: odata-v4 # [!code ++] + annotationFormat: v4 # [!code ++] + serviceEndPoint: /dpp/information # [!code ++] + appPaginationEnabled: true # [!code ++] + cacheControl: no-cache # [!code ++] + ... + - name: incidents-auth + type: org.cloudfoundry.managed-service + parameters: + service: xsuaa + service-plan: application + config: + xsappname: incidents-${org}-${space} + tenant-mode: dedicated + scopes: + - name: $XSAPPNAME.PersonalDataManagerUser # [!code ++] + description: Technical scope to restrict access to information endpoint # [!code ++] + grant-as-authority-to-apps: # [!code ++] + - $XSSERVICENAME(incidents-information) # [!code ++] -Role Name | Role Template -----------|------ -PDM_Administrator | PDM_Administrator -PDM_CustomerServiceRepresentative | PDM_CustomerServiceRepresentative -PDM_OperatorsClerk | PDM_OperatorsClerk +``` -All of these roles have two different _Application Identifiers_. -::: tip -Application identifiers with **!b** are needed for the UI, and identifiers with **!t** are needed for executing the Postman collection. ::: -[Learn more about defining a role collection in SAP BTP cockpit](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/4b20383efab341f181becf0a947a5498.html){.learn-more} - - - -### Create a Service Instance - -You need a configuration file, like the following, to create a service instance for the Personal Data Manager. - -`pdm-instance-config.json` -```json -{ - "xs-security": { - "xsappname": "incidents-mgmt", - "authorities": ["$ACCEPT_GRANTED_AUTHORITIES"] - }, - "fullyQualifiedApplicationName": "incidents-mgmt", - "appConsentServiceEnabled": true -} - +::: -``` +### Build and Deploy Your Application -Create a service instance using the SAP BTP cockpit or execute the following command: +:::details MT-scenario ```sh -cf create-service personal-data-manager-service standard incidents-mgmt-pdm -c ./pdm-instance-config.json +cds add multitenancy +npm update --package-lock-only +npm update --package-lock-only --prefix mtx/sidecar ``` +For multi-tenancy, the "enableAutoSubscription" parameter in the `mta.yaml` file must be false. +::: -### Bind the Service Instance to Your Application. - -With both the application deployed and the SAP Personal Data Manger service set up, you can now bind the service instance of the Personal Data Manager to your application. Use the URL of your application in a configuration file, such as the following example, which you need when binding a service instance. +The general deployment is described in detail in [Deploy to Cloud Foundry guide](/@external/guides/deploy/to-cf). Here's for short what you need to do. -`pdm-binding-config.json` -```json -{ - "fullyQualifiedApplicationName": "incidents-mgmt", - "fullyQualifiedModuleName": "incidents-mgmt-srv", - "applicationTitle": "PDM Incidents", - "applicationTitleKey": "PDM Incidents", - "applicationURL": "https://incidents-mgmt-srv.cfapps.eu10.hana.ondemand.com/", // get the URL from the CF CLI command: cf apps - "endPoints": [ - { - "type": "odatav4", - "serviceName": "pdm-service", - "serviceTitle": "Incidents Management", - "serviceTitleKey": "IncidentsManagement", - "serviceURI": "pdm", - "hasGdprV4Annotations": true, - "cacheControl": "no-cache" - } - ] -} +```sh +cds up ``` -Here the `applicationURL`, the `fullyQualifiedModuleName`, and the `serviceURI` have to be those of your Cloud Foundry deployment and your CAP service definition (_services-manifest.yaml_). +### Assign Role Collections -Bind the service instance using the SAP BTP cockpit or execute the following command: +SAP Data Privacy Integration comes with the following role collections for Information reporting: -```sh -cf bind-service incidents-mgmt-srv incidents-mgmt-pdm -c ./pdm-binding-config.json -``` +- DPI_NextGen_Information_CustomerServiceRepresentative +- DPI_NextGen_Information_OperationsClerk +- DPI_NextGen_Information_DataPrivacy_Administrator + +[Learn more about Assigning Role Collections to Users or User Groups](https://help.sap.com/docs/btp/sap-business-technology-platform/assigning-role-collections-to-users-or-user-groups){.learn-more} +## Using the Information Reporting application +Open the SAP DPI service from the _Instances and Subscriptions_ page in the SAP BTP cockpit. -## Using the SAP Personal Data Manager Application +![To open the DPI launchpad, open the three dot menu and select "Go to Application".](./assets/data-privacy/dpingCockpit.png){width="500"} -Open the SAP Personal Data Manager application from the _Instances and Subscriptions_ page in the SAP BTP cockpit. +![Open the "Manage Personal Data" application.](./assets/data-privacy/dpi_ng_launchpad.png){width="500"} -![To open the application, open the three dot menu and select "Go to Application".](assets/data-privacy/pdmCockpit.png){width="500"} +In this application you can search for data subjects with _First Name_, _Last Name_, and _Date of Birth_, or alternatively with their _ID_. -In the personal data manager application you can search for data subjects with _First Name_, _Last Name_, and _Date of Birth_, or alternatively with their _ID_. +![A screenshot of the SAP DPI Manage Personal Data application.](./assets/data-privacy/pdmApplication.png){width="500"} -![A screenshot of the SAP Personal Data Manager application.](assets/data-privacy/pdmApplication.png){width="500"} \ No newline at end of file +[Learn more about the applications SAP DPI Information Reporting offers](https://help.sap.com/docs/data-privacy-integration/end-user-information/information-reporting-data-privacy-integration-nextgen?locale=en-US){.learn-more}