Written by

Sales Engineer Manager at InterSystems
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$ROLESset 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]

Comments

Eduard Lebedyuk · Dec 8, 2022

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
0