How is everyone handling record security, when requirements require dynamic visi

How is everyone handling record security, when requirements require dynamic visibility? For instance, we require records for an application to be visible for all application administrators and also to the process initiator (initiator should only see the record for the process isntance they have initiated). Sometimes, company divisional views are necessary as well - divisional administrators should only see records for their specific division. With nearly 40 applications in production, we do not want to have 3+ records for each application. Just wondering if anyone has experience with similar situations. Thanks!

OriginalPostID-155229

OriginalPostID-155229

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer
    You can set security of process instance at runtime using "Modify Process Security Smart Service:"
  • 0
    Certified Lead Developer
    In general, the first thing I'd consider doing is setting the Record's security group to something permissive (such as "Record Viewers Group" containing a wide range of users), but then use an expression rule for "Default Filter" which takes the current user and the process initiator into consideration (among other things). So for example the expression rule for default filter could check:
    1) is loggedInUser = process initiator? if yes then good, if not, then:
    2) is loggedInUser = member of the admin group? if yes then good, if not then don't display the record on the list.

    The effect of this (plus or minus some tweaking) should be effectively that admins will see all records on the list, and users will see only those records that they initiated.
  • akshayan, thanks - that will work for most situations, except for group changes mid-process. We have models where hundreds of tasks will sit with a group for months - during which time the admin group is often changed, where the new admin will then not be able to see current records they should and the old will be left with views of records they should no longer have permissions - unless we create a mechanism to update close to 1,000 process instances during each group change. For example, one model has 1,246 running instances of which 743 are with 1 group for which the admin/visibility rights can change at any time. This could be part of the resolution however.
  • mschmitt, that was the direction I was heading initially. However we will be using entity backed records based on other requirements, but I'm assuming I can log intiiator account in the CDT/Entity and run touser() on that field for comparison. Groups should be less hassle to map as well - being new to Record Types/7.9 I'm just trying to figure how to map that to the filter Field vs Value - where Field is only available from the source entity - not an expression. Seems like I would need a field that holds a value of true() to compare to the loggedinuser() vs initiator vs admin group expression checks..

    Will play around with both of the suggestions, thanks!
  • 0
    Certified Lead Developer
    Good - though keep in mind that one of the main points I was making is that you'll have the ability to do your group comparison within the Default Filter expression (instead of worrying about the "Viewer Group" setting in the record setting itself); you should be able to utilize loggedinuser() and check if the user is a group of the permission group(s) you want. The advantage here is that it gives you intricate control as well as ease of editing in the future without having to worry about messing with the viewer group setting on the record page.
  • Exactly - the primary goal is to control permissions at the record level itself instead of within the process model design, if possible. On my previous comment, are there any work-arounds you know of for this method other than creating a CDT boolean field always defaulted to true() for use in the default filter 'Field' value? Then for the Value we would use an expression such as:

    =or(loggedinuser() = touser(CDT_XXX.ProcessInitiator),doesuserbelongtogroup(loggedinuser(),getgroupnamed("Admin Group Here")))
  • 0
    Certified Lead Developer
    Yeah, I seem to remember something to pass in there. It may even be as simple as setting the record field to the record's primary key ID, and in the expression, have it resolve to be equal if the user matches correctly, and have it return something else otherwise. I'd recommend playing around with it, i believe you'll find something that satisfies your requirements without too much trouble IIRC.
  • Thanks - I should have thought of that, much more elegant than an unnecessary boolean field in the CDT.
  • stefanh791 - we are aware of that approach, however in some of our processes that could lead to creation of tens of thousands of unique groups over the course of a year, which would create performance issues for users who are frequent participants from what I have read. Many of my processes currently use process instance security to give access to both admin groups and and initiator, but also to every person who has participated in the review/approval process. There doesn't seem to be any good way to replicate this behavior in record based design.