| name | manage-security |
| description | Configure Mendix security via MDL: module roles, user roles, entity/microflow/page access, project security settings, and demo users |
| compatibility | opencode |
Security configuration expert for Mendix apps using MDL. Covers module roles, user roles, access rules, project security settings, and demo users.
Covers Mendix security configuration via MDL: module roles, user roles, access control (microflows, pages, entities), project security settings, and demo users.
- Set up security for a module or project
- Create or manage module roles / user roles
- Grant or revoke access to microflows, pages, or entities
- Configure project security level or demo users
- Review existing security configuration
<security_concepts>
- Module Roles define permissions within a single module (e.g.,
Shop.Admin, Shop.Viewer)
- User Roles aggregate module roles from multiple modules (e.g.,
Administrator includes Shop.Admin + System.Administrator)
- Access Rules control CRUD rights on entities per module role
- Microflow/Page Access controls which module roles can execute/view specific elements
- Project Security Level determines enforcement:
off, prototype, or production
</security_concepts>
<syntax_reference>
Show Commands (Read-Only)
show project security;
show module roles;
show module roles in MyModule;
show user roles;
show demo users;
show access on microflow MyModule.ProcessOrder;
show access on page MyModule.CustomerOverview;
show access on MyModule.Customer;
show security matrix;
show security matrix in MyModule;
Describe Commands
describe module role MyModule.Admin;
describe user role Administrator;
describe demo user 'demo_admin';
Catalog Queries (SQL)
Security data is available in catalog tables for advanced querying. Use refresh catalog full to populate permissions and role mappings.
select * from CATALOG.PERMISSIONS where ModuleRoleName = 'MyModule.Admin';
select ElementName, AccessType from CATALOG.PERMISSIONS
where ElementType = 'ENTITY' and ModuleName = 'MyModule';
select ElementName from CATALOG.PERMISSIONS
where ElementType = 'MICROFLOW' and AccessType = 'EXECUTE';
select * from CATALOG.ROLE_MAPPINGS;
select ModuleRoleName from CATALOG.ROLE_MAPPINGS where UserRoleName = 'Administrator';
select distinct UserRoleName from CATALOG.ROLE_MAPPINGS where ModuleName = 'MyModule';
describe CATALOG.PERMISSIONS;
describe CATALOG.ROLE_MAPPINGS;
Catalog tables:
| Table | Contents | Build mode |
|---|
CATALOG.PERMISSIONS | Entity CRUD, microflow EXECUTE, page VIEW, OData ACCESS | refresh catalog full |
CATALOG.ROLE_MAPPINGS | User role → module role assignments | refresh catalog |
Module Roles
create module role MyModule.Admin description 'Full administrative access';
create module role MyModule.User;
create module role MyModule.Viewer description 'Read-only access';
drop module role MyModule.Viewer;
Microflow Access
grant execute on microflow MyModule.ACT_Customer_Create to MyModule.User, MyModule.Admin;
revoke execute on microflow MyModule.ACT_Customer_Create from MyModule.User;
Nanoflow Access
grant execute on nanoflow MyModule.NF_ValidateCart to MyModule.User, MyModule.Admin;
revoke execute on nanoflow MyModule.NF_ValidateCart from MyModule.User;
show access on nanoflow MyModule.NF_ValidateCart;
Note: Security roles persist through DROP+CREATE of the same nanoflow name within a session (by design, for refactor-in-place workflows).
Page Access
grant view on page MyModule.Customer_Overview to MyModule.User, MyModule.Admin;
revoke view on page MyModule.Customer_Overview from MyModule.User;
Entity Access (CRUD)
GRANT is additive — it merges with existing access, never removes permissions.
grant MyModule.Admin on MyModule.Customer (create, delete, read *, write *);
grant MyModule.Viewer on MyModule.Customer (read *);
grant MyModule.User on MyModule.Customer (read (Name, Email), write (Email));
grant MyModule.User on MyModule.Customer (read (Phone));
grant MyModule.User on MyModule.Order (read *, write *) where '[Status = ''Open'']';
revoke MyModule.Viewer on MyModule.Customer;
revoke MyModule.User on MyModule.Customer (read (Phone));
revoke MyModule.User on MyModule.Customer (write (Email));
revoke MyModule.User on MyModule.Customer (delete);
User Roles
create user role RegularUser (MyModule.User, OtherModule.Reader);
create user role SuperAdmin (MyModule.Admin) manage all roles;
alter user role RegularUser add module roles (MyModule.Viewer);
alter user role RegularUser remove module roles (MyModule.Viewer);
drop user role RegularUser;
Project Security Settings
alter project security level off;
alter project security level prototype;
alter project security level production;
alter project security demo users on;
alter project security demo users off;
Demo Users
create demo user 'demo_admin' password 'Admin123!' (Administrator, SuperAdmin);
create demo user 'demo_admin' password 'Admin123!' entity Administration.Account (Administrator, SuperAdmin);
drop demo user 'demo_admin';
The ENTITY clause specifies which entity (generalizing System.User) to use. If omitted, it auto-detects the unique System.User subtype in the project. If multiple subtypes exist, you must specify ENTITY explicitly.
</syntax_reference>
<starlark_lint_rule_apis>
Security data is available in Starlark lint rules (.star files):
| Function | Returns | Description |
|---|
permissions() | list of permission | All permissions across all element types |
permissions_for(qn) | list of permission | Permissions for a specific entity |
user_roles() | list of user_role | User roles with module role assignments |
module_roles() | list of module_role | Distinct module roles |
role_mappings() | list of role_mapping | User role → module role mappings |
project_security() | struct or None | Security level, guest access, password policy |
See write-lint-rules.md for object property details.
</starlark_lint_rule_apis>
<common_workflow>
A typical security setup follows this order:
create module role Shop.User description 'Regular user access';
create module role Shop.Admin description 'Administrative access';
create module role Shop.Viewer description 'Read-only access';
grant Shop.Admin on Shop.Customer (create, delete, read *, write *);
grant Shop.User on Shop.Customer (read (Name, Email), write (Email));
grant Shop.Viewer on Shop.Customer (read *);
grant execute on microflow Shop.ACT_Customer_Create to Shop.User, Shop.Admin;
grant execute on microflow Shop.ACT_Customer_Delete to Shop.Admin;
grant view on page Shop.Customer_Overview to Shop.User, Shop.Admin, Shop.Viewer;
grant view on page Shop.Customer_Edit to Shop.User, Shop.Admin;
create user role AppUser (Shop.User);
create user role AppAdmin (Shop.Admin) manage all roles;
show security matrix in Shop;
describe user role AppAdmin;
</common_workflow>
<common_mistakes>
- Creating module roles before the module exists —
create module must come first
- Referencing non-existent roles in GRANT — create the module role before granting access
- Forgetting qualified names — roles use
Module.Role format in GRANT/REVOKE
- User roles without System module roles — in Production security, user roles need at least one System module role (CE0156)
- Entity access without proper member rights — use
read * for all members or read (Attr1, Attr2) for specific ones
</common_mistakes>
After setting up security, verify with:
```bash
# check security matrix
./mxcli -p app.mpr -c "show security matrix in MyModule"
Validate with Mendix
~/.mxcli/mxbuild/*/modeler/mx check app.mpr
</validation>
<output_rules>Output MDL code only in code blocks. Keep explanations concise.</output_rules>