Record vs table level acls when script attached
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-17-2025 06:42 AM
I have the following ACL script on the sectest table(inside 1st row acl in above image for the read operation):
var user = gs.getUser(); if (user.hasRole("sn_cmp.cloud_service_designer") || current.sys_created_by == gs.getUserName() || user.hasRole("sn_cmp.cloud_governor") || user.hasRole("sn_cmp.cloud_admin") || user.hasRole("sn_cmp.cloud_operator") || current.isNewRecord()) answer = true; else answer = new CMPCheckPermission().checkPermission(current.getTableName(), current.getValue("sys_id"), gs.getUserID(), "read");
Since this script uses current, I understand it functions as a record-level ACL. However, I would like to confirm whether this can also be considered applicable at the table level, or if the presence of current strictly makes it record-level only.
Now consider the following Java logic:
GlideRecord opSignatureGlide = new GlideRecord("sectest");
if (!opSignatureGlide.canRead())
{ AccessErrorHelper.throwAccessError(fLogger, AccessErrorHelper.OperationType.READ); } opSignatureGlide.addQuery("name", opSignatureName);
opSignatureGlide.query();
while (opSignatureGlide.next()) {
if (fLogger.isDebugEnabled()) fLogger.debug("Glide record for operation signature exists with name: " + opSignatureName); operationSignatureDTO = convertGlideRecordToOpSignatureDTO(opSignatureGlide); }
My concern is that since the only ACL on the table is the record-level ACL that uses current, calling canRead() before the loop may not behave as expected.
I understand that canRead() evaluated before next() only checks for table-level ACLs. And since there is no explicit table-level ACL defined (no ACL with name .*), this check might return false even though the user has record-level access due to the script.
Therefore, should I avoid using canRead() before the query loop in such a scenario?
Would it be correct to say that a record-level ACL using current does not replace a proper table-level ACL, and that if no table-level ACL exists, then canRead() should not be used before the loop?
Let me know if this understanding is correct.
And if record is defined in my acl then where to define table level acl? how to distinguish?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-17-2025 07:57 AM
I'm not entirely sure what you're trying to achieve here. Inside the Read ACL, you're using the canRead() method—which itself checks the Read ACL on the same table. Could you clarify the actual requirement you're aiming to fulfill.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-17-2025 08:13 AM
I have a read ACL with a script that uses the current
object to evaluate access, such as checking if current.sys_created_by == gs.getUserName()
. I want to perform a table-level access check and throw an error if the user doesn't meet the required role conditions.
The problem is that if the user doesn't have any of the roles defined in the ACL, and the condition current.sys_created_by ==
gs.getUserName()
evaluates to false, access will be denied. When I call .canRead()
before looping through the records, there's no current record context yet. So even if all the records in the table were created by the logged-in user, the script still fails because the current
object isn't properly populated during the table-level .canRead()
check.
As a result, the ACL script fails to grant access even when it would have succeeded at the record level. This happens because canRead()
is used before gr.next()
has loaded any record data so for table level check separate acls are there? or am thinking in wrong direction , if we just use sectest without * then it means whatever roles given in table should be applied for table level as well? not only record level
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a month ago
Hi @J Siva / @Ankur Bawiskar
When a table has both allow if and deny unless ACLs, does calling canRead() before performing glideRecord.query() ensure that both ACL types are enforced? Do you know of any reference where such a case is mentioned?
Also, if the allow if condition is defined at the field level and the deny unless condition is at the table level, will using GlideRecordSecure without explicitly calling canRead() still handle both cases? I know it will respect the field-level ACL, but will it also apply the deny unless table-level ACL?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a month ago
@EshikaAgrawal as far as I know if there is Deny unless ACL defined, then it'll take the precedence.
Also as per the ACL validation flow, one should pass the Table level ACL first.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a month ago
Yes, the precedence is fine, but my concern is about using canRead() in code or scripts to enforce ACLs. In cases like the one above, where both “allow if” and “deny unless” are table-level ACLs, I know that “allow if” is handled by the canRead() check, but would “deny unless” also be handled by canRead()?