Application Security (Roles, ACLs, Scoped Application Security)
What to know
Access is layered. Roles (sys_user_role) grant permissions and are assigned directly to users or inherited through groups. Roles may contain other roles. Users, groups, and roles are combined in ACLs; group membership is the preferred way to grant a role at scale.
ACLs (sys_security_acl) are the enforcement point. Each ACL names a table or field, an operation (read, write, create, delete, or a UI/process operation), and a rule. The name follows table.field for fields, table.* for every field on a table, and *.field for a field on every table. An ACL can require one or more roles, a condition (declarative), or a script that returns true or false. When a condition is defined it is evaluated and the script is not used. Deny unless permitted.
Evaluation is most-specific-first: a field ACL overrides a table-level ACL; if the field ACL passes, the table read check is still applied for record access. Read ACLs also filter list queries, which is why a restricted user sees fewer rows rather than error messages. Admins bypass ACLs unless the High Security plugin is enabled, which forces admins through evaluation.
Scoped application security adds another layer: cross-scope access must be allowed, script includes are private by default, and tables carry an application access setting. Use the debug security tools to see which ACL allowed or denied an operation.
Traps
- Assuming admin always bypasses ACLs (not with High Security enabled).
- Granting a role to a user directly when a group would scale better.
- Thinking a condition and a script are both evaluated in one ACL.
- Assuming an ACL with no roles and no condition grants access; it does not.
- Overlooking that field-level write ACLs also require table-level write access.
Worked example
Restrict salary on the user record: create a read ACL on sys_user.salary requiring role payroll_reader. Only that role sees the value; other users see the field masked, and the record itself remains readable.
Rule of thumb: least privilege, granted through groups, enforced with ACLs named table.field.