Skip to main content
Version: 2.4

Roles and Privileges

This document describes how authorization is managed in the tSM (Telco Service Management) application — specifically how roles, composite roles, and privileges work together to define what each user can do within the system.

The goal of this model is to provide a predictable, auditable, and flexible access control mechanism that scales from simple standalone setups to complex enterprise environments integrated with IAM systems.


Overview​

In tSM, user permissions are determined by combining:

  • Privileges – the smallest atomic access rights (e.g., Um.User.Edit)
  • Roles – groups of privileges that define allowed or denied operations
  • Composite Roles – roles that include other roles
  • Global Role Priority – defines which role dominates in case of conflict (via globalPriority field)
  • canRestrictParent – defines whether a sub-role can remove privileges from its parent

1. Privileges​

A Privilege represents the most granular unit of access control — a single action or right granted within the system.

Examples:

Privilege CodeDescription
Um.User.ViewView user records
Um.User.EditEdit user details
Inv.Service.DeleteDelete or deactivate a service
Inv.Service.ApproveApprove a service change
Cm.Config.ViewView configuration data

Privileges are usually grouped by functional module and entity:

  • Um.User.* – User Management
  • Inv.Service.* – Inventory and Service Management
  • Cm.Config.* – Configuration Management

2. Roles​

A Role represents a named collection of privileges.
Each role defines what a user can do, and may either grant or remove certain privileges using prefix notation.

2.1 Privilege Prefixes​

  • +Privilege → grants permission
  • –Privilege → revokes permission

Example role definition:


+Um.User.View
+Um.User.Edit
-Um.User.Delete

This role allows the user to view and edit users, but not delete them.

Prefix definitions may also apply to entire namespaces:

  • +Um.User grants all user-related privileges.
  • -Um.User.Comments removes all privileges related to comments.

3. Global Role Priority​

When a user is assigned multiple roles, tSM resolves privilege conflicts using role priority (stored in the globalPriority field).

Each role has a numeric globalPriority (default = 0).
If multiple roles define conflicting privileges for the same action:

  • The role with the higher priority wins.
  • If two roles have the same priority, the more specific privilege wins (longest matching code, dot-segment aware); only when two rules are equally specific does the negative (–) win.

Privilege matching is case-insensitive (Dms.User.View == DMS.User.View) and respects dot-segment boundaries — Um.Role matches Um.Role.View but not Um.RoleManager.

Example 1 — Priority Conflict Resolution​

RolePrivilegePrefixGlobal Priority
Admin+Inv.Service.Edit+100
Reader-Inv.Service.Edit-10

Result: the privilege Inv.Service.Edit remains allowed, since the Admin role has higher global priority (100 > 10).

Example 2 — Priority with Prefix Wildcards​

RolePrivilege PatternPrefixGlobal Priority
Admin+Inv.Service+100
LimitedUser-Inv.Service.Delete-50

Result:

  • Inv.Service.View → ✅ allowed (from Admin, no conflict)
  • Inv.Service.Edit → ✅ allowed (from Admin, no conflict)
  • Inv.Service.Delete → ✅ allowed (Admin priority 100 overrides LimitedUser priority 50)

4. Composite Roles​

A Composite Role is a role that includes one or more other roles.
This allows for modular and hierarchical role definitions — for example:


Admin
├── Operator
└── Reader

Composite roles simplify maintenance by enabling reuse of base roles and consistent propagation of privilege changes.

4.1 Restriction Behavior (canRestrictParent)​

Each composite relationship defines whether the included (child) role can restrict privileges of the parent role via the canRestrictParent field.

ParameterTypeDescription
canRestrictParentBooleanIf true, the included role's negative privileges (–) can override parent privileges. Default: false.
  • If canRestrictParent = false, the child role can only add privileges (its – entries are ignored).
  • If canRestrictParent = true, the child role can add and remove privileges.

4.2 Example 1 — Non-restricting Role​


Admin
├── Reader (canRestrictParent = false)

RolePrivilegePrefix
Admin+Inv.Service+
Reader-Inv.Service.Edit-

Result:
Inv.Service.Edit remains granted, since Reader cannot restrict Admin privileges (canRestrictParent = false).


4.3 Example 2 — Restricting Role​


Auditor
├── Compliance (canRestrictParent = true)

RolePrivilegePrefix
Auditor+Inv.Service.View+
Compliance-Inv.Service.Delete-

Result:
Inv.Service.Delete is revoked, since Compliance can restrict its parent (canRestrictParent = true).


5. Merge Algorithm​

tSM calculates a user's effective privileges through a deterministic two-phase merge process:

Phase 1: Compose Each Role (within role hierarchy)​

