User Groups and Roles
Introduction
Users do not have a directly assigned role. Instead, each user is linked to one or more groups, which define their rights and possible actions on the platform.
User groups allow for structuring permissions and assigning rights based on the environments in which a user can operate.
Structure of Roles and Groups
Fundamental Principle
- A user does not have a direct role.
- A user is always linked to one or more groups.
- A group defines access rights and possible actions on the platform.
Group Management
- A group can contain multiple users.
- A user can be assigned to multiple groups simultaneously.
- A group carries the permissions associated with a specific environment.
Environments and Permissions
Each user group is limited to a specific environment and has roles that allow for executing certain actions on the platform.
Types of Environments
User groups can be created to manage actions in three distinct environments:
| Environment | clientType | Description |
|---|---|---|
| FOC (Front Office Customer) | ACCOUNT | Manages user interactions and actions in the Front Office. |
| Back Office Operator | OPERATOR | Manages the platform as an operator (general administration). |
| Back Office Supplier | SUPPLIER | Manages actions specific to suppliers. |
Examples of Roles and Permissions
The full list of roles, grouped by typology and with a plain-language description for each, is visible in the Back Office on the Groups & Roles page, and returned by the API. It is the authoritative reference — the examples below only illustrate what each environment typically covers.
- FOC (Front Office Customer) — browsing the catalogue, placing and following orders, viewing prices and offers.
- Back Office Operator — administering the platform: products and catalogues, orders, prices and commercial offers, users and groups.
- Back Office Supplier — managing a supplier's own products and offers, stock levels, and the orders addressed to them.
A worked example — who can validate an order
Two roles govern order validation in the Front Office, and their combination is worth understanding:
Validate an order (ORDER_VALIDATE)— lets the user validate their own orders. Without it, they cannot complete checkout on an order they created.
Validate orders across all accounts (ORDER_VALIDATE_ON_ALL_ACCOUNT) — lets the user validate the orders of other users of the same account.
Granting only the second creates a validator who approves everyone else's orders but not their own — a common approval workflow.
📌 Note: A user can only perform an action if one of their groups has the necessary permission in the relevant environment.
Managing Groups and Roles
Group and role management is available to customers, either in self-service or operated by the Customer Success team.
Read and Write Tiers
Access to the Groups & Roles module is split into two distinct tiers:
- Read — the Access user group management (all clients) role (
ALL_USER_GROUPS_READ) allows viewing the groups, their roles, their members, and the change history. Viewing the members of a group does not require any write permission. This read permission also conditions the consultation of an operator user's profile, which is why it is listed in the Back-Office under the Accounts & users permission group rather than under the permission-management group. - Write — a dedicated permission-management role carries all write actions on groups: creating, renaming and deleting a group, managing its members, and changing its roles. This role is separate from operator user management: the
USER_MANAGEMENT_*roles only govern the management of operator users themselves.
The write role is granted automatically to the tenant's Operator_Admin administration group. The administrator can then delegate it to other groups or reorganise it freely. It is also covered by the Self-Lockout Protection: a user cannot remove their own permission-management write right if no other of their groups carries it.
Module Capabilities
The module provides the following capabilities:
-
Roles grouped by typology — roles are returned and displayed grouped by category rather than as a flat list, making large permission sets easier to navigate. Typologies follow a one-typology-per-business-entity convention ("Entity management"): Product management, Assortment management, Order management, Payment management, Data Hub management, Store and store view management, and so on. Each role appears under the entity it relates to, and this classification does not change the permissions themselves.
-
Functional description per role — each role carries a one-sentence description explaining, in plain language, what it concretely allows. The description is shown next to the role name.
-
Group renaming — a group can be renamed at any time (both in the Back Office UI and via the API).
-
Users tab on all group types — the list of users is available for Operator and Supplier groups, in addition to Account groups.
If a role you need does not exist, raise the request with DJUST.
Note: changes to a group's roles or members apply on the affected users' next login. Users already signed in keep their current permissions until then.
Note: The endpoints for managing groups and roles are published in the DJUST API reference. Refer to the API reference for the available routes and operationIds.
Listing Groups and Counting Their Members
GET /v2/user-groups (ADM-USER-GROUP-552) returns, in a single call, the identifier and name of every group of the tenant, organised in three buckets: operatorGroups, accountGroups and supplierGroups.
Warning: Breaking change. ThenumberOfUsersfield is no longer returned for each group byGET /v2/user-groups. Computing it for every group on every call was the main cost of the route and slowed down the Back-Office "Roles & groups" page. Integrations that read this field must stop relying on it.
To get the number of members of a group, list its users with GET /v2/user-groups/{groupId}/users (ADM-USER-GROUP-554) and read the totalElements field of the paginated response. A size=1 request is enough when only the count is needed.
GET /v2/user-groups/f7c6d4e3-2345-6789-01bc-def234567890/users?page=0&size=1
dj-client: OPERATOR
dj-api-key: {{apiKey}}{
"content": [
{ "id": "0008737355", "email": "[email protected]" }
],
"totalElements": 1204,
"totalPages": 1204,
"first": true,
"last": false,
"empty": false
}
Tip:totalElementsis exact and not capped: a group with more than 1,000 members returns its real count.
Group Membership Rule — At Least One Group
A user must belong to at least one group at all times. The "no group" state — which would leave a user with no access at all — is not valid. Multi-group membership is still allowed: a user can belong to one or many groups; only the empty state is forbidden.
This rule is enforced server-side, so a direct API call (curl, Postman, or a third-party integration) cannot bypass it. Adding and removing a user from a group remain two independent operations — there is no forced "move".
Operations Guarded by the Rule
| Operation | Endpoint | Rejected when |
|---|---|---|
| Create a user | POST /v1/customer-users (and the operator / supplier user creation endpoints) | groups[] is absent or empty |
| Remove a user from a group | DELETE /v2/user-groups/{groupId}/users/USERID (ADM-USER-GROUP-301) | it is the user's only group |
| Replace a customer user's groups | PATCH /v1/customer-users/USERID/groups | the payload contains an empty array |
| Update an operator user | PUT /v1/operator-users/{id} (ADM-OPERATOR-USER-203) | the groups[] field is empty |
| Update a supplier user | PUT /v1/supplier-users/{id} | the groups[] field is empty |
In all these cases the API returns a clear message: "User must have at least one group"
Tip: To move a user between groups without hitting this rule, add the new group first, then remove the old one. Users already belonging to multiple groups are unaffected — there is no migration.
Self-Lockout Protection
A user who manages groups and roles cannot validate a change that would remove their own critical Back Office access rights — the rights needed to view groups, to create and update users, and the dedicated permission-management write right on groups and roles. This prevents an administrator from accidentally locking themselves out of the user and permission management module.
The protection is enforced server-side and applies in two situations:
| Operation | Endpoint | Rejected when |
|---|---|---|
| Replace the roles of a group | PUT /v2/user-groups/{groupId}/roles (ADM-USER-GROUP-202) | the current user belongs to the group and the change removes a critical role that none of their other groups carries |
| Remove yourself from a group | DELETE /v2/user-groups/{groupId}/users/USERID (ADM-USER-GROUP-301) | the group carries a critical role that none of the user's other groups carries |
In both cases the API rejects the operation with an explicit error, and the Back Office displays a message inviting the user to have the change performed by another operator.
flowchart LR
%% Styles (Readme)
classDef create fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
classDef read fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
classDef update fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
classDef remove fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
classDef place fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
A[🧾 Permission change<br>submitted] --> B{Does it affect<br>the caller's own groups}
B -->|No| C[✅ Change applied]
B -->|Yes| D{Does it remove a<br>critical Back Office role}
D -->|No| C
D -->|Yes| E{Is that role carried<br>by another of their groups}
E -->|Yes| C
E -->|No| F[⛔ Change rejected<br>ask another operator]
class A sys
class B decision
class D decision
class E decision
class C place
class F stop
style A rx:8,ry:8
style C rx:8,ry:8
style F rx:8,ry:8
Note: This protection only applies to the current user's own rights. Managing the rights of other users is unchanged — it remains the operator's responsibility, with a warning displayed before validation in the Back Office.
Tip: Adding roles is never blocked.PATCH /v2/user-groups/{groupId}/roles(ADM-USER-GROUP-201) only adds roles to a group and can therefore never trigger this protection — only the full replacement (PUT) and the removal of a user from a group can.
Managing Groups and Roles from the Back Office
The module lives in the Back Office under Settings → Groups & Roles. It is reserved to operator users holding the Access user group management (all clients) role — without it, the page is not reachable.
Groups are separated by environment (Operator, Account, Supplier). Selecting a group opens its detail panel, organised in two tabs.
Permissions lists the roles carried by the group, grouped by typology and collapsed by default so that large permission sets stay readable. Each role shows a plain-language description of what it allows, and a filter helps locate a specific one. Changes are staged: a pending-changes indicator appears as you edit, and a confirmation summarising the modifications is shown before saving.
Users lists the members of the group, with the ability to add a user, remove one, or move one to another group. A counter next to the tab gives the number of members.
Group-level actions are available from the panel header: rename, and delete.
A History tab exposes the change log described above — who changed what, and when — with filters on group, author, date range and action type.
Users who hold only the read role see the same screens without any write action.
Change History (Audit Log)
An admin, paginated endpoint — ADM-GROUP-ROLES-HISTORY-550 — exposes the chronological history of permission changes on the groups & roles module — who changed what, and when. This audit trail supports investigation, security, and compliance use cases.
GET /v1/group-roles/history
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Note: This endpoint is tenant-level (thedj-store/dj-store-viewheaders are ignored). It requiresdj-client: OPERATORand theALL_USER_GROUPS_READrole. The history is append-only: events cannot be edited or deleted, and no such endpoints are exposed.
The same history is also available in the Back Office, in a dedicated History tab of the Groups & Roles page (visible to users with the ALL_USER_GROUPS_READ role). The view requires selecting a client type (Operator / Account / Supplier) and offers combinable filters on group, author, date range, and action type — matching the API filters described below.
Logged Event Types
eventType | Meaning |
|---|---|
ADD_ROLE / REMOVE_ROLE | A permission was granted to / revoked from a group |
ADD_USER / REMOVE_USER | A user was added to / removed from a group |
RENAME_GROUP | A group was renamed (old name → new name) |
CREATE_GROUP / DELETE_GROUP | A group was created / deleted |
Event Fields
| Field | Description |
|---|---|
id | Event identifier |
createdAt | Event timestamp (UTC) |
eventType | One of the types above |
clientType | Scope of the change: OPERATOR, ACCOUNT, or SUPPLIER |
user | The author of the action |
role | The affected role (for ADD_ROLE / REMOVE_ROLE) |
group | The affected group |
targetUser | The affected user (for ADD_USER / REMOVE_USER) |
previousValue | The former name (for RENAME_GROUP) |
Tip: Names, emails, and group names are frozen at the moment of the event. A user who is later deleted, or a group that is later renamed or removed, remains readable in the history with its original values.
Query Parameters
| Parameter | Required | Description |
|---|---|---|
clientType | Yes | OPERATOR, ACCOUNT, or SUPPLIER. Calling without it returns 400 Bad Request. |
groupId | No | Filter by group |
userId | No | Filter by affected user |
eventType | No | Filter by one or more event types |
from / to | No | Filter by date range |
page | No | Page number (0-based). Default: 0 |
size | No | Items per page. Default: 20, max 100 |
Filters combine with AND across different parameters and OR across the values of a single multi-valued parameter. Results are sorted by createdAt:desc by default.
Example — Recent Role Changes on a Group
GET /v1/group-roles/history?clientType=OPERATOR&groupId=grp-buyers&eventType=ADD_ROLE&eventType=REMOVE_ROLE&size=20
dj-client: OPERATOR
dj-api-key: {{apiKey}}{
"content": [
{
"id": "evt-10293",
"createdAt": "2026-06-28T14:12:07Z",
"eventType": "ADD_ROLE",
"clientType": "OPERATOR",
"user": { "id": "op-001", "email": "[email protected]", "fullName": "Admin Acme" },
"role": { "id": "ORDER_VALIDATE", "name": "Validate orders" },
"group": { "id": "grp-buyers", "name": "Buyers" }
},
{
"id": "evt-10288",
"createdAt": "2026-06-27T09:41:55Z",
"eventType": "RENAME_GROUP",
"clientType": "OPERATOR",
"user": { "id": "op-001", "email": "[email protected]", "fullName": "Admin Acme" },
"group": { "id": "grp-buyers", "name": "Buyers" },
"previousValue": "Purchasers"
}
],
"totalElements": 2,
"totalPages": 1,
"number": 0,
"size": 20
}Best Practices and Limitations
Best Practices
- Structure groups based on operational needs.
- Avoid assigning too many permissions to a single group for better access management.
- Always verify the permissions assigned to groups to prevent unwanted access.
- Use separate groups for each environment to comply with role management rules.
Known Limitations
- A group can belong to only one environment.
- A user must belong to at least one group at all times — enforced server-side (see Group Membership Rule).
- A user cannot remove their own critical Back Office access rights — enforced server-side (see Self-Lockout Protection).
- Group names must be unique across the whole tenant, regardless of environment. You cannot have an "Admin" group for Back Office Operator and another one for Back Office Supplier.
- Permissions are defined at the group level and cannot be assigned directly to users.
- Role creation is not available. Roles cannot be created from the Back Office, nor through the API. The list of available roles is defined by the platform: each role name is enforced directly in DJUST's code, so a role created outside that list would carry no permission and have no effect.
- Permission changes take effect on the user's next login, not immediately. A user whose rights change keeps the permissions of their current session until they log in again.
Updated 3 days ago

