External-System CRUD Permission Control in GLPI with Access Matrix

CRUD permission matrix for external systems in GLPI with Access Matrix: 4-layer OR resolution model, an audit SQL diagnostic, CSV migration, and the field pitfalls (OR never revokes) - straight from NexTool's environment maintenance.

In an audit, nobody asks "who has access to the ERP." They ask "who can DELETE an entry in the ERP" - and the access spreadsheet rarely knows the answer. Access Matrix brings that decision matrix inside GLPI: external systems, their modules, and four CRUD flags (Create, Read, Update, Delete) resolved by role, group, and user. This guide covers the resolution model, a straight-to-the-database SQL diagnostic, the cross-environment migration format, and the pitfalls that only surface in production.

The real problem: the spreadsheet nobody trusts

While maintaining client environments, the request that exposes how fragile spreadsheet-based control is comes up again and again. An audit arrives (ISO 27001, SOX, or an access report for privacy compliance) and the ask is granular: "list every role that can create and delete records in the finance system." A "has access / no access" spreadsheet cannot answer that. It does not separate read from write, has no history of who changed what, and is already stale because the last offboarding was never reflected. Access Matrix targets exactly that gap: it models access at CRUD granularity and keeps everything inside GLPI, next to the rest of the service desk operation.

What the module models: systems, modules, and four flags

The structure is deliberately simple. You register the external systems (ERP, CRM, BI, third-party portals) and, within each one, the relevant modules (for example "Accounts Payable", "Billing", "Reports"). For each combination of role and module you tick four checkboxes: Create, Read, Update, Delete. A permission can be defined at the whole-system level or per specific module. In the database this becomes the columns can_create, can_read, can_update, can_delete (tinyint 0/1), with the module set to NULL when the rule applies to the entire system.

An honest and important clarification: Access Matrix is not a proxy that blocks login to the ERP. It does not intercept the external system. It is the authoritative decision matrix - the source of truth that documents, resolves, and displays who should hold each permission, so the team provisioning access (or the auditor reviewing it) works from trustworthy data inside GLPI rather than from a loose spreadsheet.

Four-layer resolution (OR: the most permissive wins)

A user's effective permission does not come from a single place. The module combines four sources with OR logic - for each CRUD flag, if any layer grants it, the user has it. In practice, each flag's result is a max() across the layers:

  1. The user's role - the field that defines the role is configurable (GLPI Category, Title, or default Group) via the role_source setting.
  2. Permission groups linked to the role - reusable CRUD sets assigned to the role.
  3. Permission groups linked directly to the user - one-off exceptions without touching the role.
  4. Individual permissions assigned directly to the account.
#LayerOrigin on the user recordPurpose
1RoleCategory / Title / default Group (config role_source)Baseline access by function
2Role permission groupRole → group linkReusable package across roles
3User permission groupUser → group linkException without changing the role
4Individual permissionDirectly on the accountOne-off fine-tuning

On the query tab, the module shows any user's effective permission with badges indicating which layer each access came from (Role, Group, or Individual) - which makes resolution auditable rather than a black box.

Straight-to-the-database diagnostic (SQL)

In an audit, the most frequent question is "who can write (create, update, or delete) in each system." You can answer it with a SELECT straight against the per-role permission table. The example below assumes the default source (usercategories_id, the user Category) and lists only those with a write flag:

-- Roles (user Category) with WRITE power over each external system
-- Default role source = usercategories_id
SELECT s.name                                AS system_name,
       COALESCE(m.name, '(whole system)')    AS module_name,
       c.name                                AS role,
       p.can_create, p.can_update, p.can_delete
FROM        glpi_plugin_nextool_accessmatrix_perm_categories p
JOIN        glpi_plugin_nextool_accessmatrix_systems s
              ON s.id = p.plugin_nextool_accessmatrix_systems_id
LEFT JOIN   glpi_plugin_nextool_accessmatrix_modules  m
              ON m.id = p.plugin_nextool_accessmatrix_modules_id
JOIN        glpi_usercategories c
              ON c.id = p.usercategories_id
WHERE       p.can_create = 1 OR p.can_update = 1 OR p.can_delete = 1
ORDER  BY   s.name, role;

