GenevaGem - ACL Execution Plan

Believe it or not, after working with ServiceNow security for nearly 10 years (and being the security product manager for a while), I almost have it figured out. It didn't really take that long but understanding the laws of security rules doesn't come quickly. Finally, with the Geneva release, things are starting to get slightly easier to follow. 

In my mind, this could be the hope diamond of the GenevaGems for any admin or developer.

To start, it's important to explain the complexities that have existed since contextual (record-based) security was introduced way back in 2008'ish. For you history buffs, before this we only had control at the table level. Interesting enough, there's actually no concept of table level controls today. For table records, access control rules only define security for row and/or column access. There's plenty of confusion and side-effects of not having table controls, but I'll save that for another day (buy me a beer at Knowledge16 and I'll be happy to rant about it).

Ok, back to the confusing part. As defined in the contextual security wiki, controls are evaluated in a particular order based on most-specific to least-specific, using a combination of row and column checks. The wiki attempts to explains this in text and flow chart.

I won't get into the specifics here since the processing flow chart explains it quite well. The main point is, when working with inherited tables this model gets confusing and there's no easy way to visualize possible conflicts.

This happens frequently with the large hierarchical structure of task and CMDB tables, but let's take a simple example to show how easy it is to get into trouble.

By default, the work_notes field on the task table control grants write access to the itil and task_editor roles.


Try to follow along in the process flow image. If a task extension table, such as incident, does not have a table specific ACL for the work_notes field, it will inherit the task.work_notes rule. This may be fine in many cases, but what happens if we want to allow another role, say incident_worknote_writers (custom role), to write to the incident work_note field and not all other tasks.

Easy enough, right? We need to add a new access control rule for write operations on 'incident.work_notes' and grant access to our new role. 

Now, users with the incident_worknote_writers role can write to the incident work_notes field. Just so this doesn't turn into a security book, I'm assuming that this role already has access to write to at least some incident rows.

The problem with this may not be that obvious at first, and may not be caught until the change migrates to user testing or production use. Since the incident.work_notes field didn't have a specific rule before, it inherited the two roles from task.work_notes rule. Now that we created an incident specific rule, it will no longer inherit the task rule, which means we just prevented the itil and task_editor role users from writing to incident work notes. In the past you would usually come across this when a user complains, and you track it down using some of the security debugging tools. The good news is that you'll quickly learn all the hard lessons you should know about access rule processing.

Enter the Geneva ACL execution plan and watcher features. For those just starting their ServiceNow career on the Geneva release, you will never truly appreciate the pain your peers have experiences.

Instead of waiting for a production user to let you know that you broke security, the watcher will let you know as soon as you try to create the conflicting incident.work_notes control record.

Watcher let's us know that this new rule will end up masking (voiding) the task.work_notes control for the incident table.

The watcher is great for alerting you as you make changes. In the event that you're trying to make sense of existing rules in your environment, the ACL execution plan viewer is the tool you need.

From any access control form, you have access to the Show ACL Execution Plan UI action form link. Now that we have created the new rule on incident.work_notes column, here's what the execution plan looks like.

We can see that the task.work_notes control is no longer inherited. We can also assume that if this rule was deleted, the task rule would take over control.

This may seem like a simple example that you'd be able to track down quickly but remember the issue escalates quickly as the number of rules on child tables grows.

As for a fix for the  design issue we created, we would have to grant write access for the itil and task_editor roles back through our new rule or another explicit rule on the incident.work_notes column.

If you're looking for an additional way to view effective security summaries at an application level, check out the Access Risk Dashboard app in the ServiceNow store.