Extending record permissions
This functionality is available for Creatio 8.3.4 and later.
Out-of-the-box record-level access rights can implement any access condition. Users with the organizational or functional role can read, edit, or delete only the records their access rights allow. Learn more: Record permissions (user documentation).
To apply a condition through the out-of-the-box mechanism, Creatio calculates record-level access rights in advance and recalculates them whenever the record data changes — typically through business processes or triggers. Some access conditions are lightweight from a technical perspective and have little effect on Creatio performance. For example, comparing a single field value on the record. For a condition that depends on frequently changing data, or that applies to a large number of records, this recalculation can require significant computation and affect Creatio performance. Additionally, access rights can be temporarily out of date until the next recalculation completes since recalculating takes some time.
Since version 8.3.4, Creatio lets you extend the out-of-the-box record-level access rights with a condition, evaluated directly wherever Creatio checks access, instead of recalculating and storing access rights in advance. This lets you apply conditional access rights without the extra computation and without the risk of temporarily inconsistent access. A record permission extension is the class you implement to add a custom condition for the read, edit, or delete operation and one or more "Object" type schemas.
Typical scenarios for a record permission extension include:
- a "Read" operation restricted by a business-specific record attribute
- an "Edit" operation that depends on a simple condition
- a "Delete" operation controlled by a rule for a small number of "Object" type schemas
Each of these scenarios is also possible with the out-of-the-box mechanism alone, but requires additional configuration effort, such as a business process or trigger that recalculates access rights.
Record permission extensions are managed by the UseRecordPermissionExtensions additional feature. Out of the box, the feature is registered and enabled, so record permission extensions extend record-level access rights for the read, edit, and delete operations. Record permission extensions do not extend object-level or column-level access rights. They also do not extend any operation outside the out-of-the-box record-rights logic.
Extension combination modes
For every operation, Creatio checks whether an extension is configured for the current operation and "Object" type schema. If it is configured, Creatio executes the extension and combines the returned condition with the out-of-the-box condition. Select the combination mode to extend the record-level access rights based on the business goals listed in the table below.
Business goal | Combination mode to use | Description |
|---|---|---|
Replace the out-of-the-box access rights check | InsteadOf | Recommended mode. The extension condition alone determines access for the operation, and Creatio does not evaluate the out-of-the-box condition. |
Narrow access beyond the out-of-the-box access rights | And | A record passes the check only if it satisfies both the out-of-the-box condition and the extension condition. |
Broaden access beyond the out-of-the-box access rights | Or | A record passes the check if it satisfies either the out-of-the-box condition or the extension condition. We do not recommend using this mode, since Creatio must evaluate both the out-of-the-box and extension conditions, which can affect performance. |
Structure of the record permission extension
Creatio implements the record permission extension through the classes and schemas listed in the table below.
Element | Description |
|---|---|
| The main integration point for the record-level access rights extension. Creatio uses it to:
|
| An abstraction between the
|
| The concrete runtime implementation of
|
"Record permission extension" ( | The configuration schema that tells Creatio which extension to use. Creatio uses it to:
The extension parameters are stored in the Record permission extension lookup that based on the "Record permission extension" ( |
| Loads active rows from the "Record permission extension" (
|
"SysRecordPermissionExtensionListener" ( | Guards configuration changes and invalidates the cache of the
|
When the UseRecordPermissionExtensions additional feature is disabled, the CachedPermissionExtensionsProvider class does not initialize its cache or subscribe to synchronization events. Instead, the DBSecurityEngine class falls back to out-of-the-box record-right logic.
Selecting and resolving the applicable record permission extension
Creatio does not chain several extensions for the same operation and "Object" type schema. It selects and applies only one extension. Several active rows can exist for the same operation and schema, but configuration alone controls their priority — not the package load order or the class name.
Selecting and resolving the applicable record permission extension includes the following steps:
-
Identify the active configuration rows for the target operation type and the "Object" type schema.
-
Select the row with the lowest
Positionproperty value. If several rows have the samePositionproperty value, Creatio selects the row with the latestCreatedOnproperty value instead. -
Call the
TryGet()method of theClassFactoryclass. This Creatio mechanism resolves a class by its registered binding name, passing theExtensionNameproperty value of the selected row as the binding name to resolve. -
Resolve the extension.
- If the binding name matches a registered class, it uses that class as the applicable extension.
- If the binding name does not match any registered class, it skips the row and logs a warning, even though the row stays active in the database.
Filtering records for the "Read" operation
Creatio uses this flow not only for reading records. It also uses this flow in other query-building scenarios that must restrict which records are available, including update-related flows.
Building the condition for the "Read" operation through the GetRecordsByRightCondition() method of the DBSecurityEngine class includes the following steps:
-
Build the
QueryConditionobject, starting from the out-of-the-box record-right condition for the "Object" type schema. -
If the
UseRecordPermissionExtensionsadditional feature is enabled and a "Read" permission extension exists for that schema:- Call the
GetReadRightCondition(UserConnection userConnection, PermissionExtensionContext context)method. The extension class implements this method through theIReadRecordPermissionExtensioninterface. - Apply the returned
QueryConditionobject according to the combination mode configured for it.
- Call the
-
Attach the
QueryConditionobject to aSelectobject used for query construction. -
Transform the
Selectobject into SQL text.
This flow builds a filter condition for selecting which records are available. Determining whether the current user can perform the "Read," "Edit," or "Delete" operation for a specific record is a different task.
Evaluating access rights for a specific record
This flow determines whether the current user can perform the "Read," "Edit," or "Delete" operation for this exact record.
Evaluating the read, edit, and delete operations through the GetEntitySchemaRecordRightLevel() method of the DBSecurityEngine class includes the following steps:
-
Check whether the "Object" type schema is administered by records.
-
Short-circuit to full access rights for privileged users, when appropriate.
-
Select which record-level access rights to use.
- If the
UseRecordPermissionExtensionsadditional feature is disabled, uses the out-of-the-box access rights calculation. - If the
UseRecordPermissionExtensionsadditional feature is enabled, resolves the "Read," "Edit," and "Delete" permission extensions configured for the schema of the "Object" type.
- If the
-
Execute each applicable extension by building a correlated subquery that checks whether the extension condition matches the current record.
-
Transform the extension conditions into per-operation right levels, adding the following flags to the extension-derived access rights set:
- A matching "Read" permission extension adds the
CanReadandCanChangeReadRightflags. - A matching "Edit" permission extension adds the
CanEditandCanChangeEditRightflags. - A matching "Delete" permission extension adds the
CanDeleteandCanChangeDeleteRightflags.
- A matching "Read" permission extension adds the
-
Replace or merge the out-of-the-box access rights with the extension-derived access rights, using the combination mode configured for each operation. For example, the read operation may use the "And" mode, the edit operation may use the "InsteadOf" mode, and the delete operation may have no extension at all. This keeps each operation independent.
Read, edit, and delete may all have an applicable extension. If each operation has an applicable extension and uses the "InsteadOf" combination mode, Creatio returns only the extension-derived access rights for this record. It does not merge them with the out-of-the-box access rights. This behavior is both an optimization and a semantic rule.
Invalidating the cache and synchronizing web farm nodes
The cache of the CachedPermissionExtensionsProvider class is lazy and persistent. Creatio needs a reliable way to invalidate it after a configuration change. The following actions complete after an insert, update, or delete of the "Record permission extension" (SysRecordPermissionExtension code) schema of the "Object" type:
- The
SysRecordPermissionExtensionListenerclass clears the local cache of theCachedPermissionExtensionsProviderclass. The next request rebuilds the cache from fresh configuration data. - If your Creatio instance uses a web farm, the
CachedPermissionExtensionsProviderclass also publishes a synchronization message through a publish/subscribe channel. - Other web farm nodes receive the message and clear their own local caches, so all nodes apply configuration changes consistently.
Without this step, one node could keep using outdated extension metadata after another node had already applied a change.
Falling back to out-of-the-box behavior
Creatio falls back to out-of-the-box behavior in the following cases:
- If no extension exists for the operation and "Object" type schema, the out-of-the-box access rights logic continues to apply.
- If the extension method returns
null, Creatio treats the result as not applicable, as if no extension were configured for that operation in this evaluation. - If Creatio cannot resolve the selected extension name through the
ClassFactoryclass, it skips the extension and continues with the out-of-the-box behavior.
These fallback rules reduce the risk of hard failures in the record-level access rights extension.