Technology Blog Posts by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
gopalanand
Product and Topic Expert
Product and Topic Expert
1,076

Introduction

While SAP Cloud Application Programming (CAP) provides automatic audit logging through annotations, there are scenarios where you need more granular control over what gets logged. Custom audit logging becomes essential when you want to capture specific security events, such as unauthorised access attempts or track custom business logic violations.
 
In this blog post, we'll explore how to implement custom audit logging in your CAP application to capture 403 Forbidden events when users attempt to access resources without proper authorisation.
 
This blog contains information from the SAP BTP Developer's Guide: https://github.com/SAP-samples/btp-developer-guide-cap/tree/main/documentation

Why Custom Audit Logging?

Enterprise applications often require tracking security events beyond data access. Consider these scenarios:
Security Monitoring: Log unauthorised access attempts
- Compliance Requirements: Track specific business rule violations
- Custom Events: Capture application-specific audit trails
Custom audit logging fills these gaps by giving developers the flexibility to log any event deemed critical for security or compliance.

Setting Up Custom Audit Logging

CAP provides powerful event handlers that allow you to intercept requests and responses. Here's how to implement custom audit logging for security events:
Step 1: Create the Server Extension
Create a server.js file at the root of your CAP application and implement the custom audit logging logic:
 
const cds = require('@sap/cds')

let audit

cds.on('served', async () => {
  audit = await cds.connect.to('audit-log')
})

const audit_log_403 = (resource, ip) => {
  // we need to start our own tx because the default tx may be burnt
  audit.tx(async () => {
    await audit.log('SecurityEvent', {
      data: {
        user: cds.context.user?.id || 'unknown',
        action: `Attempt to access restricted resource "${resource}" with insufficient authority`
      },
      ip
    })
  })
}

// log for non-batch requests
cds.on('bootstrap', app => {
  app.use((req, res, next) => {
    req.on('close', () => {
      if (res.statusCode == 403) {
        const { originalUrl, ip } = req
        audit_log_403(originalUrl, ip)
      }
    })
    next()
  })
})

// log for batch subrequests
cds.on('serving', srv => {
  if (srv instanceof cds.ApplicationService) {
    srv.on('error', (err, req) => {
      if (err.code == 403) {
        const { originalUrl, ip } = req.http.req
        if (originalUrl.endsWith('/$batch')) audit_log_403(originalUrl.replace('/$batch', req.req.url), ip)
      }
    })
  }
})

module.exports = cds.server​

Step 2: Understanding the Implementation

The implementation consists of three key components:

  1. Audit Connection: Establishes a connection to the audit-log service when CAP is served
  2. Custom Audit Function: Creates security event entries with user context and resource information
  3. Event Handlers: Captures 403 errors for both regular and batch requests

The code handles two scenarios:

- Non-batch requests: Uses Express middleware to capture response status codes

- Batch requests: Leverages CAP's error handling for OData batch operations

Testing Your Custom Audit Logging

To verify your implementation works correctly:

  1. Start your CAP server with cds watch
  2. Modify user permissions: Remove the `admin` role from user `alice` in your `package.json`
  3. Send a test request: Use the following HTTP request to trigger a 403 error
GET {{server}}/odata/v4/admin/Customers
Authorization: Basic {{username}}:{{password}}
​
  • Check the console output: You should see a custom audit log entry like this:
[audit-log] - SecurityEvent: {
     data: {
       user: 'alice',
       action: 'Attempt to access restricted resource "/odata/v4/admin/Customers" with insufficient authority'
     },
     ip: '::ffff:127.0.0.1',
     uuid: '1109134c-64db-42f8-a780-2dde61cf6821',
     tenant: undefined,
     user: 'alice',
     time: 2025-05-28T04:59:43.653Z
   }
​

Conclusion

Custom audit logging in CAP applications provides the flexibility needed for comprehensive security monitoring and compliance. By leveraging CAP's event system and audit logging infrastructure, you can create robust audit trails that go beyond standard data access logging.

The implementation shown here focuses on security events, but the same principles apply to any custom audit logging requirements in your enterprise applications.
Learn more about SAP BTP Developer's Guide and More concepts: https://help.sap.com/docs/btp/btp-developers-guide/btp-developers-guide

Note: The views and opinions expressed in this post are my own.