Role-Based Access Control
This page documents the role-based access control (RBAC) system used across SureClinical, and how it governs access to SureDrive features, routes, and operations. It covers the role taxonomy defined in the Java backend, the Angular frontend enforcement layer, and the administration UI for managing roles and features.
Architecture Overview
SureClinical RBAC operates on two parallel role dimensions that are combined per user:
| Dimension | Purpose | Stored In |
|---|---|---|
| System Role | Platform-level authority (Admin, Editor, Viewer, etc.) | user.systemRole on the cached user object |
| User Role | Custom named role configured by admins; mapped to one or more application roles | user.userRole on the cached user object |
A User Role groups one or more Application Roles. Each Application Role belongs to a specific product (Archives/eTMF, CTMS, Network, QMS). Application Roles control which Application Features (individual UI capabilities) a user can access within that product. SureDrive uses the Archives (System / eTMF) application role set.
Role Taxonomy — Java Backend
UserRoleType Enum
File: SC/suredms-common/src/main/java/com/sureclinical/suredms/entity/UserRoleType.java
Defines the six role categories used across the platform:
| Enum Value | Value | Display Name | Role ID Prefix | Application Role? |
|---|---|---|---|---|
TYPE_ROLE | 0 | User Role | suredms_ | No (user-facing role) |
TYPE_ORGANIZATION | 1 | Organization (Legacy) | suredms_ | No (legacy) |
TYPE_SYSTEM | 2 | Archives (System) | suredms_etmf_ | Yes — required |
TYPE_CTMS | 3 | CTMS | suredms_ctms_ | Yes |
TYPE_NETWORK | 4 | Network | suredms_network_ | Yes |
TYPE_QMS | 5 | QMS | suredms_qms_ | Yes |
isApplicationRole() returns true for all types except TYPE_ROLE and TYPE_ORGANIZATION. TYPE_SYSTEM (Archives) is the required application role — it cannot be omitted from a user role definition. canGrantFeatureAccess() returns true for both application roles and the legacy organisation type.
APPLICATION_ROLE_TYPES is a computed constant holding all application role types, used wherever the system needs to iterate over configurable product roles.
SureRoles — Role ID Constants
File: SC/suredms-common/src/main/java/com/sureclinical/suredms/common/SureRoles.java
Central registry of all role ID strings and reserved usernames.
Role ID prefixes:
| Prefix Constant | Value | Application |
|---|---|---|
ROLE_PREFIX | suredms_ | Platform / User Roles |
ETMF_ROLE_PREFIX | suredms_etmf_ | Archives / SureDrive |
CTMS_ROLE_PREFIX | suredms_ctms_ | SureCTMS |
NETWORK_ROLE_PREFIX | suredms_network_ | SureNetwork |
QUALITY_ROLE_PREFIX | suredms_qms_ | SureQMS |
Platform / User Role IDs (prefix suredms_):
| Constant | Role ID | Description |
|---|---|---|
ROLE_SYSTEM_ADMIN | suredms_system_admin | Internal system administrator |
ROLE_SYSTEM_APP | suredms_system_app | Internal system application user |
ROLE_ADMIN | suredms_admin | Platform administrator |
ROLE_USER_MANAGER | suredms_user_manager | User management only |
ROLE_EDITOR | suredms_editor | Content editor |
ROLE_VIEWER | suredms_viewer | Read-only viewer |
ROLE_AUDITOR | suredms_auditor | Audit-only access |
ROLE_SPONSOR | suredms_sponsor | Sponsor (external viewer) |
ROLE_STUDY_ADMINISTRATOR | suredms_study_administrator | Study/drive administrator |
ROLE_PROJECT_EDITOR | suredms_project_editor | Project-scoped editor |
ROLE_FINANCE_EDITOR | suredms_finance_editor | Finance-scoped editor |
ROLE_HUB_USER | suredms_hub_user | External hub user |
ROLE_ETMF_ADMIN | suredms_etmf_admin | Alias for Archives Admin |
Network roles (suredms_network_): viewer, editor, admin, hub_user
QMS roles (suredms_qms_): viewer, auditor, editor, training_manager, documents_manager, admin, department_manager, hub_user
Internal / reserved usernames: Administrator, scsystem, scapp, guest. These accounts are excluded from licence counts and cannot be assigned signing roles.
Internal roles (hidden from admin UI): administrators, suredms_system_admin, suredms_system_app.
PredefinedRoles Enum
File: SC/suredms-common/src/main/java/com/sureclinical/suredms/common/PredefinedRoles.java
Defines the ten built-in roles that are created by default on every SureClinical installation. Each predefined role carries IDs for all four application surfaces.
| Enum | Display Name | User Role ID | eTMF Role ID | CTMS Role ID | Network Role | QMS Role |
|---|---|---|---|---|---|---|
ADMIN | Admin | suredms_admin | suredms_etmf_admin | suredms_ctms_admin | network_admin | qms_admin |
USER_MANAGER | User Manager | suredms_user_manager | suredms_etmf_user_manager | suredms_ctms_user_manager | network_editor | qms_viewer |
STUDY_ADMINISTRATOR | Study Administrator | suredms_study_administrator | suredms_etmf_study_administrator | suredms_ctms_study_administrator | network_editor | qms_viewer |
EDITOR | Editor | suredms_editor | suredms_etmf_editor | suredms_ctms_editor | network_editor | qms_editor |
VIEWER | Viewer | suredms_viewer | suredms_etmf_viewer | suredms_ctms_viewer | network_viewer | qms_viewer |
AUDITOR | Auditor | suredms_auditor | suredms_etmf_auditor | suredms_ctms_auditor | network_viewer | qms_auditor |
PROJECT_EDITOR | Project Editor | suredms_project_editor | suredms_etmf_project_editor | suredms_ctms_project_editor | network_editor | qms_viewer |
FINANCE_EDITOR | Finance Editor | suredms_finance_editor | suredms_etmf_finance_editor | suredms_ctms_finance_editor | network_editor | qms_viewer |
SPONSOR | Sponsor | suredms_sponsor | suredms_etmf_sponsor | suredms_ctms_sponsor | network_viewer | qms_viewer |
HUB_USER | Hub User | suredms_hub_user | suredms_etmf_hub_user | suredms_ctms_hub_user | network_hub_user | qms_hub_user |
getApplicationRoleId(UserRoleType application) resolves the correct role ID for a given application surface. DEFAULT_ROLES, DEFAULT_ETMF_ROLES, DEFAULT_CTMS_ROLES, DEFAULT_NETWORK_ROLES, and DEFAULT_QUALITY_ROLES in SureRoles are computed from these predefined values.
PredefinedRoles.toEtmfRole(role) and toCtmsRole(role) convert a user role ID to the corresponding eTMF/CTMS application role ID — used during study-level role assignment for SureDrive and SureETMF.
Frontend Role Constants
File: SC/suredms-web-client/src/main/webapp/app/js/common/user.js
The web client mirrors the Java role registry with JS constants used throughout Angular controllers.
System role ID constants:
| JS Constant | Value |
|---|---|
SYSTEM_ROLE_SYSTEM_ADMIN | suredms_system_admin |
SYSTEM_ROLE_ADMIN | suredms_etmf_admin |
SYSTEM_ROLE_STUDY_ADMIN | suredms_etmf_study_administrator |
SYSTEM_ROLE_EDITOR | suredms_etmf_editor |
SYSTEM_ROLE_PROJECT_EDITOR | suredms_etmf_project_editor |
SYSTEM_ROLE_FINANCE_EDITOR | suredms_etmf_finance_editor |
SYSTEM_ROLE_VIEWER | suredms_etmf_viewer |
SYSTEM_ROLE_AUDITOR | suredms_etmf_auditor |
SYSTEM_ROLE_SPONSOR | suredms_etmf_sponsor |
Role group arrays used for access checks:
| Array | Members |
|---|---|
ADMIN_ROLES | administrators, suredms_system_admin, suredms_system_app, suredms_etmf_admin |
SYSTEM_ROLES | suredms_system_admin, suredms_system_app |
AT_LEAST_ADMIN_ROLES | All ADMIN_ROLES + suredms_etmf_study_administrator |
AT_LEAST_EDITOR_ROLES | All AT_LEAST_ADMIN_ROLES + editor variants (editor, project_editor, finance_editor) |
User-facing role objects (USER_ROLE_*) carry { id, name, style, rank } and form the USER_ROLES sorted array used in the admin UI for filtering and display styling.
UserService — Frontend Authorization API
File: SC/suredms-web-client/src/main/webapp/app/js/common/user.js (Angular service UserService)
UserService is the primary authorization API consumed by Angular controllers, components, and route guards. All checks read from CacheService.getCurrentUser() (or a named user from the system snapshot) and compare against the role group arrays above.
Identity Checks
| Method | Returns true when |
|---|---|
isSystemUser(username?) | User is scsystem or scapp (internal system accounts) |
isSystemAdministratorUser(username?) | Username equals scsystem exactly |
isSystemApplicationUser(username?) | Username equals scapp exactly |
isSystemAdminUser(username?) | Username equals admin exactly |
isExternal(username?) | user.external === true |
isExcludedFromLicenseUser(username?) | Is a system or admin user; does not consume a licence |
Privilege Checks
| Method | Access Level | Typical Use |
|---|---|---|
isSystemAdmin(username?) | SYSTEM_ROLES | Guard internal-only operations |
isAdmin(username?) | ADMIN_ROLES | Show admin-only UI, gate user CRUD, import/export |
isAtLeastAdmin(username?) | AT_LEAST_ADMIN_ROLES | Includes Study Administrator; used for date format settings |
isAtLeastEditor(username?) | AT_LEAST_EDITOR_ROLES | Includes all editing roles |
isViewer(username?) | Role equals SYSTEM_ROLE_VIEWER | Read-only fallback state |
isSystemAdministratorUser() | Username is scsystem | Server configuration edit guard |
hasRole(role, username?) | Role ID equals user.systemRole exactly | Point-specific role check |
Representative Usage Patterns
// Gate admin-only actions in the Users controller
UserService.isAdmin() // show Import from AD, Export to Excel, etc.
// Gate feature editing in server configuration panels
UserService.isSystemAdministratorUser() // server.js: isFeaturesEditable
// Gate signing certificate downloads
UserService.isAdmin() // user-signing-certificate.js: canDownloadCertificate
// Prevent system accounts from appearing in signers list
!UserService.isSystemUser(user.username) && !UserService.isSystemAdminUser(user.username)
// Allow editing a user only if the current user outranks the target
UserService.canEditUser(targetUsername)
// Internally: compares systemRole ranks using getSubSystemRoles()
Role Rank Hierarchy
getSubSystemRoles(role) computes which roles a user can manage by comparing rank values from the USER_ROLES array. Higher rank = more authority. A user can edit or manage users whose systemRole.rank is ≤ their own rank. The rough ranking is: System Admin (10) > Admin (5) > Study Admin (3) > Editor/Project Editor/Finance Editor (2) > Viewer/Auditor/Sponsor (2).
User Data Model
Each user object in the system snapshot carries:
| Field | Description |
|---|---|
username | Unique login name |
systemRole | eTMF (Archives) system role ID string — primary authority level |
userRole | Custom user role ID — maps to application roles |
external | Boolean; external Hub Users |
active | Boolean; inactive users cannot log in |
archives | Array of study/drive archive objects the user belongs to |
projects | Array of CTMS project objects |
features | Array of enabled feature IDs for this user |
Route Guards and Access Enforcement
requireLogin
All protected routes in SC/suredms-web-client/src/main/webapp/app/js/state/app-states.js carry data: { requireLogin: true } in their state definition. The Angular router run block checks this flag on every state transition and redirects unauthenticated users to the login page.
requireRule
Some routes additionally carry data: { requireRule: NAVIGATION_RULE_* }. Rule constants (e.g., NAVIGATION_RULE_DOCUMENTS_MIGRATION) are evaluated at navigation time and can gate access to features like document migration based on the user's role and enabled modules.
Controller-Level Guards
Most feature-gating happens inside individual Angular controllers, not at the route level:
// Integration manager: only admins or system admins can edit
integrationManager.isEditable = UserService.isAtLeastAdmin() || UserService.isSystemAdministratorUser();
// Administration dashboards: only admins
administrationUser.isCurrentUserAdmin = UserService.isAdmin();
// Server configuration panels: only system admin
administrationServer.isFeaturesEditable = UserService.isSystemAdministratorUser();
// Signing setup wizard: skip system users
if (UserService.isSystemUser(username) || UserService.isSystemAdminUser(username)) { ... }
Administration UI — Roles and Permissions
Accessing Role Administration
Navigate to Administration → User Roles in the SureClinical dashboard.
Help file: Help/contents/Content_Repo/Viewing_and_Managing_User_Organization_Roles_and_Person_Roles.htm
The page shows three panels:
- Applications and User Roles — graphical matrix of user roles, application roles, and user counts. Filter by application type (Archives/System, CTMS).
- User Roles — list of all named user roles, each showing its mapped application roles.
- Applications and Application Roles — per-application role list (Archives, CTMS, Network, QMS).
Creating and Managing User Roles
Help file: Help/contents/Content_Repo/Creating_and_Managing_User_Roles.htm
A User Role bundles one application role per product. Creating a new role:
- Click +, enter a User Role Name.
- For each SureClinical application (Archives, CTMS, Network, QMS), select the Application Role to assign.
- Click Create.
Editing: click the role name to enter the Application Features view. Select which sub-features within each application role are accessible to users bearing this role. Click Update to save.
All users assigned to a User Role inherit both the chosen Application Roles and the selected Application Features.
Creating and Managing Application Roles
Help file: Help/contents/Content_Repo/Creating_and_Managing_Application_Roles.htm
Application roles are per-product permission containers. Creating a new application role:
- Click +, enter a Name and select the Type (Archives, CTMS, Network, or QMS).
- Click Create.
Editing: click the role name to see the feature checklist for that application. Toggle individual features on or off and click Update. Use the overflow menu to switch between application types (Archives, CTMS, Network, QMS) when viewing or assigning features.
Application Features
Help file: Help/contents/Content_Repo/Configuring_SureClinical_Application_Features.htm
Application features are the finest-grained permission unit. They are grouped by product and include both system-level features (e.g., External User Creation, Flex editor access) and module-specific features (e.g., Administrative Reports tab). Assigning a feature to an Application Role makes it available to every User Role that includes that Application Role.
The server-side operation constants for role-related reports are defined in SureOperations:
| Operation Constant | Value |
|---|---|
OP_MOBILE_GET_APPLICATION_ROLES_REPORT | Mobile.GetApplicationRolesReport |
OP_MOBILE_GENERATE_APPLICATION_ROLES_REPORT | Mobile.GenerateApplicationRolesReport |
OP_MOBILE_GET_USER_ROLES_REPORT | Mobile.GetUserRolesReport |
OP_MOBILE_GENERATE_USER_ROLES_REPORT | Mobile.GenerateUserRolesReport |
RBAC in SureDrive Context
Who Can Do What in SureDrive
| Action | Minimum Required Role |
|---|---|
| View SureDrive documents | Viewer (suredms_etmf_viewer) |
| Upload documents, initiate workflows | Editor (suredms_etmf_editor) or above |
| Manage content model, blinding rules, properties | Study Administrator (suredms_etmf_study_administrator) or above |
| Create or delete a SureDrive | Admin (suredms_etmf_admin) |
| Export / lock a SureDrive | Admin |
| Configure server settings, application features | System Administrator (scsystem username) |
| Sign documents without a workflow | Admin or Study Administrator |
| Manage users and user roles | Admin (isAdmin() = true) |
| Download signing certificates | Admin |
| Manage integration / connector configuration | isAtLeastAdmin() or isSystemAdministratorUser() |
Study-Level Role Assignment
When a user is added to a SureDrive via the Team menu, their userRole is translated to an eTMF-scoped application role using PredefinedRoles.toEtmfRole(role). This mapped eTMF role governs their permissions within that specific drive, independently of what other drives they may belong to.
External Hub Users (HUB_USER) receive a restricted application role (suredms_etmf_hub_user) which limits their access to shared content only.
Blinding Rules and Document Visibility
Blinding Rules (see the SureDrive Properties page) layer additional per-folder, per-user access restrictions on top of the system role. A user's role may grant general read access, but blinding rules can further restrict which content types they see within a drive. Visibility can also be configured at the individual document level from the Documents area.
Feature Flag Interaction
ProvisioningCacheService.isModuleEnabled(MODULE_*) gates certain role-based actions behind active module licences. For example, importing pending users from Active Directory requires both isAdmin() and isModuleEnabled(MODULE_LABORATORY) to be true simultaneously.
Permissions Layer
While roles define who a user is, the permissions layer enforces what a user can do at the document, archive, feature, and network level. The classes and services below sit between the role taxonomy and the actual UI/API operations.
DocumentPermissionsHelper — Document-Level Permission Gate
DocumentPermissionsHelper is the authority on whether the current user may perform any operation on a specific document. It is constructed with a Document instance and resolves the current User from DesktopClient. On construction it computes all state flags once; callers query individual boolean methods.
State evaluated at construction:
| Flag | Source |
|---|---|
isSureDriveDocument | document.isCloudDocument() |
isReadOnlyArchive | UserVisibilityHelper.isArchiveWriteable() + archive.isLocked() |
isRemoteArchive | archive.isRemote() |
isHierarchyLocked | Any parent folder is locked (unless user is whitelisted) |
isLocked | Document itself is locked (unless user is whitelisted) |
isEffectivelyReadOnly | Union of above + isEntityWriteable, checked-out state, site-document flag, quality archive flag |
Key permission methods:
| Method | Returns true when |
|---|---|
isEffectivelyReadOnly() | Document cannot be modified by this user |
isSignable() | PDF mime type + not yet certified |
canBeMovedToArchive() | Queued doc, not read-only, acquire queue feature enabled, document complete |
canBeMovedToQueue() | Regular doc, not read-only, acquire feature enabled; for SureDrive docs also checks per-drive acquire queue setting |
canEditPdf() | Not read-only, not signed, PDF mime type, exportable |
isMimeTypePdf() | Document blob is application/pdf |
isExportable() | InstanceRestrictionsHelper.isExportable(document) |
DocumentPermissionsHelper is imported in WorkflowPlatformServiceImpl, WorkflowNavigatorPanel, and NuxeoHelper to enforce document-level constraints within workflow and Nuxeo integration code paths.
FeatureSnapshotHelper — Feature-to-Role Permission Engine
File: SC/suredms-common/src/main/java/com/sureclinical/suredms/common/objects/FeatureSnapshotHelper.java
FeatureSnapshotHelper wraps a FeatureSnapshot (a data transfer object loaded from the server) and provides efficient lookup of whether a given application role has access to a given feature flag.
Internal structure:
permissions:Map<featureKey, Map<roleId, FeatureSnapshotItem>>— the full matrix of feature × role entries.enabledFeaturesForRole:Multimap<roleId, featureKey>— fast iteration of all enabled features for one role.featuresById:Map<featureKey, FeatureDescriptionDto>— feature metadata for display.
Key methods:
| Method | Purpose |
|---|---|
getFeaturePermissions(role, featureKey, defaultValue) | Returns boolean — whether the role has access to the feature; falls back to defaultValue if not configured |
getFeaturePermissions(role, List<BasicFeatureDescription>) | Returns Map<featureKey, Boolean> for a set of features at once |
getEnabledFeatures(roleId) | Returns the display-name list of all features enabled for a role |
getFeatureKeys() | Ordered list of all feature keys in the snapshot |
getRoles() | Ordered list of all role IDs in the snapshot |
FeatureSnapshotHelper is used in:
AbstractFeatureManager(desktop connector) — delegated to viagetFeaturePermissions(role, featureKey)to gate desktop features per role.ApplicationConfigurationParser(parser) — used to render an "X" cell in the exported feature-permission matrix spreadsheet.
ExpandedArchiveAclRule — Archive ACL Model
File: SC/suredms-common/src/main/java/com/sureclinical/suredms/common/objects/ExpandedArchiveAclRule.java
An ExpandedArchiveAclRule represents a single access control rule for an archive (SureDrive or study). It carries the following permission dimensions:
| Dimension | Fields |
|---|---|
| Rule metadata | id, active, unrestricted, permissionType (READ_WRITE or restricted) |
| Target | archiveId — the specific archive this rule applies to |
| Users | users — set of user IDs explicitly covered |
| Archives | archives — set of child archive IDs |
| Content types | contentTypes, hiddenContentTypes, writableContentTypes |
| Organizations | organizations, hiddenOrganizations, writableOrganizations |
| Documents | documents, hiddenDocuments |
The hidden* sets define what content the matching users cannot see; the writable* sets define what they can edit. This model supports the blinding rules system described in the SureDrive context section above.
UserRolesApplicationFeaturesService — Frontend Feature Permission Editor
Angular service UserRolesApplicationFeaturesService is the frontend-side counterpart to FeatureSnapshotHelper. It drives the Application Features editing UI in Administration → User Roles.
APPLICATION_PERMISSIONS map:
Maps application type IDs to the feature flags that control whether that application is accessible at all:
| App Type ID | Constant | Features Mapped |
|---|---|---|
2 (Archives) | ARCHIVES_APPLICATION_TYPE_ID | FEATURE_ETMF_APPLICATION_ENABLED, FEATURE_SURE_DRIVE_APPLICATION_ENABLED, FEATURE_SURE_HUB_APPLICATION_ENABLED, FEATURE_SURE_ISF_APPLICATION_ENABLED, FEATURE_SURE_QMS_APPLICATION_ENABLED |
3 (CTMS) | CTMS_APPLICATION_TYPE_ID | FEATURE_CTMS_APPLICATION_ENABLED |
4 (Network) | NETWORK_APPLICATION_TYPE_ID | FEATURE_NETWORK_APPLICATION_ENABLED |
FEATURES_TO_HIDE is a list of application-enable feature IDs that are suppressed from the feature checklist to prevent admins from accidentally disabling an entire product through the per-role editor.
Key methods:
| Method | Purpose |
|---|---|
getFeaturesFromApplication(application) | Collects {featureKey, role, access} snapshot items from current checkbox state for a given application panel |
createApplication(application, features, role) | Builds an application panel model from the feature list and role; splits Archives into "System" and "Archives" sub-panels |
NetworkPermissionService — Hub and Project Permission Checks
File: SC/suredms-web-client/src/main/webapp/app/js/ (injected Angular service)
NetworkPermissionService resolves whether the current user can edit a SureNetwork hub or project. It is consumed by:
| Consumer | Usage |
|---|---|
store/store.js | store.canEditProjectHub = NetworkPermissionService.canEditHub(hub) |
portal/portal-context.js | Gates project editing in the portal dashboard |
network/workspace/projects/workspace-projects.js | Controls write access to workspace project records |
Permissions in Reports
Role and permission data is also exposed through the reporting system:
| Report Type | Constant | Description |
|---|---|---|
USER_ROLE | ReportType.USER_ROLE | Lists all users and their assigned user roles |
APPLICATION_ROLE | ReportType.APPLICATION_ROLE | Lists application roles and their feature sets |
USER_ACCESS_BY_ARCHIVE | ReportType.USER_ACCESS_BY_ARCHIVE | Shows per-archive user access permissions |
Column constants (ReportConstants.USER_ROLES, ReportField.FIELD_USER_ROLES) and training certificate fields (TrainingCertificateFields.FIELD_USER_ROLES) make role data available in generated report output. Report generation is initiated via SureOperations.OP_MOBILE_GET_USER_ROLES_REPORT and OP_MOBILE_GENERATE_USER_ROLES_REPORT.