mxcli bug: GRANT ... ON ENTITY ... WHERE '...' overwrites instead of merging the attribute list
mxcli version
nightly-20260720-88077af1 (2026-07-20T06:06:00Z)
Mendix version
10.24.20.105674
Severity
High. This is a silent security regression: re-granting additional attributes to a role/entity/XPath combination that already has an access rule replaces that rule's attribute list instead of adding to it, with no error, warning, or diff shown. manage-security.md documents GRANT as "additive — it merges with existing access, never removes permissions," which is true when no WHERE clause is involved, but is false once a WHERE (XPath) clause matches an existing rule: read/write access to every attribute not mentioned in the new GRANT statement is silently revoked for that role on that XPath-scoped rule. A developer following the documented "additive" behavior to extend an existing rule with one or two new attributes will, without any indication, strip access to every other attribute already granted under that rule.
Steps to reproduce (project-independent)
Minimal domain model + existing XPath-scoped grant:
create persistent entity Sample.Order (
Number: string(50),
Status: string(50),
Total: decimal
);
/
create module role Sample.Viewer;
/
grant Sample.Viewer on Sample.Order (read (Number, Status, Total)) where '[Status != '''']';
Verify: describe entity Sample.Order shows the rule with all 3 attributes readable for Sample.Viewer under that XPath.
Now add one more attribute to the entity and grant read on it, using the same role and the same XPath text (the documented "additive" pattern):
alter entity Sample.Order add attribute Priority: integer;
/
grant Sample.Viewer on Sample.Order (read (Priority)) where '[Status != '''']';
mxcli exec reports success with no error or warning.
Then re-run describe entity Sample.Order.
Expected behaviour
Per the documented additive semantics, the rule should now read (Number, Status, Total, Priority) — the new attribute merged into the existing rule (same role + same XPath).
Actual behaviour (verbatim from my session, generalized names)
The rule's attribute list is replaced, not merged. In my session (real entity/attribute names, same mechanism):
- Before, an existing rule read:
grant Module.RoleA, Module.RoleB on Module.Entity (read (AttrX, AttrY, AttrZ, AttrRangorde, AttrDate, Assoc1, Assoc2)) where '[XPathCondition1][XPathCondition2]';
- I ran a
grant for the same Module.RoleA, Module.RoleB / Module.Entity / identical where string, adding 3 new attributes:
grant Module.RoleA, Module.RoleB on Module.Entity (read (NewAttr1, NewAttr2, NewAttr3)) where '[XPathCondition1][XPathCondition2]';
mxcli exec printed:
Granted access on Module.Entity to Module.RoleA, Module.RoleB
Result: read (NewAttr1, NewAttr2, NewAttr3)
(no error, no warning that anything else changed)
- A subsequent
describe entity Module.Entity showed the rule now reading only (NewAttr1, NewAttr2, NewAttr3) — AttrX, AttrY, AttrZ, AttrRangorde, AttrDate, Assoc1, Assoc2 were gone from that rule (i.e. read access to all 7 original attributes/associations was silently revoked for RoleA/RoleB under that XPath). This happened identically on two separate rules (two different role-pairs, two different attribute sets, same entity) in the same session — not a one-off fluke.
- This is distinct from
GRANT calls without a WHERE clause, which did behave additively in the same session (merging a new attribute into a role's unconstrained grant on a different entity worked as documented).
I only discovered the regression because I re-ran describe entity immediately afterward as a sanity check (per this workspace's coding.md rule to verify after every model change) — nothing in mxcli's own grant output flagged it.
Workaround
Applied in-session: before granting additional attributes on a rule that has a WHERE clause, first describe entity to capture the existing full attribute list for that exact role+entity+XPath combination, then issue one GRANT that includes the union of the old and new attributes (plus the identical WHERE text) — i.e. always treat GRANT ... WHERE as "set/replace this rule's attribute list," not "add to it," and manually pre-merge. After doing this, describe entity confirmed the rule correctly contained the full original + new attribute list.
Diagnostic bundle
Available: yes — mxcli-diag-20260819-220247.tar.gz (workspace root). Note: the bundle does not log a before/after diff of the affected rules' attribute lists (the grant log lines only show the Result: summary quoted above, which itself is what's misleading — it doesn't reflect the full post-grant attribute list either) — the verbatim before/after describe entity output above was captured directly from the terminal during the session and is not otherwise present in the bundle.
mxcli bug:
GRANT ... ON ENTITY ... WHERE '...'overwrites instead of merging the attribute listmxcli version
nightly-20260720-88077af1 (2026-07-20T06:06:00Z)Mendix version
10.24.20.105674Severity
High. This is a silent security regression: re-granting additional attributes to a role/entity/XPath combination that already has an access rule replaces that rule's attribute list instead of adding to it, with no error, warning, or diff shown.
manage-security.mddocumentsGRANTas "additive — it merges with existing access, never removes permissions," which is true when noWHEREclause is involved, but is false once aWHERE(XPath) clause matches an existing rule: read/write access to every attribute not mentioned in the newGRANTstatement is silently revoked for that role on that XPath-scoped rule. A developer following the documented "additive" behavior to extend an existing rule with one or two new attributes will, without any indication, strip access to every other attribute already granted under that rule.Steps to reproduce (project-independent)
Minimal domain model + existing XPath-scoped grant:
Verify:
describe entity Sample.Ordershows the rule with all 3 attributes readable forSample.Viewerunder that XPath.Now add one more attribute to the entity and grant read on it, using the same role and the same XPath text (the documented "additive" pattern):
mxcli execreports success with no error or warning.Then re-run
describe entity Sample.Order.Expected behaviour
Per the documented additive semantics, the rule should now read
(Number, Status, Total, Priority)— the new attribute merged into the existing rule (same role + same XPath).Actual behaviour (verbatim from my session, generalized names)
The rule's attribute list is replaced, not merged. In my session (real entity/attribute names, same mechanism):
grantfor the sameModule.RoleA, Module.RoleB/Module.Entity/ identicalwherestring, adding 3 new attributes:mxcli execprinted:describe entity Module.Entityshowed the rule now reading only(NewAttr1, NewAttr2, NewAttr3)—AttrX, AttrY, AttrZ, AttrRangorde, AttrDate, Assoc1, Assoc2were gone from that rule (i.e. read access to all 7 original attributes/associations was silently revoked forRoleA/RoleBunder that XPath). This happened identically on two separate rules (two different role-pairs, two different attribute sets, same entity) in the same session — not a one-off fluke.GRANTcalls without aWHEREclause, which did behave additively in the same session (merging a new attribute into a role's unconstrained grant on a different entity worked as documented).I only discovered the regression because I re-ran
describe entityimmediately afterward as a sanity check (per this workspace'scoding.mdrule to verify after every model change) — nothing inmxcli's own grant output flagged it.Workaround
Applied in-session: before granting additional attributes on a rule that has a
WHEREclause, firstdescribe entityto capture the existing full attribute list for that exact role+entity+XPath combination, then issue oneGRANTthat includes the union of the old and new attributes (plus the identicalWHEREtext) — i.e. always treatGRANT ... WHEREas "set/replace this rule's attribute list," not "add to it," and manually pre-merge. After doing this,describe entityconfirmed the rule correctly contained the full original + new attribute list.Diagnostic bundle
Available: yes —
mxcli-diag-20260819-220247.tar.gz(workspace root). Note: the bundle does not log a before/after diff of the affected rules' attribute lists (thegrantlog lines only show theResult:summary quoted above, which itself is what's misleading — it doesn't reflect the full post-grant attribute list either) — the verbatim before/afterdescribe entityoutput above was captured directly from the terminal during the session and is not otherwise present in the bundle.