Authorizations in CDS and RAP β An Overview
In customer projects, we keep noticing that authorizations are often a rather unpopular topic. Not infrequently, the authorization concept is reduced to assigning the authorization object S_START (OData V4) or S_SERVICE (OData V2) to the user role β in other words, to the start authorization check that SAP technically requires.
This article aims to shed some light on the topic β with practical tips from real software projects and a bit of RAP background knowledge π. We start with the different levels of an authorization concept and use a set of guiding principles to explain what really matters. We close with special cases and tips and tricks. At the very end you will find a list of further links.
The Levels of Authorization Checks
The basic architecture of RAP-based applications and services consists of the OData service as the endpoint, read access to the database via CDS views, and transactional changes via RAP business objects and their implementation in ABAP.
| Level | Read | Write |
|---|---|---|
| 1 β Start | S_START: The start authorization β who is allowed to execute the OData service in the SAP backend in order to read data or make changes? (applies equally to reading and writing) | |
| 2 β Global | For global authorization checks β that is, checks that are independent of the concrete data (instances) β the activity field ACTVT with the value '03' is used by convention to check whether the current user is allowed to read at all β including in the DCL of the exposed CDS view. One could argue that the S_START authorization check renders the global read check redundant in the context of an OData service: changing without reading rarely makes sense, and anyone who may neither read nor write does not need a start authorization either. However, we recommend using both concepts in order to be prepared for other kinds of access to the data. | With authorization master ( global ), RAP BOs offer the possibility of implementing global checks for the modifying operations via AUTHORITY-CHECK: Is the current user allowed to execute the RAP BO standard operations CREATE, UPDATE, DELETE, or one of the actions at all? This can be controlled individually per operation.Since actions are conceptually special update operations, there is a useful declaration for reusing the update operation's check, i.e. delegating to it. |
| 3 β Instance | In addition to the global ACTVT check, authorization fields can of course be added that vary per instance, e.g. which SalesOrg am I authorized for? While the ACTVT check yields the same result across all instances, the SalesOrg is checked per row, so the unauthorized instances are already filtered out on the database. This allows the OData read access with SADL on a CDS view via RAP (more precisely, via SADL) to be executed functionally correct in a single statement on the database β including paging with limit and offset as well as further filter operations. | With authorization master ( instance ), instance operations can be checked at instance level: Is the current user (who is globally authorized β RAP sensibly checks this beforehand) allowed to change or delete this instance with this operation? The READ operation does not need to be checked in a managed RAP BO, because the RAP runtime reads from the DCL-protected CDS view here as well, so the DCL check already applies indirectly. |
Guiding Principles of Authorization Checks
Authorization checks always take place on the I or R layer, never on the C layer
Authorizations are essential properties of the data and independent of scenario or protocol. The consumption layer semantically belongs to the service level β for different services or apps there are different projections with different data selections and relevant BO operations. The underlying authorization check, however, is identical in every case β just like the business logic and the data (no rule without exceptions). This means the authorization check is declared via DCL in the I and R views and implemented in the RAP BO. The consumption layer inherits this check (DCL: inheriting conditions) or delegates to the RAP BO runtime (BDEF projection).
The transactional buffer must be authorization-compliant at all times
No data may enter the buffer that the user is not authorized for. The risk is too great that functionality is executed based on the unauthorized data and that this is exploited in an attack. Three obligations follow from this principle:
(a) Nothing unauthorized may get in β CREATE. As described above, the instance check is not relevant for static operations β only the global authorization check applies. The global check, however, does not know the data. Therefore, a PRECHECK must be used to verify that no forbidden values were passed with the create (or a static factory method). A validation is not recommended here, because by the time it runs, the data is already in the buffer.
(b) Nothing may become unauthorized through change β UPDATE. This is unfortunately overlooked most of the time: The instance check sees the old state. The new state, however, must be checked as well. If I am authorized for a specific region, I must not be able to "move" data into a different region. The instance authorization checks the initial state, the precheck checks the target state β both are necessary.
(c) Your own code must not write anything unauthorized into the buffer. Internal logic such as determinations or actions via EML IN LOCAL MODE bypasses the authorization checks. This should be known and taken into account during implementation.
Checks happen at the entry point β after that, only privileged access
Authorizations are checked at the exposed entry point, i.e. for all data and operations exposed in the OData service. In application jobs, it is the leading data set that the select options refer to.
Technically, this can be implemented via a privileged mode for the secondary accesses β but unfortunately not everywhere:
| Technology | Privileged mode support |
|---|---|
| CDS | WITH PRIVILEGED ACCESS is a clear consumer decision and available for all CDS views |
| RAP | PRIVILEGED in EML requires that the consumed RAP BO offers privileged mode and has implemented it consistently |
| BAPI | BAPIs generally do not offer a privileged mode (which would arguably be quite dangerous for RFC-enabled function modules anyway) |
GDPR trumps everything
Due to the General Data Protection Regulation, special attention must be paid to the processing of personal data to protect natural persons. Among many other aspects, the topics of data minimization and context-bound disclosure according to the need-to-know principle must be taken into account:
- In a value help listing all business partners, displaying their addresses is certainly not a good idea.
- The person processing a sales order, however, has a legitimate interest in the delivery address.
Sensitive data must not be exposed via value helps. Data on a Fiori object page may be visible at most when access to the leading object is authorized. If, for example, access to the sales order is authorized, (at most) then the buyer's delivery address may be visible as well.
But how do we prevent all addresses from being requested via the OData protocol? For this, the CDS view must be equipped with the appropriate DCL means, so that only the privileged access via the associations from the sales order to the business partner delivers the data.
These explanations are to be understood as pointers; the topic of GDPR is highly complex.
Special Cases
Custom views on SAP standard views (in a clean core environment)
Not infrequently, we see Z views that wrap and expose SAP standard views β without a DCL. In 99% of cases, however, the DCL of the standard view should be inherited. In a clean core environment, it additionally holds that SAP reserves the right to change the DCL in the SAP view, e.g. by introducing an additional authorization field in the authorization object and in the CDS view.
This could lead to a syntax error in the Z view. To prevent this, SAP recommends delegating the authorization check to an associated view:
... inheriting conditions from entity <SAP View>
replacing { root with _DCLOrigin };
Here, _DCLOrigin is an association that in turn points to the SAP view. This means: at runtime, the WHERE clause is executed on the association target; the association thereby becomes an inner join, and the instances of the Z view are restricted accordingly.
Unmanaged query / custom entity
The check must be performed in the query implementation itself.
Additional logic in the projection or in BO interfaces
The authorization from the base BO is inherited automatically. For actions and functions newly defined in the projection, a separate authorization control can be defined.
Tips and Tricks
SACMSEL
Interesting for authorization problems in the CDS environment when the expected data is not visible.
Authorization context in the BDEF
While the authorization check in the DCL is defined declaratively so that the ABAP SQL runtime can perform the check on the database, in RAP and in ABAP the classic authority check remains the solution.
In the course of the ABAP Cloud C1 release of S/4HANA RAP BOs, the concept of the AUTHORIZATION CONTEXT was introduced. It can be used to define:
- Which authorization checks take place in the BO β once described, authorization checks that are not listed lead to a contract violation in RAP at runtime, i.e. to a dump.
- Which authorization checks in the BO are to be ignored β this is important on SAP's side when building RAP BO facades for legacy code, so that irrelevant checks can be suppressed without causing a disruption of the existing code.
- Which authorization checks are to be suppressed in EML
privileged mode. By default, this is the same list as in the first point β but GDPR considerations come into play here as well.
Central authorization class
Global authorization checks in the transactional context in particular can be implemented very elegantly via a central authorization object, a central authorization check, and a central class for executing this check. We like to use this approach as part of the holistic authorization concept in customer projects β analogous to S_START, a Z_EDIT with the name of the application as a parameter: Does the current user have the authorization to make changes in this app?
Infographic

References
- ABAP: AUTHORITY-CHECK
- ABAP Core Data Services (CDS)
- CDS: Access via privileged associations
- CDS / DCL: Inheriting SAP standard authorizations in a clean core environment
- ABAP SQL:
WITH PRIVILEGED ACCESS - RAP - ABAP RESTful Application Programming Model
- RAP Business Object (RAP BO)
- RAP BO: PRECHECK
- RAP BO: EML
PRIVILEGED - RAP BO: Authorization Context
- RAP BO: EML
IN LOCAL MODE - RAP BO: Global authorization
- RAP BO: Instance authorization
- SAP Gateway - Security Enhancements for OData V4, including S_START
- Service Adaptation Description Language (SADL)
- SADL - OData query runtime
- General Data Protection Regulation (GDPR)



