Issue
As per CAP documentation:
- Each
@PersonalData entity needs to identify a DataSubjectID element.
- For entities with
DataSubject semantics, this is typically the primary key.
- For entities with
DataSubjectDetails or Other semantics, this is usually an association to the data subject.
- Fields marked as
DataSubjectID should use not null to guarantee a value is present at all times.
Note the use of the word typically, meaning it is not mandatory.
However, the audit-logging plugin only works correctly when the DataSubjectID is a key in the database.
While I understand that the DataSubjectID should be a unique identifier, imho it shouldn't enforce this to be a key in the datamodel as well.
Test case
context db {
@PersonalData: {
DataSubjectRole: 'Employee',
EntitySemantics: 'DataSubject'
}
entity Employees {
key ID : Integer;
name : String(100) @PersonalData.IsPotentiallyPersonal;
phoneNumber : String(50) @PersonalData.IsPotentiallyPersonal;
// 1. DataSubjectID as key, works fine
key employeeNumber : String(50) @PersonalData.FieldSemantics: 'DataSubjectID';
// 2. DataSubjectID as non-key, results in empty DataSubjectID in audit log:
// employeeNumber : String(50) not null @PersonalData.FieldSemantics: 'DataSubjectID';
}
}
service ManageDataService {
entity Employees as projection on db.Employees;
}
import cds from "@sap/cds";
export default class ManageDataService extends cds.ApplicationService {
async init() {
await INSERT.into('db_Employees').entries({
ID: 1,
employeeNumber: 'EMP001',
name: 'John Doe',
phoneNumber: '111-111-1111'
})
return super.init();
}
}
PATCH {{server}}/odata/v4/manage-data/Employees(ID=1,employeeNumber='EMP001')
Content-Type: application/json
{
"phoneNumber": "222-222-2222"
}
Tests Results
Case 1: key employeeNumber : String(50) @PersonalData.FieldSemantics: 'DataSubjectID';
[audit-log] - PersonalDataModified: {
data_subject: {
id: { employeeNumber: 'EMP001' },
role: 'Employee',
type: 'ManageDataService.Employees'
},
object: {
type: 'ManageDataService.Employees',
id: { ID: 1, employeeNumber: 'EMP001' }
},
attributes: [ { name: 'phoneNumber', old: '111-111-1111', new: '222-222-2222' } ],
uuid: '0e66969f-abcf-4f64-ba21-debcfed45481',
tenant: undefined,
user: 'anonymous',
time: 2026-05-08T10:30:00.598Z
}
Case 2: employeeNumber : String(50) @PersonalData.FieldSemantics: 'DataSubjectID';
[audit-log] - PersonalDataModified: {
data_subject: { id: {}, role: 'Employee', type: 'ManageDataService.Employees' },
object: { type: 'ManageDataService.Employees', id: { ID: 1 } },
attributes: [ { name: 'phoneNumber', old: '111-111-1111', new: '222-222-2222' } ],
uuid: '625eb308-be87-40e0-8b44-11ebd7583f73',
tenant: undefined,
user: 'anonymous',
time: 2026-05-08T10:29:03.739Z
}
Issue
As per CAP documentation:
Note the use of the word
typically, meaning it is not mandatory.However, the audit-logging plugin only works correctly when the
DataSubjectIDis a key in the database.While I understand that the DataSubjectID should be a unique identifier, imho it shouldn't enforce this to be a key in the datamodel as well.
Test case
Tests Results
Case 1:
key employeeNumber : String(50) @PersonalData.FieldSemantics: 'DataSubjectID';[audit-log] - PersonalDataModified: { data_subject: { id: { employeeNumber: 'EMP001' }, role: 'Employee', type: 'ManageDataService.Employees' }, object: { type: 'ManageDataService.Employees', id: { ID: 1, employeeNumber: 'EMP001' } }, attributes: [ { name: 'phoneNumber', old: '111-111-1111', new: '222-222-2222' } ], uuid: '0e66969f-abcf-4f64-ba21-debcfed45481', tenant: undefined, user: 'anonymous', time: 2026-05-08T10:30:00.598Z }Case 2:
employeeNumber : String(50) @PersonalData.FieldSemantics: 'DataSubjectID';[audit-log] - PersonalDataModified: { data_subject: { id: {}, role: 'Employee', type: 'ManageDataService.Employees' }, object: { type: 'ManageDataService.Employees', id: { ID: 1 } }, attributes: [ { name: 'phoneNumber', old: '111-111-1111', new: '222-222-2222' } ], uuid: '625eb308-be87-40e0-8b44-11ebd7583f73', tenant: undefined, user: 'anonymous', time: 2026-05-08T10:29:03.739Z }