Before role-based access control was introduced, rights would be granted directly to user groups. When upgrading an older version of the Thinkwise Platform (G9 or earlier), temporary roles would be automatically created based on the user groups to ensure nothing changed for end users. Not everyone replaced these temporary roles with proper roles.
An earlier blog was written around the time of the 2017.1 release, which introduced roles and presented global guidelines.
Today, I’ll be providing more detailed guidelines for role administration within your application, even if it was built before roles were introduced.
What is a role?
A role is a collection of rights that allows a user to carry out a single responsibility.A responsibility can be anything from well-defined value chain activities to ad-hoc cases or a more passive responsibility like monitoring a flow of information.
One of our goals is that a role can be transferred to different users, so they can take over a responsibility, without inadvertently giving them more privileges than required.
Role size
To allow roles to be transferable, roles should be as small as possible. On the other hand, a role should be useful on its own - usable without having to combine them with other roles.Because of this, it would not be wise to name roles after functions, departments. Unless every member of the department or employee sporting this function has only one single responsibility within the application, the role would be too large.
For example, it would be problematic to create a role granting only the rights on the report model object. If the people responsible for printing this report are all unavailable and someone needs to take over, granting them the role to print this report will not be enough. At the very least, the menu and menu item should be granted. Or, if the report is not present in the menu, grant minimal rights on the menu item containing the table from which the report is executed as well.
Role naming
Application managers should be able to recognize what a role will provide to the users based on the name. Application managers cannot see the underlying collection of rights on model objects.Try to keep the names of the roles focused on the responsibility they support. The roles should be opaque to the underlying data structures, so try not to name them after model objects either.
Some examples of bad names:
- Manager Sales
- Internship
- External customer
- Task generate sales invoice
Examples of proper role names will follow in the other chapters.
Let’s start role-mining!
While the task at hand might seem daunting, creating roles can be approached in a very structured manner. There are some key starting points that will help to set up an initial, proper set of roles:- The menu
- The process diagrams
- Variants
- Strong entities
- Base data and configuration tables
- Subroutines marked as API
Every starting point will provide insight in one or more categories of roles. These categories are based around different types of responsibility.
For every category, I’ll provide a different approach of identifying and creating roles. The categories themselves are not formal in any way and might not fully cover all types of roles. Feel free to deviate where needed.
Operational roles
Operational roles are focused around elementary pieces of work or monitoring, done by a single user and often in a single session.
A well-built application should have many operational roles.
Good examples would be:
- Sales invoice creation
- High-risk quote review and approval
- Customer registration
- Customer review and approval
- Purchase order preparation
- Stock dashboard monitoring
- Department KPI monitoring
How to find operational roles?
Operational roles can often be found by looking at the leaf nodes in the process diagrams. Everything required to perform this step within the process can be bundled as a role. If you end up adding several menu items, you might want to scratch your head and re-evaluate whether this leaf node really represents a single activity.
Another approach to find operational roles is by looking at process flows. Process flow share some of the beforementioned attributes with operational roles - they are executed by a single user in a single session.
To validate whether you have identified all process roles, you can go over all menu items. When a menu item points to a variant, this variant is often tailored towards a specific activity. If the variant is properly focused on one activity or monitoring something specific, you can create the role around this the variant.
There are scenarios where a single menu item is responsible for multiple operational activities. This is not wrong but might be a bit trickier to maintain. Make sure that there are no dependencies between the various roles that use this menu item, so the roles remain transferable.
Dossier roles
The operational roles are used to support the happy flow and common exception scenarios. However, you cannot plan for everything. To provide support for ad-hoc cases, some expert users will need access to browse and/or modify the raw data. This responsibility is covered using dossier roles.
For instance: A phone call comes in from a customer. The customer accidentally registered twice and needs to have two accounts merged. There is no menu item developed to merge two customer accounts. The customer dossiers role can be used to manually merge the data of the two accounts. It might not be very user-friendly as the dossier screens are not tailored towards this specific activity, but it will get the job done. If this happens too often, it might be worth asking the developers to create a tailored menu item and corresponding operational role.
How to find dossier roles?
The ad-hoc responsibilities can be bundled as a dossier role for every strong entity. These dossiers are often accessible via the menu, providing access to all details related to this strong entity. It is quite common for a non-variant table to be used as dossier. Generally, there should be fewer dossier roles than operational roles.
Good examples would be:
- Sales invoice dossiers
- Employee dossiers
- Customer dossiers
- Article overview
- Stock overview
Always double-check to make sure the proper authorization prefilters are in place for these dossier roles, both on the strong entities and the details of these entities.
Configuration roles
While the previous two categories of roles focus around operational support, the configuration roles bring responsibility for base data management within the system.
These roles are a bit harder to identify as these responsibilities are often not included in process diagrams.
How to find configuration roles?
A good way to find base data is checking for tables which aren’t part of any role but still require occasional maintenance. Often, a menu item per type of base data is available.
Base data generally has a single key, a limited amount of records and is referenced by operational data.
If the data should only be configured once when installing the product, you found some base data. If you consider whether data should be stored as a table or a domain with elements, you found some base data.
You can choose to place responsibility for various base data in a single role. It is uncommon for all types base data to be managed exclusively by different users. But if your solution calls for it, feel free to make them as fine-grained as needed.
Good examples would be:
- General system configuration
- User management
- Article base data configuration
- Warehouse base data configuration
When there are multiple application instances or tenants (e.g. SaaS) it might be worth considering which roles are focused around the initial application configuration or tenant configuration and which roles are focused around changing operational base data. Responsibility of these often lies with different user groups.
API roles
Most applications provide one or more APIs to 3rd parties.
Logical operations or requests for data performed through API’s should be created as a role, so it can be granted to or revoked from accounts belonging to 3rd parties.
How to find API roles?
Subroutines defined to be an API are a very good way to identify these roles. Make sure to bundle them as logical sets per role. Having a role for creating a sales invoice via an API and a second role to add additional lines to this sales invoice would be odd.
Good examples would be:
- Purchase order status notification API
- Price list API
Row-level access considerations
Roles primarily focus on access to various parts of the application. However, there is a second dimension to be considered. Within the various parts of the application, not all data must always be available to the users. Users are often limited to a subset of rows, a slice of data.
We are entering the area of row-level access security. While there is a lot to write about this subject, this blog focuses on the overlap with roles.
Should we create a role for every slice of data?
The discouraged way
Information about row-level restrictions can certainly be encoded within the roles. This is done by defining prefilters on restricted data sources for every data slice.
For instance, an application requires restrictions on a data source based on regions: North, East, South and West. A way to approach this is by creating a prefilter for every region and set the prefilter as authorization prefilter per role.
When the model is set up like this, the roles will have to be duplicated per region. Stock overview (North), Stock overview (East), etc., each with a different region prefilter set as authorization prefilter.
A challenge arises when a new region, Central, is added to the system. A new prefilter must be created and new roles must be added in the Software Factory. This cannot be done directly in a live environment.
This is already quite tedious for a limited set of data slices like the regions above, but once you have an impressive set of roles and many more slices of row-level restrictions, you'll get an explosion of roles.
The encouraged way
Instead, the row-level restrictions on dynamic properties can be written into SQL prefilters. These prefilters can be defined as locked in the model, effectively turning them into authorization prefilters.
These prefilters would look something like this.
exists(
select 1
from user_region t2
where t2.region_id = t1.region_id
and t2.tsf_user = dbo.tsf_user()
)
A mapping of users and corresponding data slices is required within the application. The upside is that an administrator can update the row-level security settings by modifying the user_region data. There is no need to update the model or roles in the Software Factory.
Dealing with unrestricted users
There are often some users that are not limited by row-level restrictions. This must be facilitated without compromising on security or maintainability.
The most obvious approach would be to create an unrestricted version of the role where the prefilter is not locked. The prefilter is no longer a locked authorization prefilter in the model but will be locked for the restricted roles and unlocked for the unrestricted roles.
There are two reasons not to go with this approach:
- There will be maintenance on two nearly identical roles, restricted and unrestricted.
- There is a risk of forgetting to lock the authorization prefilter when developing new roles.
Instead, it would be wise to have the prefilters always set as a locked prefilter in the model. The prefilter code can be expanded to account for the unrestricted users. The example prefilters would look something like this.
exists(
select 1
from user_region t2
where t2.region_id = t1.region_id
and t2.tsf_user = dbo.tsf_user()
)
or exists(
select 1
from super_user t3
where t3.tsf_user = dbo.tsf_user()
)
An additional mapping of users not restricted by this type of row-level access restrictions will be required within the application.
No duplicate roles are required for various data slices and assignment of data slices can be done in a live environment. The mapping between users and data slices can be adapted to be as simple or as complex as the business demands.
Testing roles
Role simulation has been added to the Software Factory. Developers can leverage this feature to ensure every role can be used to fulfill the users’ responsibility. Process tests can be run in concert with role simulation to test the completeness of your role.The future of roles
Besides a concise authorization structure and transferable responsibilities, the future will bring even more incentive to have a robust administration of roles.- Platform rights for roles bring very little to the table and cause a lot of headaches when simulating roles. We'll probably get rid of them.
- All-rights roles do still exist but will be grandfathered in a future release. All-rights will be made available in IAM at user group level, granting access to all roles for an application.
- We'd like to group roles as modules. Independent software vendors will be able to release specific modules to IAM instead of the full complement of roles to align with licensing plans.
- We have plans to bind roles to menu items, variants and process flows, having them update automatically. Quite tricky, we are still in the process of hammering out the details on this one.
- The option to define the role under which an automated process test should run will make for powerful smoke tests.
- Roles are a prime candidate to be tied into workflow assignment mechanisms, assigning activities to those who can bear the responsibility of executing the activity.
- And much more.
We will follow up on the future of roles and the positioning of IAM in all this in another blog.
Bottomline is that it has many benefits to have a structured, proper administration of roles. Using the guidelines provided in this blog, your applications will be ready for the future!