π Access Matrix Guideο
β οΈ Warning: This documentation is a work in progress. Some sections may be incomplete, inaccurate, or subject to change.
This guide explains how to fill in the access matrices (authorization matrices) that Assets Guardian generates as empty Excel sheets. These matrices are the reference against which the audit command validates the accesses actually collected on your platforms: any access held by an employee that is not covered by the matrix raises a finding in the audit report.
π§ How matrices workο
π Lifecycleο
Generation: the first
syncrun creates one matrix sheet per audited plugin instance in the Excel workbook (paths.excelinconfig.yml, by defaultoutputs/assets_guardian.xlsx). The sheet is created empty: a header row with example scope columns, and one row per profile found inemployees.json.Manual completion: you replace the example columns with your real scopes and fill in the authorized role for each (profile, scope) pair. This is the manual step described in this guide.
Preservation: on every subsequent
sync, matrix sheets are preserved as-is (they are copied verbatim into the regenerated workbook, never overwritten).Consumption: the
auditcommand reads the matrices back from the same Excel file and evaluates theMATRIX-XXXrules against the collected accesses.
π‘ Tip:
paths.excelcan belocal:orremote:(SharePoint, via the Microsoft 365 plugin). In the remote case, the workbook is cached locally and re-downloaded whenever the SharePoint version changes, exactly likerules_config.ymlandemployees.json.
π·οΈ Sheet namingο
Each matrix sheet is named after its source plugin and instance:
Situation |
Sheet name |
|---|---|
Plugin instance with an |
|
Plugin instance without |
|
The audit command locates the sheet by this exact pattern (case-insensitive, instance-specific name first, then the generic name as fallback).
β οΈ Warning: Do not rename matrix sheets. A renamed sheet is silently ignored and the audit runs with an empty matrix.
π Sheet layoutο
The matrix is a pivot table: profiles as rows, scopes as columns, authorized roles in the cells.
Cell |
Content |
Rule |
|---|---|---|
|
Sheet title (e.g. |
Ignored by the audit, but must stay non-empty. |
|
Scope names (one column per audited resource) |
Must exactly match the expected scope keys listed per plugin below. |
|
Profile names (one row per profile) |
Must exactly match the values of the |
Other cells |
The role/permission the profile is authorized to hold on that scope |
An empty cell means βnot authorizedβ. Accepted values depend on the plugin (see below). |
Generated sheets are pre-filled with the example scope columns Group: Example1, Group: Example2, Instance and Project: Example: replace them with your real scopes.
β οΈ Warning: These example columns are identical for every plugin, they are not tailored to the source. A Dolibarr or Microsoft 365 sheet is therefore created with
InstanceandProject: Examplecolumns that its rules never audit. Always replace the whole header row with the scope columns documented for that plugin below.
π― Matching rulesο
All lookups are exact string matches (case-sensitive): profile names, scope headers and role values must be spelled exactly as documented.
Employees are identified by email: matrix rules resolve a userβs profiles from
employees.jsonthrough the email attached to the collected access. A user missing fromemployees.jsonhas no profile, so none of their audited accesses can be authorized.emailandusernameinemployees.jsonaccept a single value or a list. Every value listed becomes a lookup key for the same profiles, which is how one employee holding several accounts (e.g.john.doe@company.comandjdoe@company.com) is matched.usernameis only used as a fallback, when the entry has noemailat all.When an employee has several profiles, an access is authorized as soon as one of the profiles allows it (for hierarchical GitLab roles, the most permissive profile wins).
Rows with an empty first cell are skipped, so blank separator rows are harmless. Extra profile rows that match no employee are ignored.
β οΈ Warning: Do not leave an empty header cell between two scope columns: it shifts the column/value alignment when the matrix is read back.
βοΈ Enabling the matrix rulesο
Matrix rules only run if they are declared in rules_config.yml under the sourceβs section:
gitlab:
<<: *default_rules
MATRIX-001:
description: "Unauthorized GitLab instance administrator"
MATRIX-002:
description: "Unauthorized GitLab group/project access"
dolibarr:
<<: *default_rules
MATRIX-001:
description: "Unauthorized Dolibarr superadmin"
MATRIX-002:
description: "Unauthorized critical module access"
microsoft365:
<<: *default_rules
MATRIX-001:
description: "Unauthorized Microsoft365 group access"
β οΈ Warning:
name,description, andseveritymay all be overridden from the YAML. Ifseverityis missing or empty, the rule logs a warning and falls back to its default value (see the per-plugin tables below).
π§© Interpretation is plugin-specificο
Matrix semantics are not implemented by the audit engine but by the MATRIX-XXX rules that each plugin registers for its own source. The engine only extracts a neutral (profile, scope) β cell value mapping from the sheet and hands it to those rules; everything else, which scope columns are recognized, how cell values are interpreted (hierarchical roles on GitLab, presence-based checks on Dolibarr, accepted admin values), lives in the pluginβs own rule implementations. In practice:
A shared rule ID does not mean a shared behavior: GitLabβs
MATRIX-001and DolibarrβsMATRIX-001are independent implementations. This is why the sheet layout and accepted values are documented per plugin below, and why they can differ freely from one plugin to another.A plugin that ships no MATRIX rules cannot audit a matrix: declaring
MATRIX-XXXinrules_config.ymlfor such a source logs an error and the rule is skipped, the sheet, even carefully filled in, is never read.Supporting matrices in a new plugin therefore means implementing its own MATRIX rules; the conventions described in this guide do not transfer automatically to other sources.
π¦ GitLab matrixο
Sheet: Gitlab Matrix or Gitlab (<instance_id>) Matrix.
ποΈ Scope columnsο
Column header |
Audited by |
What it covers |
|---|---|---|
|
|
Instance-wide administrator flag. |
|
|
Membership role on the GitLab group |
|
|
Membership role on the GitLab project |
<group name> / <project name> is the display name of the group or project as shown in GitLab (the API name field, not the URL path). The prefix is capitalized and followed by a colon and a single space: Group: Backend, Project: Website.
π€ Accepted cell valuesο
Instance column: authorizes the instance administrator flag:
Value |
Meaning |
|---|---|
|
The profile may be a GitLab instance administrator. |
|
Same effect; the trailing |
(empty or any other value) |
Not authorized: every instance administrator with this profile is flagged. |
Group: β¦ / Project: β¦ columns: the maximum role the profile may hold, using GitLabβs role hierarchy:
Value |
GitLab access level |
|---|---|
|
10 |
|
20 |
|
30 |
|
40 |
|
50 |
The comparison is hierarchical: a cell containing Developer authorizes Guest, Reporter and Developer, but a user holding Maintainer or Owner on that scope is flagged. Spelling must be exact, any other value is treated as below Guest and flags every membership.
βοΈ Evaluation semanticsο
Only groups/projects that appear as a column in the matrix are audited: a group or project absent from the matrix is not checked at all.
The
Instancecheck applies to all collected instance administrators, whether or not theInstancecolumn exists (no column means nobody is authorized).For a user with several profiles, the highest authorized level across their profiles is used.
π Exampleο
Gitlab Matrix |
Instance |
Group: Backend |
Group: Infra |
Project: Website |
|---|---|---|---|---|
R&D |
Developer |
Maintainer |
||
R&D / DevOps |
Maintainer |
Owner |
||
Exploitation / Information technology (IT) |
Administrator |
Maintainer |
||
Support |
Reporter |
With this matrix, a Support employee owning the Website project raises a MATRIX-002 finding (Reporter max), and any instance administrator outside the IT profile raises a MATRIX-001 finding.
πΌ Dolibarr matrixο
Sheet: Dolibarr Matrix or Dolibarr (<instance_id>) Matrix.
ποΈ Scope columnsο
Column header |
Audited by |
What it covers |
|---|---|---|
|
|
The Dolibarr superadmin flag ( |
|
|
Rights on the Bank module. |
|
|
Rights on the Invoicing module. |
|
|
Rights on the Third parties module. |
|
|
Rights on the Users module. |
Module column headers use the technical Dolibarr module names in lowercase (banque, facture, societe, user). These four modules are the ones declared critical in the plugin (CRITICAL_MODULES); other Dolibarr modules are not audited by matrix rules.
π€ Accepted cell valuesο
Dolibarr column: authorizes the superadmin flag:
Value |
Meaning |
|---|---|
|
The profile may be a Dolibarr superadmin. |
|
Same effect, |
(empty or any other value) |
Not authorized: every superadmin with this profile is flagged. |
Critical module columns β presence-based check: any non-empty value authorizes the profile to hold rights on that module; the value itself is not interpreted. By convention, write the highest permission granted (e.g. lire, creer, modifier, supprimer) so the matrix stays readable for reviewers.
βοΈ Evaluation semanticsο
Critical modules are always audited: any user holding a right on
banque,facture,societeoruser(including sub-permissions such asbanque.modifieroruser.self.password) whose profiles have no entry for that module is flagged.One authorized profile is enough for the access to be considered legitimate.
π Exampleο
Dolibarr Matrix |
Dolibarr |
banque |
facture |
societe |
user |
|---|---|---|---|---|---|
Direction |
Administrateur |
modifier |
modifier |
creer |
lire |
Administratif / Finance |
modifier |
modifier |
lire |
||
Commerce & Marketing / Commerce |
creer |
creer |
|||
Exploitation / Information technology (IT) |
Administrateur* |
supprimer |
βοΈ Microsoft 365 matrixο
Sheet: Microsoft365 Matrix or Microsoft365 (<instance_id>) Matrix.
ποΈ Scope columnsο
Column header |
Audited by |
What it covers |
|---|---|---|
|
|
Membership in the Microsoft 365 / Azure AD group |
<group name> is the display name of the group as shown in Microsoft 365 / Azure AD. The prefix is capitalized and followed by a colon and a single space: Group: Finance.
π‘ Tip: Unlike GitLab and Dolibarr, the Microsoft 365 plugin currently ships a single matrix rule (
MATRIX-001): there is noMATRIX-002.
π€ Accepted cell valuesο
Group: β¦ columns β presence-based check: any non-empty value authorizes the profile to be a member of that group; the value itself is not interpreted. By convention, write a short note (e.g. oui, membre) so the matrix stays readable for reviewers.
βοΈ Evaluation semanticsο
Only groups that appear as a column in the matrix are audited: a group absent from the matrix is not checked at all (same behavior as GitLab groups/projects).
One authorized profile is enough for the access to be considered legitimate.
π Exampleο
Microsoft365 Matrix |
Group: Finance |
Group: IT-Admins |
|---|---|---|
Direction |
oui |
|
Administratif / Finance |
oui |
|
Exploitation / Information technology (IT) |
oui |
With this matrix, any member of the IT-Admins group whose profiles are not IT raises a MATRIX-001 finding.
β Filling checklistο
Run
synconce so the empty matrix sheets are generated with your profiles pre-filled fromemployees.json.Replace the example scope columns with your real scopes (exact names, see per-plugin tables above).
Fill in one cell per authorized (profile, scope) pair; leave every unauthorized combination empty.
Make sure the sourceβs matrix rules are declared in
rules_config.yml(MATRIX-001andMATRIX-002for GitLab and Dolibarr,MATRIX-001only for Microsoft 365).Run
auditand review theMATRIX-XXXfindings: each one is either an access to revoke or a missing authorization to add to the matrix.
π‘ Tip: An entirely empty matrix is a valid starting point: the first
auditwill then flag every superadmin/instance administrator and every right on Dolibarr critical modules, which gives you the complete list of accesses to arbitrate. (GitLab groups/projects and Microsoft 365 groups are the exception: they are only audited once their column exists in the matrix.)β οΈ Warning: The matrix is read from the workbook referenced by
paths.excelinconfig.yml. If you archive or move the Excel file, the nextauditruns against an empty matrix and the findings become meaningless.β οΈ Warning: The same silent failure happens if
paths.excelcontains theDATEplaceholder andauditruns on a different day than thesyncthat produced the workbook:auditlooks for todayβs filename, does not find it, and evaluates every matrix rule against an empty matrix. Run both commands on the same day, or dropDATEfrompaths.excel.