- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 08-08-2022 07:09 AM
Security setup: Default table/record ACLs analyzed
In an Out Of the Box (OOB) system, there are already some fallback security rules (ACL’s) setup on the table/record level. This makes sure that, even if there are no other ACLs in place, it falls back to evaluating these. Below image displays that evaluation, based on this Doc article https://docs.servicenow.com/bundle/sandiego-platform-security/page/administer/contextual-security/co...
There are 14 default access control rules *-ACL’s determining Create, Read, Update/Write, and Delete access (CRUD):
- 3 for create
- 4 for read
- 3 for write
- 4 for delete
You can check on your own instance by going to:
< your instance >.service-now.com/sys_security_acl_list.do?sysparm_query=name%3D*%5Etype%3Drecord
If you are in an OOB instance, with the default settings/properties, this translates in the following access:
- 3 for create
- Admin can create new records.
- 4 for read access for:
- Admin can read the record
- Approver of the record can read the record
- 3 for write
- Admin can update/write the record
- 4 for delete
- Admin can delete records
- workflow_admin can delete Workflow Activity Variables
Below are the more detailed descriptions. In green the ACL’s that can evaluate to true.
Create
Name |
Action |
Role |
Script |
Allows access to |
* |
Write |
Admin |
- |
Admin |
* |
Write |
snc_internal |
gs.getProperty('glide.sm.default_mode') == 'allow' |
users with the ‘snc_internal’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ à default this property is set to ‘ deny’ |
* |
Read |
public |
answer = false; if (gs.getProperty('glide.sm.default_mode') == 'allow') { if (current != null && GlidePublicPage.isPublic(current.getTableName())) answer = true; } |
users with the ‘public’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ AND the table is a public table |
Read
Name |
Action |
Role |
Script |
Allows access to |
* |
Read |
Admin |
- |
Admin |
* |
Read |
snc_internal |
gs.getProperty('glide.sm.default_mode') == 'allow' |
users with the ‘snc_internal’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ à default this property is set to ‘ deny’ |
* |
Read |
snc_internal |
answer = new ApproverUtils().canApproversRead(); |
users with the ‘snc_internal’-role, if it is an approval user with read access |
* |
Read |
public |
answer = false; if (gs.getProperty('glide.sm.default_mode') == 'allow') { if (current != null && GlidePublicPage.isPublic(current.getTableName())) answer = true; } |
users with the ‘public’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ AND the table is a public table |
Update/Write
Name |
Action |
Role |
Script |
Allows access to |
* |
Write |
Admin |
- |
Admin |
* |
Write |
snc_internal |
gs.getProperty('glide.sm.default_mode') == 'allow' |
users with the ‘snc_internal’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ à default this property is set to ‘ deny’ |
* |
Read |
public |
answer = false; if (gs.getProperty('glide.sm.default_mode') == 'allow') { if (current != null && GlidePublicPage.isPublic(current.getTableName())) answer = true; } |
users with the ‘public’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ AND the table is a public table |
Delete
Name |
Action |
Role |
Script |
Allows access to |
* |
Delete |
Admin |
- |
Admin |
* |
Delete |
snc_internal |
var ra = false; if (root_rule.substring(0,7)=='var__m_') { ra = gs.getUser().hasRole('workflow_creator') || gs.getUser().hasRole('delegated_developer'); } ra; |
workflow_admin required to delete Workflow Activity Variables |
* |
Delete |
snc_internal |
gs.getProperty('glide.sm.default_mode') == 'allow' |
users with the ‘snc_internal’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ à default this property is set to ‘ deny’ |
* |
Delete |
public |
answer = false; if (gs.getProperty('glide.sm.default_mode') == 'allow') { if (current != null && GlidePublicPage.isPublic(current.getTableName())) answer = true; } |
users with the ‘public’-role, if system property 'glide.sm.default_mode' is set to ‘allow’ AND the table is a public table |
The 2nd Delete ACL is highlighted orange, as it can be improved to evaluate more efficiently. It is always best (for performance) to first specify the Roles required.The principle is described here.
⚠️Note: It is not advised to adjust OOB functionality/scripts for this purpose only.
You can see here that the Role evaluation is done first (number 1 in the figure below), if that does not matches, evaluation ends and the user is Denied access:
The script only returns true for users with the “workflow_creator”-role or the “delegated_developer”-role. Performance wise moving those to the Role condition is better. This requires adjusting the script and looks like this:
* |
Delete |
workflow_creator or delegated_developer |
answer = (root_rule.substring(0,7)=='var__m_'); |
workflow_admin required to delete Workflow Activity Variables |
If the user does not have the “workflow_creator”-role or the “delegated_developer”-role the evaluation of the ACL would look like this without adjustments:
And like this with the adjustments:
So with the adjustment it does not need to evaluate the Condition, nor the Script, which saves performance. Especially if you have a production instance with 1000's of records.
Let me know if you have any questions regarding ACLs or any additions to the discussed topic.
- 1,841 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Willem,
thanks for bringing this up.
I understand everything you have explained and agree 100%.
Now everyone would need to consider if it is worth adapting the OOTB rule. It's more or less a "Upgradeability vs. Performance".
You already wrote:
"...So with the adjustment it does not need to evaluate the Condition, nor the Script, which saves performance. Especially if you have a production instance with 1000's of records..."
Were you able to measure this? I mean from the explanation and the design of ServiceNow it must be faster for sure, but I would be interested if we can confirm this with numbers (e.g. 3% faster in OOTB instance) or something like this.
Because this would underline if it might be interesting to amend this with the cons of having an issue / skipped upgrade on new releases.
Furthermore:
This sounds like an improvement that should be merged into the CORE of ServiceNow (by ServiceNow of course). So it might be a good idea to address that to the ServiceNow Developers somehow, as it would then benefit all customers at once. And they would also comply to their own Best Practices.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
The link seam not working