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

  • +Privilegegrants permission
  • –Privilegerevokes 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 negative () privilege takes precedence (for safety).

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
  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: If two roles have equal globalPriority, negative () overrides positive (+) for safety.
  5. Generate audit trace indicating the origin of each privilege.

Example

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.ViewAllowHighest priority grants it
100AdminInv.Service.EditAllowHighest priority grants it
100AdminInv.Service.DeleteAllowHighest priority grants it
100AdminInv.Service.ApproveAllowHighest priority grants it
50ServiceManagerAll privilegesIgnored (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.ViewAllow
50ServiceManagerInv.Service.EditAllow
50ServiceManagerInv.Service.DeleteDeny
50ServiceManagerInv.Service.ApproveDeny

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
idUUIDUnique identifier (not intended for end-user display).
codeStringYesUnique ASCII code (no spaces). Used in APIs & configurations. Min 1, max 255 characters.
nameStringYesDisplay name shown to users. Min 1, max 255 characters.
descriptionStringTooltip/long description.
validityFromDateBegin of the validity of the role.
validityToDateEnd of the validity of the role.
validBooleanYesTrue/False depending on whether we are within validity interval. Computed, not stored.
localizationDataObjectTranslations for attributes (e.g., name, description).
dataTagsListLabels/tags for search and reporting.
ldapMemberOfStringIf role is in LDAP, the location in LDAP directory.
configMapAdditional configuration.
auditInfoObjectStandard audit fields (created by/at, updated by/at).
globalPriorityIntegerGlobal 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
idUUIDUnique identifier (not intended for end-user display).
codeStringYesUnique ASCII code (no spaces). Used in APIs & configurations. Min 1, max 255 characters.
nameStringYesDisplay name shown to users. Min 1, max 255 characters.
descriptionStringTooltip/long description.
validityFromDateBegin of the validity of the privilege.
validityToDateEnd of the validity of the privilege.
validBooleanYesTrue/False depending on whether we are within validity interval. Computed, not stored.
localizationDataObjectTranslations for attributes (e.g., name, description).
dataTagsListLabels/tags for search and reporting.
configMapAdditional general configuration of the Privilege entity.
auditInfoObjectStandard audit fields (created by/at, updated by/at).
privTypeEnumType 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
childRoleStringCode of the child role
canRestrictParentBooleanIf 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
idUUIDUnique 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).
auditInfoObjectStandard audit fields.

User Role (attributes)

Associates users with roles.

FieldTypeRequiredDescription
idUUIDUnique identifier of the user-role assignment.
userIdUUIDYesID of the user.
roleIdUUIDYesID of the assigned role.
auditInfoObjectStandard 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.