Audit Logging
Find here information about the AuditLog service in CAP Java.
AuditLog Service
Overview
As of CAP Java 1.18.0, an AuditLog service is provided for CAP Java applications. The AuditLog service can be used to emit AuditLog related events to registered handlers.
The following events can be emitted with the AuditLogService to the registered handlers:
AuditLog events typically are bound to business transactions. In order to handle the events transactionally and also to decouple the request from outbound calls to a consumer, for example a central audit log service, the AuditLog service leverages the outbox service internally which allows deferred sending of events.
Use AuditLogService
Get AuditLogService Instance
The AuditLogService
can be injected into a custom handler class, if the CAP Java project uses Spring Boot:
import com.sap.cds.services.auditlog.AuditLogService;
@Autowired
private AuditLogService auditLogService;
Alternatively the AuditLog service can be retrieved from the ServiceCatalog
:
ServiceCatalog catalog = context.getServiceCatalog();
auditLogService = (AuditLogService) catalog.getService(AuditLogService.DEFAULT_NAME);
See section Using Services for more details about retrieving services.
Emit Personal Data Access Event
To emit a personal data access event use method logDataAccess of the AuditLogService
.
List<Access> accesses = new ArrayList<>();
Access access = Access.create();
// fill access object with data
accesses.add(access);
auditLogService.logDataAccess(accesses);
Emit Personal Data Modification Event
To emit a personal data modification event use method logDataModification of the AuditLogService
.
List<DataModification> dataModifications = new ArrayList<>();
DataModification modification = DataModification.create();
// fill data modification object with data
dataModifications.add(modification);
auditLogService.logDataModification(dataModifications);
Emit Configuration Change Event
To emit a configuration change event use method logConfigChange of the AuditLogService
.
List<ConfigChange> configChanges = new ArrayList<>();
ConfigChange configChange = ConfigChange.create();
// fill config change object with data
configChanges.add(configChange);
auditLogService.logConfigChange(Action.UPDATE, configChanges);
Emit Security Event
Use method logSecurityEvent of the AuditLogService
to emit an security event.
String action = "login";
String data = "user-name";
auditLogService.logSecurityEvent(action, data);
Deferred AuditLog Events
Instead of processing the audit log events synchronously in the audit log handler, the AuditLogService
can store the event in the outbox. This is done in the same transaction of the business request. Hence, a cancelled business transaction will not send any audit log events that are bound to it. To gain fine-grained control, for example to isolate a specific event from the current transaction, you may refine the transaction scope. See ChangeSetContext API for more information.
As the stored events are processed asynchronously, the business request is also decoupled from the audit log handler which typically sends the events synchronously to a central audit log service. This improves resilience and performance.
By default, the outbox comes in an in-memory flavour which has the drawback that it can't guarantee that the all events are processed after the transaction has been successfully closed.
To close this gap, a sophisticated persistent outbox service can be configured.
By default, not all events are send asynchronously via (persistent) outbox.
- Security events are always send synchronously.
- All other events are stored to persistent outbox, if available. The in-memory outbox acts as a fallback otherwise.
❗ Compliance & Data Privacy
- It is up to the application developer to make sure that audit log events stored in the persistent outbox don't violate given compliance rules. For instance, it might be appropriate not to persist audit log events triggered by users who have operator privileges. Such logs could be modified on DB level by the same user afterward.
- For technical reasons, the AuditLog service temporarily stores audit log events enhanced with personal data such as the request's user and tenant. In case of persistent outbox, this needs to be handled individually by the application to comply with data privacy rules.
AuditLog Handlers
Default Handler
By default, the CAP Java SDK provides an AuditLog handler that writes the AuditLog messages to the application log. This default handler is registered on all AuditLog events and writes DEBUG
log entries. However, the application log does not log DEBUG
entries by default. To enable audit logging to the application log, the log level of the default handler needs to be set to DEBUG
level:
logging:
level:
com.sap.cds.auditlog: DEBUG
AuditLog v2 Handler
Additionally, the CAP Java SDK provides an AuditLog v2 handler that writes the audit messages to the SAP Audit Log service via its API version 2. To enable this handler, an additional feature dependency must be added to the srv/pom.xml
of the CAP Java project:
<dependency>
<groupId>com.sap.cds</groupId>
<artifactId>cds-feature-auditlog-v2</artifactId>
<scope>runtime</scope>
</dependency>
Also a service binding to the AuditLog v2 service has to be added to the CAP Java application, then this handler is activated. The Auditlog v2 handler supports the premium
plan of the AuditLog Service as described here.
If it's required to disable the AuditLog v2 handler for some reason, this can be achieved by setting the CDS property cds.auditLog.v2.enabled
to false
in application.yaml:
cds:
auditlog.v2.enabled: false
The default value of this parameter is true
and the AuditLog v2 handler is automatically enabled, if all other requirements are fulfilled.
Custom AuditLog Handler
CAP Java applications can also provide their own AuditLog handlers to implement custom processing of AuditLog events. The custom handler class has to implement the interface EventHandler
and needs to be annotated with @ServiceName(value = "*", type = AuditLogService.class)
. If the CAP Java project uses Spring Boot, the class can be annotated with @Component
to register the handler at the CDS runtime.
For each of the four supported AuditLog events, a handler method can be registered. Depending on the event type, the method signature has to support the corresponding argument type:
With one of the annotations @Before
, @On
, and @After
the handler method needs to be annotated to indicate in which phase of the event processing this method gets called.
The following example defines an AuditLog event handler class with methods for all event types:
import com.sap.cds.services.auditlog.*;
import com.sap.cds.services.handler.*;
import com.sap.cds.services.handler.annotations.*;
import org.springframework.stereotype.*;
@Component
@ServiceName(value = "*", type = AuditLogService.class)
class CustomAuditLogHandler implements EventHandler {
@On
public void handleDataAccessEvent(DataAccessLogContext context) {
// custom handler code
}
@On
public void handleDataModificationEvent(DataModificationLogContext context) {
// custom handler code
}
@On
public void handleConfigChangeEvent(ConfigChangeLogContext context) {
// custom handler code
}
@On
public void handleSecurityEvent(SecurityLogContext context) {
// custom handler code
}
}
Learn more about implementing an event handler in Event Handler Classes.