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]
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).