Article
Tani Frankel · Dec 8, 2022 1m read

Privileged Routine Applications (PRA) and $ROLES After

When creating a PRA (Privileged Routine Application; which by the way is not relevant just for Routines but also for Classes/Methods), it is important to make sure you include a new $ROLES, before calling AddRoles(). For example:

 new $ROLES
 set status=$System.Security.AddRoles("MyPrivilegedRoutineApplication")

This way you ensure that indeed the added (elevated) roles "evaporate" for the User running this code, once the User is out of the scope of that routine/method.

[Thank you @Andreas Dieckow for validating this]

8
0 128
Discussion (3)2
Log in or sign up to continue

Great find, Tani!

You can also use the same trick to remove roles temporarily (for example if you need to execute untrusted code):

Class User.Role
{

/// do ##class(User.Role).Test()
ClassMethod Test()
{
    do ..SecurityContext("Test before")
    do
    . new $roles
    . do ##class(%SYSTEM.Security).Login("UnknownUser") // has no roles
    . do ..Untrusted()

    do ..SecurityContext("Test after")
}

ClassMethod Untrusted()
{
    do ..SecurityContext("Untrusted")
}

ClassMethod SecurityContext(context)
{
    w "Context: ", context, !
    w "Roles: ", $roles, !
    w "User: ", $username, !, !
}

}

Produces this output:

Context: Test before
Roles: %All
User: _SYSTEM
 
Context: Untrusted
Roles:
User: UnknownUser
 
Context: Test after
Roles: %All
User: _SYSTEM

@Tani Frankel  - thank you very much for taking the time to share this helpful tidbit!