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
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!
The Docs also include this recommendation (thanks to @Shawn Fennell for the pointer).