This SELECT is read-only and covers the role layer (the baseline). The final effective permission - adding permission groups and individual tweaks via the 4-layer OR - is resolved by the module in PHP; use the query tab for the consolidated per-user value. The SQL is for quick audit sweeps and for checking the baseline before digging deeper.

Cross-environment migration: CSV Import/Export

Configuring the matrix in staging and promoting it to production without redoing everything by hand is done via CSV Import/Export. The export produces a single file with systems, modules, and permissions, in this format:

type,system_name,module_name,comment,is_active,role_source,role_id,can_create,can_read,can_update,can_delete
system,ERP Protheus,,Financial management,1,,0,0,0,0,0
module,ERP Protheus,Accounts Payable,,1,,0,0,0,0,0
permission,ERP Protheus,Accounts Payable,,0,usercategories_id,5,1,1,1,0
permission,ERP Protheus,,,0,groups_id,12,0,1,0,0

The type column distinguishes system, module, and permission rows; on permission rows, role_source says which layer that rule comes from. Before applying, the module shows a preview of the changes and writes an automatic backup (JSON snapshot) of the prior state, so you can roll back if something turns out different from expected.

Ticket integration

A dedicated tab appears on every ticket form, already pre-selecting the requester and displaying their effective permissions. In practice, when a ticket like "grant so-and-so access to module X of the ERP" comes in, the technician sees at once what that user already has in each system - without leaving the ticket, without opening another screen, without depending on that spreadsheet.

Field pitfalls (the common mistake is...)

Three details only surface once the matrix is in use, and they come from hands-on operation:

  • OR never revokes. The common mistake is trying to "remove" access by unticking the flags at the user's individual layer while a permission group still grants that CRUD. Because resolution is OR (the most permissive wins), the permission still stands. There is no "deny" that overrides a "grant" from another layer: to truly remove it, take it out of the layer that grants it.
  • A user with no role filled in does not inherit the role matrix. If you configured the source as Category but the user's account has the Category blank, layer 1 simply does not apply - only the user's groups and individual permissions count. The module warns about this on the query tab, but the day-to-day symptom is "I configured the role and the user still has no access." Check the role field on the user record before suspecting the module.
  • Switching the role source does not erase what you configured. If you migrate role_source from Category to Title, the permissions saved under Category do not vanish - they lie dormant in the database and stop being displayed while that mode is not theirs. Switching back to the old source brings everything back. It is safe to experiment, but know that "everything disappeared" after switching the source is almost always this, not data loss.

Modeling the matrix once is the easy part; keeping it consistent with offboardings, role changes, and recurring audits is maintenance work. That is what NexTool does: explore Access Matrix or talk to NexTool's GLPI maintenance to structure external-system access control with governance and an audit trail.


Este conteudo foi produzido com auxilio de inteligencia artificial e revisado pela equipe Nextool Solutions.

Frequently Asked Questions

Register the ERP as an external system and its modules, configure the CRUD matrix per role, and use the query tab to see each user's effective permission with a source badge. For quick sweeps, a SELECT on the glpi_plugin_nextool_accessmatrix_perm_* tables filtering can_delete = 1 lists the roles with delete power. The final resolution (with groups and individual tweaks) is consolidated on the module's query tab.

No. It is not a proxy and does not intercept the login to the ERP/CRM. It is the authoritative decision matrix inside GLPI: it documents, resolves, and displays who should hold each CRUD permission, to guide provisioning and audits. The technical block still happens in the external system itself; Access Matrix is the source of truth that says what to provision.

By OR logic: for each flag (Create, Read, Update, Delete), if any layer grants it, the user has it - the result is the max() across role, role groups, user groups, and individual permission. The practical consequence is that you cannot revoke access by unticking one layer while another still grants it.

Yes, via CSV Import/Export. The export produces a single file with systems, modules, and permissions (columns type, system_name, module_name, role_source, role_id, and the four CRUD flags). On import, the module shows a preview of the changes and writes an automatic backup (JSON snapshot) of the prior state before applying, allowing a rollback.

It is configurable via the role_source setting: it can be the user Category (usercategories_id, the default), the Title (usertitles_id), or the default Group (groups_id). Note: switching the source does not erase permissions already saved under the previous source; they lie dormant and reappear if you switch the mode back.

Need help?