Tip #1087: Hierarchical Security and Disabled Users

So you want to use hierarchical security to give your sales managers access to their team’s account records. One thing that you should be aware of is how hierarchical security works when users are disabled.

If a user becomes disabled, records that he or she owns are not available for hierarchical security. This is a performance related limitation but is not currently documented in the official documentation.

Recommendation

  1. If a user who owns account records leaves the company, your offboarding process should include reassigning his records to another user (or to the sales manager).
  2. If #1 is not practical, such as high turnover scenarios or where there is no current replacement for the territory, consider creating a team for each sales manager called something like “west territory-open.” Make the sales manager a member of the team, then assign the disabled user’s records to the open team. That way the manager can see and manage those accounts, but they will be open so that when a replacement is hired, they can be reassigned to the new user.
  3. If none of these options work, consider an alternative to hierarchical security. One common approach that we frequently did prior to the introduction of hierarchical security was to create an access team on Account that grants the desired managerial permission, then have a nightly batch job (using KingswaySoft, Scribe, or some other ETL tool)  that builds the access team membership with the sales manager for each account. This approach avoids the problem of sharing, as well as the limitations in hierarchical security.

One thought on “Tip #1087: Hierarchical Security and Disabled Users

  1. AdamV says:

    I would be wary about option 2 for various reasons:
    The team will need to have a security role with at least “user” level read privileges to all the entities that need to be transferred to it. Not a major thing, but yet another role to look after. If the sales manager needs to do more than just read, this role needs those privileges too.

    You just moved records up the hierarchy, so in a larger organisation this could change which records someone way up the chain has read access to. Again, not major, but to be considered.
    If you have two people who left and are not yet replaced, you really need two teams so that their records don’t get irreversibly merged. Or 3, or 4…

    Teams can’t be members of teams. If the original user was a member of one or more teams, it is quite possible that other team members relied on this for their vsibility of records. For example, an inside sales person in the West Territory might have read access to all records in that area (BU) or maybe across the whole company. But on a day-to-day basis they use a view to show them just the records of the sales people they are buddied up with, using a query such as “All Accounts owned by any user who is in a team that has me as a member (excluding default teams)”. This breaks once you move the records to a team instead of a user.

    Various advanced find features include queries such as “Owned by users in my hierarchy” which will not work when the ownership changes to a team rather than a user.

    If you have any sort of code which auto-assigns records to the right user, such as incoming leads being assigned by territory, you will need to revisit all of this to build in exceptions that assign to teams instead of users. Sounds like a lot of work for an edge case.

    Option 3 is reasonable, with some coding, but is does not “avoid the problem of sharing” as such – Access Teams are just teams with a particular flag set. The records are shared with those teams, those shares cascade down the entity relationships just as always, the POA table grows bigger. By using teams rather than sharing with individual users it reduces the impact, just as it would if you share with an owner team. Access Teams can’t have roles, so they are ignored when enumerating what roles a user has and evaluating their privileges from that, so a user can be a member of a huge number of Access Teams with far less impact than using owner teams (even if those teams have no roles, they still get evaluated). Also, changing Access Team memberships does not flush the user’s security cache so there is less performance hit every time you update this. The POA table is used in the same way, queries to return records (especially retrieve multiple) treat shares with owner and access teams equally. It is not true to say the problem of sharing is avoided, it is just kept to a minimum. The whole point of hierarchical security was to provide a better managed, high performance way to meet this sort of requirement.

    What alternatives are there? Do we need to disable the user record (if you are not using hierarchical security, this is still probably the best means of being sure to lock someone out)? Can we just remove the licence? Can we just remove all security roles? What if they are members of a team that has roles? We might have to leave them in the teams, but would that give them enough rights to sign in? Each scenario will be different and needs to be tested thoroughly, but it might be possible to look at offboarding / onboarding like this:
    User is leaving: prevent them signing in without disabling their user record.
    Replacement user arrives: re-assign all the records from the old user, and *now* disable their user account.

    Now for the tricky question: while there is a gap between old and new user, how do you assign new records? If you disable the old user or remove all their roles, you can’t assign records to them. But let’s say you have a new lead (or anything else) that would have gone to this person, and will need to be looked after by their replacement, how do you assign it in the interim period? Esepcially if that is currently handled by code. So you might need to have a role for users who have left which allows user level read access to some entities, but does not have all the usual baseline privileges which would allow the user to sign in. And test, test, test again…

Leave a Reply

Your email address will not be published. Required fields are marked *