For each assigned role:

  1. Collect privileges from the role itself.
  2. Recursively include all child roles from composite relationships.
  3. Apply canRestrictParent logic:
    • If canRestrictParent = false: ignore negative (–) privileges from the child role
    • If canRestrictParent = true: apply both positive and negative privileges from the child role
    • Deep nesting: a descendant's negative privilege reaches an ancestor only if every edge on the path has canRestrictParent = true (AND along the path).
  4. Result: a flattened privilege set for this role with all composite relationships resolved.

Phase 2: Merge Across Roles (using global priority)​

  1. Collect all composed roles assigned to the user.
  2. Sort by globalPriority (highest first).
  3. Apply privileges in priority order:
    • Start with the highest priority role's privileges
    • For each subsequent role, only apply privileges that haven't been decided yet
    • If a privilege conflict occurs, the higher priority wins
  4. Tie-breaking: at equal globalPriority the more specific rule wins (longest matching code); only at equal specificity does negative (–) override positive (+). Matching is case-insensitive.
  5. Generate audit trace indicating the origin of each privilege.

Example​

(The privilege codes in this worked example are illustrative.)

Given user assigned roles:

  • Admin (simple role, priority 100)
  • ServiceManager (composite role, priority 50)

Role definitions:

Admin (globalPriority = 100):
+Inv.Service # Grants all service privileges

ServiceManager (globalPriority = 50):
+Inv.Service.View
+Inv.Service.Edit
Includes: RestrictivePolicy (canRestrictParent = true)

RestrictivePolicy (child of ServiceManager):
-Inv.Service.Delete # Removes delete permission
-Inv.Service.Approve # Removes approve permission

Step 1: Compose Each Role (within role hierarchy)

RoleDirect PrivilegesIncludescanRestrictParentComposed Result
Admin+Inv.Service——+Inv.Service (grants all: View, Edit, Delete, Approve)
ServiceManager+Inv.Service.View
+Inv.Service.Edit
RestrictivePolicytrue+Inv.Service.View
+Inv.Service.Edit
-Inv.Service.Delete (restriction applied)
-Inv.Service.Approve (restriction applied)

Explanation of Step 1:

  • Admin: Simple role, no composition. Result: grants entire Inv.Service namespace.
  • ServiceManager: Composite role that includes RestrictivePolicy with canRestrictParent = true
    • Starts with: +View, +Edit
    • RestrictivePolicy adds: -Delete, -Approve
    • Because canRestrictParent = true, the negative privileges are applied
    • Composed result: View ✅, Edit ✅, Delete ❌, Approve ❌

Step 2: Merge Across Roles (using global priority)

Now we merge the two composed roles based on globalPriority:

PriorityRolePrivilegeDecisionReason
100AdminInv.Service.View✅ AllowHighest priority grants it
100AdminInv.Service.Edit✅ AllowHighest priority grants it
100AdminInv.Service.Delete✅ AllowHighest priority grants it
100AdminInv.Service.Approve✅ AllowHighest priority grants it
50ServiceManagerAll privileges—Ignored (lower priority)

