Appearance
Lesson 15 Companion — CDS DCL and RAP Authorization
This companion supports:
text
Lesson 15 — Authorization: CDS DCL and RAP AuthorizationUse it as:
text
instructor reference
syntax reference
troubleshooting guide
solution review1. Authorization layers
The lesson separates four concepts:
| Concept | Main question |
|---|---|
| DCL | Which rows may the user read? |
| Global authorization | May this user perform an operation generally? |
| Instance authorization | May this user perform it on this instance? |
| Feature control | Is it meaningful for the current business state? |
These mechanisms complement one another.
2. Guided ownership field
Add to:
text
ZRESV_###abap
responsible_user : abp_creation_user;It is intentionally nullable because existing rows may already exist.
3. Root CDS change
Add:
abap
Reservation.responsible_user as ResponsibleUser,and change:
abap
@AccessControl.authorizationCheck: #NOT_REQUIREDto:
abap
@AccessControl.authorizationCheck: #CHECK4. Access Control reference
abap
@EndUserText.label: 'Reservation Read Access'
@MappingRole: true
define role ZR_Reservation_###
{
grant select on ZR_Reservation_###
where ResponsibleUser = aspect user;
}5. DCL mental model
For normal access:
text
application WHERE
+
DCL WHERE
=
effective row restrictionA row that fails DCL is not returned through the protected CDS read.
The row is not physically deleted.
6. Why aspect user is useful here
It gives a real user-dependent rule without requiring custom PFCG role provisioning:
text
ResponsibleUser
=
current authenticated ABAP userThis is reproducible in BTP Trial.
7. aspect user and current syntax
Use:
text
aspect userinside DCL.
Do not use obsolete older forms such as:
text
ASPECT_USERThe predefined user aspect is the appropriate authorization-language construct for this condition.
8. PFCG authorization concept
Productive DCL can also use:
text
aspect pfcg_authto map CDS elements to authorization-object fields.
Example shape:
text
(Field) = aspect pfcg_auth(
AUTH_OBJECT,
AUTH_FIELD,
ACTVT = '03'
)The exact object and field names are application-specific.
9. Trial boundary
Certification knowledge — not reproducible in BTP Trial
This course does not provision custom productive PFCG authorization objects and business-role assignments.
Students should recognize:
text
AUTHORITY-CHECK
aspect pfcg_auth
activity values
PFCG/business rolesbut the guided runtime proof uses the current user and ResponsibleUser.
10. BDEF authorization header
Replace:
abap
authorization master ( none )with:
abap
authorization master ( global, instance )This tells RAP that the root is the authorization master.
11. Field changes in BDEF
Recommended additions:
abap
field ( readonly:update ) ResponsibleUser;If not already present:
abap
field ( readonly ) Status;Keep existing:
text
managed Uuid
admin fields
ReservationNo field control
Fee/Currency instance features12. Action authorization delegation
Reference:
abap
action ( features : instance, authorization: update )
confirm result [1] $self;
action ( features : instance, authorization: update )
cancel result [1] $self;Meaning:
text
feature availability
→ still calculated independently
authorization
→ delegated to update authorization13. Full BDEF excerpt
abap
managed implementation in class zbp_r_resv_### unique;
strict ( 2 );
define behavior for ZR_Reservation_### alias Reservation
persistent table zresv_###
lock master
authorization master ( global, instance )
etag master LocalLastChangedAt
{
create;
update;
delete;
field ( numbering : managed, readonly ) Uuid;
field ( readonly )
Status,
LocalCreatedBy,
LocalCreatedAt,
LocalLastChangedBy,
LocalLastChangedAt,
LastChangedAt;
field ( mandatory:create, readonly:update ) ReservationNo;
field ( readonly:update ) ResponsibleUser;
field ( features : instance ) Fee, CurrencyCode;
determination setInitialStatus on modify { create; }
validation validateCustomer on save
{ create; field CustomerName; }
validation validateDate on save
{ create; field ReservationDate; }
validation validateFee on save
{ create; field Fee, CurrencyCode; }
action ( features : instance, authorization: update )
confirm result [1] $self;
action ( features : instance, authorization: update )
cancel result [1] $self;
mapping for zresv_###
{
Uuid = uuid;
ReservationNo = reservation_no;
CustomerName = customer_name;
CustomerEmail = customer_email;
WorkshopCode = workshop_code;
ReservationDate = reservation_date;
Status = status;
ResponsibleUser = responsible_user;
Fee = fee;
CurrencyCode = currency_code;
Notes = notes;
LocalCreatedBy = local_created_by;
LocalCreatedAt = local_created_at;
LocalLastChangedBy = local_last_changed_by;
LocalLastChangedAt = local_last_changed_at;
LastChangedAt = last_changed_at;
}
}14. Generated authorization signatures
Use Quick Fix.
Expected declarations are equivalent to:
abap
METHODS get_global_authorizations
FOR GLOBAL AUTHORIZATION
IMPORTING
REQUEST requested_authorizations FOR Reservation
RESULT result.
METHODS get_instance_authorizations
FOR INSTANCE AUTHORIZATION
IMPORTING
keys
REQUEST requested_authorizations FOR Reservation
RESULT result.Prefer ADT-generated signatures.
15. Global authorization implementation
Training implementation:
abap
METHOD get_global_authorizations.
IF requested_authorizations-%create = if_abap_behv=>mk-on.
result-%create = if_abap_behv=>auth-allowed.
ENDIF.
IF requested_authorizations-%update = if_abap_behv=>mk-on.
result-%update = if_abap_behv=>auth-allowed.
ENDIF.
IF requested_authorizations-%delete = if_abap_behv=>mk-on.
result-%delete = if_abap_behv=>auth-allowed.
ENDIF.
ENDMETHOD.This is an implementation-contract exercise, not a production role model.
16. Productive global authorization pattern
SAP documentation commonly demonstrates logic equivalent to:
text
operation requested
→ run an authority check
→ return allowed or unauthorizedActivities can include:
text
01 create
02 change
06 deleteDo not invent a fake custom authorization object just to imitate production in Trial.
17. Instance authorization implementation
Reference:
abap
METHOD get_instance_authorizations.
READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
ENTITY Reservation
FIELDS ( ResponsibleUser )
WITH CORRESPONDING #( keys )
RESULT DATA(reservations)
FAILED failed.
DATA current_user TYPE abp_creation_user.
current_user = cl_abap_context_info=>get_user_technical_name( ).
LOOP AT reservations INTO DATA(reservation).
APPEND VALUE #(
%tky = reservation-%tky
) TO result ASSIGNING FIELD-SYMBOL(<authorization>).
IF requested_authorizations-%update = if_abap_behv=>mk-on.
<authorization>-%update =
COND #(
WHEN reservation-ResponsibleUser = current_user
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized
).
IF reservation-ResponsibleUser <> current_user.
APPEND VALUE #(
%tky = reservation-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'You are not responsible for this reservation'
)
) TO reported-reservation.
ENDIF.
ENDIF.
IF requested_authorizations-%delete = if_abap_behv=>mk-on.
<authorization>-%delete = if_abap_behv=>auth-allowed.
ENDIF.
ENDLOOP.
ENDMETHOD.18. Why reported matters
Authorization can be denied without an obvious explanation.
A reported message tells the consumer why.
The actual authorization decision remains:
text
auth-unauthorized19. Why delete is allowed in the lesson
The lesson creates an intentionally unauthorized/unassigned row.
To keep repeated classroom runs simple:
text
update/actions
→ owner-controlled
delete
→ allowedThis is a training policy, not a general production recommendation.
20. Current user API
Use:
abap
cl_abap_context_info=>get_user_technical_name( )SAP uses this API in ABAP Cloud examples for user-dependent logic.
21. Global permission request
abap
DATA request_global
TYPE STRUCTURE FOR PERMISSIONS REQUEST ZR_Reservation_###.
request_global-%create = if_abap_behv=>mk-on.
request_global-%update = if_abap_behv=>mk-on.
request_global-%delete = if_abap_behv=>mk-on.
GET PERMISSIONS ONLY GLOBAL AUTHORIZATION
ENTITY ZR_Reservation_###
REQUEST request_global
RESULT DATA(global_permissions)
FAILED DATA(failed_global)
REPORTED DATA(reported_global).No instance key is supplied for a global authorization query.
22. Instance permission request
abap
DATA request_instance
TYPE STRUCTURE FOR PERMISSIONS REQUEST ZR_Reservation_###.
request_instance-%update = if_abap_behv=>mk-on.
request_instance-%delete = if_abap_behv=>mk-on.
GET PERMISSIONS ONLY INSTANCE AUTHORIZATION
ENTITY ZR_Reservation_###
FROM VALUE #(
( Uuid = uuid )
)
REQUEST request_instance
RESULT DATA(instance_permissions)
FAILED DATA(failed_instance)
REPORTED DATA(reported_instance).Instance authorization requests need instance keys.
23. Permission result families
Authorization:
text
auth-allowed
auth-unauthorizedFeature control:
text
fc-o-enabled
fc-o-disabled
fc-f-unrestricted
fc-f-read_onlyNever interpret one family as the other.
24. Feature-vs-authorization test
For the unassigned row:
text
Status = N
ResponsibleUser = initialExpected:
text
feature:
confirm enabled
authorization:
update unauthorizedBecause:
text
confirm authorization delegates to updatethe action must still be denied.
25. DCL test design
Create:
text
98000001
ResponsibleUser = current user
98000002
ResponsibleUser = initialAfter commit:
text
root F8
→ only 98000001
table Alt+F8
→ both rowsThis is a direct, visible DCL proof.
26. Safe reset pattern
Because the protected root hides one training row, reset may use a read-only persistence lookup:
abap
SELECT FROM zresv_###
FIELDS uuid
WHERE reservation_no = '98000001'
OR reservation_no = '98000002'
INTO TABLE @DATA(old_keys).Then modify only through EML:
text
DELETE by those UUIDs
COMMIT ENTITIESNo direct SQL writes.
27. Why the read-only reset exception is acceptable
The normal application path remains:
text
Consumer → EML → RAP BOThe read-only persistence lookup exists only because:
text
the lesson deliberately hides one test row with DCLIt is a repeatability technique, not application architecture.
28. Existing rows after DCL
Older Lesson 12–14 rows may have:
text
ResponsibleUser initialThey will no longer appear through the protected root.
Use:
text
table previewwhen you need to prove they still exist.
29. Action delegation details
With:
text
authorization: updatethe action's authorization follows the update permission.
This avoids separate owner logic for:
text
confirm
cancel30. When delegation would be wrong
A future action might require a stronger privilege.
Example:
text
ordinary update
→ standard editor
approve high-value request
→ manager-onlyThen:
text
authorization: updatemay not be appropriate.
31. DCL and RAP authorization solve different problems
An instance may be:
text
readable but not writableor:
text
globally writable in principle
but unauthorized for this instanceA robust backend uses the correct layer for each concern.
32. Why authorization belongs before OData
Lesson 16 exposes the BO through OData.
Authorization should already exist before exposure.
Otherwise the architecture risks:
text
consumer-facing service
without backend authorization33. #CHECK vs #NOT_REQUIRED
Before Lesson 15:
text
#NOT_REQUIREDwas appropriate because no DCL protected the root.
After DCL:
text
#CHECKexpresses the intended protected model.
34. DCL troubleshooting
If expected rows are missing:
text
check current technical user
check ResponsibleUser
check #CHECK
check Access Control activation
check @MappingRole
check protected CDS entity name35. Authorization troubleshooting
If a write/action fails:
text
global authorization
instance authorization
ResponsibleUser
requested_authorizations
action delegation
feature result
FAILED
REPORTED36. Global allowed + instance unauthorized
This is valid:
text
global update = allowed
instance update = unauthorizedMeaning:
text
the user may update Reservations generally
but not this particular Reservation37. Feature enabled + authorization unauthorized
Also valid:
text
feature:
confirm enabled
authorization:
update unauthorizedThe operation is denied.
Business state and user permission are independent dimensions.
38. Provider-side local mode
Authorization handlers read BO data with:
text
IN LOCAL MODEbecause the provider needs its own state to calculate authorization.
External consumer classes must not use local mode.
39. DCL is read protection
DCL is primarily a CDS read-access mechanism.
RAP modifying operations require RAP authorization design.
Do not assume:
text
hidden row
=
all write operations automatically secure40. Certification relevance
Practical certification work can require:
text
creating an Access Control
repairing a DCL condition
changing #NOT_REQUIRED to #CHECK
changing authorization master settings
generating authorization handlers
using requested_authorizations
returning RAP auth constants
testing with GET PERMISSIONSThe skill is tracing the full authorization path.
41. Practice BO mapping
Practice uses:
text
ZR_ISSUE_###Add:
text
ResponsibleUserThen:
text
DCL
→ ResponsibleUser = aspect user
instance update auth
→ current user must equal ResponsibleUser
startProcessing
close
→ authorization delegates to update42. Lesson 16 boundary
Do not add:
text
projection CDS
projection BDEF
value help
metadata extension
Service Definition
Service Binding
OData V4Authorization should already work before those layers appear.