* Configuring Security |
[This is preliminary documentation and is subject to change.]
This topic describes the security system in TOPICA applications, especially how the system handles access control to individual patient data records, and how the configurator may customize this system.
This topic contains the following sections.
"Security" is a broad term used for many parts of a system:
Authorization (granting individual user rights on different data objects). For employee users this is matter of checking profiles and permissions set on the logged in user. (Patient users are much simpler- a logged in patient as has access to his or her own data - and nothing else).
(Restricting) access to data - on the data type level and/or on the individual record level (aka. "row level security"). This is what this topic is about.
TOPICA is designed to construct applications, that handle healthcare records. This type of data is almost per definition sensitive, personal information.
Access to sensitive information should be restricted to users that need the information for performing optimal healthcare service for the patients they encounter.
Security is about restricting access to data - ensuring that users may see / edit only the data, they are allowed to. The challenge is to specify which users are allowed to do what.
This topic only discusses access control to "records" - e.g. the data entered in the configured, dynamic forms - patient record data. And particularly how the configurator may customize this.
These factors related to users influence the security system:
Employee users:
Not all employee users are equal. Employee users may be given different rights, depending on their job functions, level of expertise/responsibility within the system etc.
In TOPICA this is modeled using Permissions and Profiles. Each permission controls access to a specific action (or actions) within the system. Permissions are defined by the framework. A profile is a collection of permissions. The framework defines a standard set of profiles, but profiles may be set up per application.
Employee users are associated with profiles (and hence indirectly with permissions). The set of permissions from all the profiles associated with a user, defines the functions, the user has access to. The set of permissions for the logged in user often has a direct visible effect in the user interface. If a user does not have permission (neither to read nor write) a particular piece of data, this is often seen as an inactive menu item or hyperlink. In the user has read access, but not write access, this may be seen as read-only fields in input forms and/or disabled "Save" buttons.
An employee user may be employed by 1 organizational unit (Glossary / Org.Unit) and "associated" with several - the security system does not distinguish between these. See User Administration.
Patient users:
Patient users are much simpler than employee users. Patient users are not separately created in the database. If "log in as patient" is enabled in the application (e.g. a .config file contains
<add key="LoginAsPatient" value="true" />
each patient created in the database may log in. Depending on installed login modules, patients may be automatically created in the system after login. As a consequence, there are no such things as "permissions and profiles" for patient users.
Per definition, a patient user only has access to his or her own data. That is, a logged in patient can only view/edit data in his or her own record - all other functions (organization management, user management, configuration, etc.) are inaccessible. Therefore, teh main menu that is displayed when an employee user is logged in, is NOT displayed when a patient is logged in.
![]() |
---|
Access type set up in the Data Dictionary is done separately for employee users and patient users. |
There may be differences between various type of healthcare record information. Examples:
Some pieces of information should be accessible across several organizational units (e.g. hospital departments), while other pieces of information should be restricted user associated with one organizational unit (encounter level data).
It is customary to treat information regarding psychiatric conditions with stricter security than information regarding somatic conditions.
The forms / tables in the configured data structure do not need to have the same access modes. Access modes may be specified per table in the Data Dictionary (by setting properties on the StructureElement)
Employee users:
The configurator may specify different types of READ access modes per form (table) using the AccessModeRead property.
The configurator may specify different types of WRITE access modes per form (table) using the AccessModeWrite property.
Patient users:
The configurator may specify different types of access per form (table) for patient users using the PatientAccessMode property.
None
Read
Write
![]() |
---|
Access type set up in the Data Dictionary is done separately for employee users and patient users. |
![]() |
---|
This chapter relates to employee users only - NOT patient users! |
In TOPICA the database table OrgUnit holds organizational units. Tables / records may have relations to OrgUnit - and these relations affect the security.
The structure of all healthcare data related to patients is configurable in TOPICA (the configurator defines input forms and relations between forms). The relations between forms are defined in The Structure File, where the configurator associates input forms with database table names using StructureElement items. Here the relations to OrgUnit are defined, too.
Healthcare systems normally use the term "encounter" to group healthcare data. An encounter is where a patient "encounters" the healthcare system. An encounter is related to one patient and one responsible organizational unit (but there may be references to more organizational units). The data stored in the encounter form (and all subforms below it) is said to be "owned" by the organizational unit responsible for the encounter.
Two different modes of relations to OrgUnit exist:
In the default mode, all dynamic tables (and hence all records) have one and only one relation to table OrgUnit. The type of relation to OrgUnit is specified on the StructureElement, field OrgUnitRelation.
The topmost level in the data structure where OrgUnitRelation=Select, is the "encounter" (any levels above this level must have OrgUnitRelation=None).
In the "external relations" mode, the configurator may specify any number of relations to table OrgUnit per dynamic table.
The topmost level in the data structure, where an OrgUnit relation is specified, is the "encounter".
In TOPICA the term "data owner" is used to specify the organizational unit "owning" the record.
Not all organizational units are equal. Most hospital departments are specialized, for example. Some very general forms may be useful on all departments, but forms for specialized examinations / procedures should only be "owned" by departments with the proper specialization.
Example: a form describing an operation should be related to ("owned by") surgical departments (meaning that employees on surgical departments may create/edit instances of this form). It would not make sense that a medical department should "own" data on operations.
The relationship between organizational units and the forms / tables "allowed" per each organizational unit is managed by setting the desired organizational unit in context, and select the tab "Tables". - see Organization Administration. Only forms / tables with OrgUnitConfigure=true on StructureElement are visible in this list.
![]() |
---|
The above description only discusses the "built-in" relations to organization. These relations influence the security (this is why this is discussed here in the first place). Other relations may well exits between patient record data and organization. For example: OrgUnitPicker elements configured in forms are used to enter relations to organization units. But these relations DO NOT (automatically) influence the security - so these relations are not discussed here. |
The functionality described above enables the configurators (and end users) to control many aspects of the security.
If more fine-grained control over the security is needed (e.g. "row level security"), the configurator may use computations to control all access.
Computations (like all other configuration options regarding security) are defined in The Structure File, on each StructureElement (and hence: per dynamic table table).
See Computation Reference) for detailed information.
A computation is simply a TOPICA Basic expression, returning a boolean value: True to allow access, False to deny access.
As always, the TOPICA Basic expressions have access to the full context (user, patient, record objects, .config-file settings, etc.)
The following computations controlling security may be defined:
Create _ allow creation of record
Read - allow read access to record
Update - allow updating of record
Delete - allow deletion of record (if no child records exist)
CascadeDelete - allow deletion of record AND all child records
Visible - display record in Patient Record Tree
Refer to demo configuration DemoSecurity for examples.
![]() |
---|
Some might ask: what is the difference between Read and Visible? When Visible is false, the user still has read access to records. The records are invisible in the Patient Record Tree, but it is possible for the user to view the data by other means. |
![]() |
---|
The above computations make it possible to specify some scenarios, that may not give much meaning. E.g. it is possible to allow users to create data, but deny all read access. |
Typical scenarios for using computations to customize access to data:
Some forms may only be relevant for some types of patients. Example: A form containing data about pregnancy should only be allowed on female patients. Define computation Create:
Patient.Sex = Sex_Female
Custom access per type of user: Some data may be accessible only by doctors, some data only by nurses, and some data by all employees. This may be implemented by testing on user's classification (if an employee classification is used) - or on user's profile:
Example: some data will be created and updated by doctors - nurses should have read, but update access.
Define computation Create to:
IsNotNull(EmployeeUser.Profiles("Doctor"))
Define computation Update to:
IsNotNull(EmployeeUser.Profiles("Doctor"))
Define computation Delete to:
IsNotNull(EmployeeUser.Profiles("Doctor"))
Define computation Read to:
IsNotNull(EmployeeUser.Profiles("Doctor")) Or IsNotNull(EmployeeUser.Profiles("Nurse"))
Implementing workflow - examples:
An instance of Form B can be created only after an instance of "sibling" form A has been created. Define computation Create for form B:
IsNotNull(ParentRecord.SubRecord("A"))
Instances of form C should only be visible, when an instance of the "sibling" form A is created, and field X in this record has the specific value Y. Define computation Visible for form C:
IsNotNull(ParentRecord.SubRecord("A")) And (ParentRecord.SubRecord("A").X = Y)
When the system determines, what kind of access the logged in user should have to a particular piece of patient record data, the following rules are used:
The access rights determined by the user is examined. If the user does have the requested permission, access is denied, and the following checks are not made.
The access rights originating from the record data is examined (this has mainly to do with "data ownership", i.e. which organizational unit "owns" the data, and how this relates to the user's associated org.units). If the user does have required access the organizational unit of the record (the "data owner"), access is denied, and the following checks are not made.
If the record or any of the record's "ancestor" records has status "closed", write access is denied.
Refer to Status Closed for details on how it is determined that a record is "closed".
Any relevant computations are evaluated. If the relevant computation is defined, and the expression evaluates to false, access is denied.
![]() |
---|
The computations defined by the configurator may only limit access - it cannot grant access, if the built-in algorithm described above denies access. |
Access to individual records is mainly through the patient record tree (the hierarchical treeview displayed in the left pane, when a patient is selected).