Effective permissions:

  • Inv.Service.View → ✅ allowed (Admin priority 100)
  • Inv.Service.Edit → ✅ allowed (Admin priority 100)
  • Inv.Service.Delete → ✅ allowed (Admin priority 100 wins over ServiceManager's restriction)
  • Inv.Service.Approve → ✅ allowed (Admin priority 100 wins over ServiceManager's restriction)

Alternative Scenario: If user has only ServiceManager role (without Admin):

PriorityRolePrivilegeDecision
50ServiceManagerInv.Service.View✅ Allow
50ServiceManagerInv.Service.Edit✅ Allow
50ServiceManagerInv.Service.Delete❌ Deny
50ServiceManagerInv.Service.Approve❌ Deny

Effective permissions:

  • Inv.Service.View → ✅ allowed
  • Inv.Service.Edit → ✅ allowed
  • Inv.Service.Delete → ❌ denied (RestrictivePolicy restriction via canRestrictParent = true)
  • Inv.Service.Approve → ❌ denied (RestrictivePolicy restriction via canRestrictParent = true)

Key insight:

  • Phase 1 (Composition): canRestrictParent = true allows child roles to restrict parent's privileges within a single composed role.
  • Phase 2 (Merge): globalPriority determines which role wins across different roles - higher priority always overrides lower priority, regardless of restrictions in the lower-priority composed role.

6. Data Model Overview​

EntityDescription
rolesDefines role metadata, including globalPriority and composedRoles (list of included child roles).
role_privilegesLinks roles to privileges with prefixes + or –.
user_rolesAssociates users with roles.
privilegesStores all available privilege codes and descriptions.

Domain Model​


6.1 Reference - Entity Attributes​

Role (attributes)​

FieldTypeRequiredRead-onlyDescription / Notes
idUUID––Unique identifier (not intended for end-user display).
codeStringYes–Unique ASCII code (no spaces). Used in APIs & configurations. Min 1, max 255 characters.
nameStringYes–Display name shown to users. Min 1, max 255 characters.
descriptionString––Tooltip/long description.
validityFromDate––Begin of the validity of the role.
validityToDate––End of the validity of the role.
validBoolean–YesTrue/False depending on whether we are within validity interval. Computed, not stored.
localizationDataObject––Translations for attributes (e.g., name, description).
dataTagsList––Labels/tags for search and reporting.
ldapMemberOfString––If role is in LDAP, the location in LDAP directory.
configMap––Additional configuration.
auditInfoObject––Standard audit fields (created by/at, updated by/at).
globalPriorityInteger––Global priority for conflict resolution. Default: 0. Higher values take precedence.
composedRolesList<ComposedRole>––List of child roles included in this composite role. Each entry specifies childRoleId, childRoleCode, and canRestrictParent.

Privilege (attributes)​

FieldTypeRequiredRead-onlyDescription / Notes
idUUID––Unique identifier (not intended for end-user display).
codeStringYes–Unique ASCII code (no spaces). Used in APIs & configurations. Min 1, max 255 characters.
nameStringYes–Display name shown to users. Min 1, max 255 characters.
descriptionString––Tooltip/long description.
validityFromDate––Begin of the validity of the privilege.
validityToDate––End of the validity of the privilege.
validBoolean–YesTrue/False depending on whether we are within validity interval. Computed, not stored.
localizationDataObject––Translations for attributes (e.g., name, description).
dataTagsList––Labels/tags for search and reporting.
configMap––Additional general configuration of the Privilege entity.
auditInfoObject––Standard audit fields (created by/at, updated by/at).
privTypeEnum––Type of privilege: SYSTEM or USER. Default: SYSTEM.

PrivType Enum:

  • SYSTEM — system-defined privilege
  • USER — user-defined privilege

ComposedRole (nested object)​

Part of: Role.composedRoles list

Purpose: Defines a child role included in a composite role and its composition rules.

FieldTypeRequiredDescription
childRoleString–Code of the child role
canRestrictParentBoolean–If true, child role's negative privileges can override parent's positive privileges. Default: false.

Example API representation:

{
"id": "parent-role-uuid",
"code": "ServiceManager",
"name": "Service Manager",
"globalPriority": 50,
"composedRoles": [
{
"childRole": "RestrictivePolicy",
"canRestrictParent": true
},
{
"childRole": "BaseOperator",
"canRestrictParent": false
}
]
}

Role Privilege (attributes)​

Links roles to privileges with grant/deny prefixes.

FieldTypeRequiredDescription
idUUID–Unique identifier of the role-privilege relationship.
roleIdUUIDYesID of the role.
privilegeCodeStringYesCode of the privilege (can be a specific privilege or a namespace prefix).
prefixStringYes+ (grant) or - (deny).
auditInfoObject–Standard audit fields.

User Role (attributes)​

Associates users with roles.

FieldTypeRequiredDescription
idUUID–Unique identifier of the user-role assignment.
userIdUUIDYesID of the user.
roleIdUUIDYesID of the assigned role.
auditInfoObject–Standard audit fields.

7. Auditing and Debugging​

Every effective privilege can be traced to its source. tSM records which role granted or removed each permission and how conflicts were resolved.

Example audit log entry:

Privilege: Inv.Service.Edit
Effective: ALLOW
Source: +Inv.Service (from role Admin, priority 100)
Conflicted with: -Inv.Service.Edit (from role Reader, priority 10, ignored)

This ensures transparent decision tracking for compliance and debugging.


8. Best Practices​

RecommendationDescription
Use higher priorities for broader or administrative roles.Example: Admin = 100, Manager = 50, Reader = 10.
Keep canRestrictParent = false for most composites.Ensures inherited roles only expand capabilities.
Use canRestrictParent = true for compliance or security roles.Allows limiting sensitive actions.
Avoid deep nesting of roles.Simplifies privilege resolution.
Regularly review effective privileges.Changes in composite hierarchies can propagate widely.

9. Summary​

ConceptDescription
PrivilegeSmallest atomic access right (e.g., Um.User.Edit).
RoleA collection of privileges with + and – prefixes.
Global PriorityDetermines which role wins when conflicts occur.
Composite RoleRole that includes other roles.
canRestrictParentDefines whether a child role can override the parent's rights.

The result is a clear, modular, and auditable authorization system that supports both simple deployments and enterprise IAM integration.