The @cap-js/audit-logging plugin provides out-of-the box support for automatic audit logging of data privacy-related events, in particular changes to personal data and reads of sensitive data. Find here a step-by-step guide how to use it.
The following is mainly written from a Node.js perspective. For Java's perspective, please see Java - Audit Logging.
To enable automatic audit logging simply add the @cap-js/audit-logging plugin package to your project like so:
Behind the Scenes…
CDS Plugin Packages are self-contained extensions. They not only include the relevant code but also bring their own default configuration. In our case, next to bringing the respective code, the plugin does the following:
Sets cds.requires.audit-log: true in cds.env, equivalent to:
Which in turn activates the audit-log configuration presets:
While we simply dumped audit log messages to stdout in local development, we'll be using the SAP Audit Log Service on SAP BTP in production. Following is a brief description of the necessary steps for setting this up. A more comprehensive guide, incl. tutorials, is currently under development.
In addition to the generic audit logging provided out of the box, applications can also log custom events with custom data using the programmatic API.
Connecting to the service:
const audit =await cds.connect.to('audit-log')
Sending log messages:
Audit Logging as Just Another CAP Service
The Audit Log Service API is implemented as a CAP service, with the service API defined in CDS as shown in the next section. In effect, the common patterns of CAP Service Consumption apply, as well as all the usual benefits like mocking, late-cut µ services, resilience and extensibility.
Below is the complete reference modeling as contained in @cap-js/audit-logging. The individual operations and events are briefly discussed in the following sections.
The service definition declares the generic log operation, which is used for all kinds of events, as well as the common type LogEntry, which declares the common fields of all log messages. These fields are filled in automatically by the base service and any values provided by the caller are ignored.
Further, the service has pre-defined event payloads for the four event types:
By default, all log messages are sent through a transactional outbox. This means, when sent, log messages are first stored in a local outbox table, which acts like a queue for outbound messages. Only when requests are fully and successfully processed, these messages are forwarded to the audit log service.
This provides an ultimate level of resiliency, plus additional benefits:
Audit log messages are guaranteed to be delivered — even if the audit log service should be down for a longer time period.
Asynchronous delivery of log messages — the main thread doesn't wait for requests being sent and successfully processed by the audit log service.
False log messages are avoided — messages are forwarded to the audit log service on successfully committed requests; and skipped in case of rollbacks.
This transparently applies to all implementations, even custom implementations. You can opt out of this default by configuring outbox: false in the configuration, for example, as we do in the default configuration for development: