OutSystems Developer Cloud End-User Roles, Groups and Group Mappings
In this article, we examine a significant change from O11 to ODC regarding end-user roles and a pattern for managing roles across ODC applications using end-user groups and Identity Provider claims mapping (Group Mappings).
For general information about ODC roles, check the official documentation.
End-User Roles
In OutSystems Developer Cloud applications end-user roles serve two main purposes:
Limit Access to Screens - Select specific roles for the screen, allowing only members of those roles to access it.
Limit Access to Actions - Add a Check<RoleName> client or server action to the client, server, or service action flow to verify a user's membership and either continue or stop the action flow.
It's important to note that roles grant access to screens or actions, not to individual resources like a record in an entity. Think of it like the entrance gate of a theme park: you can enter if you have a ticket, but once inside, there may be additional restrictions on rides (resources) based on age or height. These additional restrictions are outside the scope of roles, and it's up to your business and resource authorization logic to grant access to individual resources.
When I first wrote this article, roles in ODC were only available within the application where they were created. It was not possible to define a role as public, like in O11, and use it in other applications. However, today, roles in ODC can be defined as public, allowing them to be used in any other application.
In my opinion, having public roles in O11 made perfect sense and was necessary because it allowed the creation of multiple layers within an application. You could create a role in the Core Service layer and use it across the business logic and frontend layers. I never used roles across application boundaries because OutSystems roles, despite the name, are more related to individual permissions rather than user roles like "Sales Manager." For the latter, my approach was always to use OutSystems groups that combine user accounts with individual application roles.
This same approach is also my best practice for role management in ODC in an enterprise context, where central identity and access management are essential.
Role Management
I want to share my approach to ODC role management in an enterprise context. Let's start by looking at the different role types involved in this pattern.
Organizational Roles
On an organizational level roles typically refer to a job description. An Accounting department could have the following roles defined.
Head of Accounting
Accounting Manager
Accounting Clerk
Organizational roles are often described in a hierarchical structure to further detail a role. For example the Accounting Manager role could be structured into individual Accounting Manager roles for each legal entity or business unit of an organization.
Solution Roles
When it comes to software solutions, we define roles based on the features or areas of an application. For example, let's consider an expense management application that could have the following solution roles:
Expense Administrator: Manages expense policies.
Expense Approver: Reviews and approves or rejects submitted expenses.
Expense User: Employees who enter and track their expenses.
Solution roles have a much narrower scope than organizational roles. An organizational role might use multiple solutions and therefore need multiple solution role assignments.
Application and Resource Roles
In ODC a solution is usually not a single application but a set of ODC applications that work together to form the complete solution. An expense management solution might include the following individual applications:
Expense Mobile App - A mobile app for entering and tracking expenses.
Expense Web App - A web application for users to enter and track expenses, and for approvers to review and approve expenses.
Expense Manage App - A management application for managing and tracking expense policies.
Expense Service - A service application that provides the business logic as service actions to manage, store and retrieve (query) expenses for both the mobile and web applications.
Each of these ODC applications has its own roles to grant access to screens (for the mobile and web applications) and service actions (for the expense service). Our goal is to map solution roles, like Expense User, to the individual roles defined in our ODC applications.
Since we will associate multiple roles with a solution role, it is helpful to establish a proper naming convention for roles. This will provide a clear understanding of the associated permissions.
One approach is to use different naming conventions for ODC roles in frontend applications (mobile and web) to control screen access (application roles), and ODC roles in service applications to control access to service actions that handle business logic or return business data (resource roles).
For the above expense management we could define the following ODC roles
Expense Mobile App
- ExpenseTracking - Members of this role can use the mobile app to submit and track expenses
Expense Web App
ExpenseTracking - Members of this role can use the web app to submit and track expenses.
ExpenseApproval - Members of this role can approve expenses
Expense Manage App
- ExpenseManagement - Members of this role can use the web app to manage and track expense policies.
A naming pattern for roles in frontend applications should reflect the task or feature, along with its screens, that a user is performing.
Expense Service
The Expense Service provides business logic and retrieves expense data through service actions, but no screens. At a high level, service actions always deal with resources, whether they are internal entities or external services. A possible naming pattern is to define role names that reflect this interaction with resources.
In our simple expense management solution, we have two resources:
Expense - a single expense item submitted by a user
Policy - an expense policy created by an expense administrator
For these resources, we create the following ODC roles:
ExpenseRead - Members of this role can query expenses
ExpenseReadWrite - Members of this role can query expenses and also create or modify expense entries
PolicyRead - Members of this role can query expense policies
PolicyReadWrite - Members of this role can query expense policies and also create or modify expense policies
So far, we have defined the following roles:
Solution Roles
Expense Administrator
Expense Approver
Expense User
Application Roles
ExpenseTracking (Expense Mobile App)
ExpenseTracking (Expense Web App)
ExpenseApproval (Expense Web App)
ExpenseManagement (Expense Manage App)
Resource Roles
ExpenseRead (Expense Service)
ExpenseReadWrite (Expense Service)
PolicyRead (Expense Service)
PolicyReadWrite (Expense Service)
Roles to End-User Groups Assignment
Now it is time to bring them all together. For every solution role we create one ODC end-user group and associate the necessary application and resource roles to that group.
Expense Administrator
An expense administrator is responsible for managing and tracking expense policies. We conclude that an Expense Administrator only needs access to the Expense Manage App, so we add the ExpenseManagement (Expense Manage App) application role to the group.
Regarding resources, an Expense Administrator needs to read and write policies, so we add the resource role PolicyReadWrite (Expense Service). Additionally, they need to make reports on submitted expenses related to expense policies, so we assign the resource role ExpenseRead (Expense Service) as well.
ExpenseManagement (Expense Manage App)
PolicyReadWrite (Expense Service)
ExpenseRead (Expense Service)
Expense Approver
Approvers handle the approval or rejection of submitted expenses using specific screens in the Expense Web App. Therefore, we assign the ExpenseApproval (Expense Web App) role to the group. Approvers need to read and write expenses (setting the approval status), so we also add the resource role ExpenseReadWrite (Expense Service). Additionally, approvers need to know if expenses comply with defined policies, so we assign the PolicyRead (Expense Service) role as well.
ExpenseApproval (Expense Web App)
ExpenseReadWrite (Expense Service)
PolicyRead (Expense Service)
Expense User
Regular users can use the mobile or web app to submit and track expenses, so we assign the application roles ExpenseTracking (Expense Mobile App) and ExpenseTracking (Expense Web App) to the group. Users need to read and write expenses, so we assign the resource role ExpenseReadWrite (Expense Service). Additionally, they need to know if they are hitting an expense policy, so we add the PolicyRead (Expense Service) role as well.
ExpenseTracking (Expense Mobile App)
ExpenseTracking (Expense Web App)
ExpenseReadWrite (Expense Service)
PolicyRead (Expense Service)
This leaves us with an ODC end-user group for each defined solution role, and we can now associate individual user accounts with these roles to grant access.
But this is not the end of the story as we still want to map organizational roles to the created solution groups.
Mapping Organizational Roles to Solution Groups
The following section explains how to map organizational roles to ODC solution groups using Microsoft Entra Security Groups. This principle can also be applied to other Directory/Identity Provider combinations.
The good news is that you probably won't need to define and structure organizational roles yourself. These roles are usually described in an HR system by HR people, and the hierarchy and employee membership are often synced to Microsoft Entra as nested security groups and user accounts. If not, you should at least have a security group structure in your Entra tenant that somewhat reflects the organizational role structure.
Another requirement is to have your Entra tenant set up as the Identity Provider in your OutSystems Developer Cloud environment. The configuration steps are clearly explained in the OutSystems Developer Cloud Documentation.
ODC end-groups have a useful feature called Group Mappings. With Group Mappings, you specify a claim name and value. If a matching name and value are sent from the Identity Provider during user login, the user is automatically associated with the group.
If a user logs in through a configured Identity Provider to your applications, ODC retrieves multiple tokens, but only the Identity Token is relevant for group mappings. The Identity Token is a base64 encoded JSON document with multiple attributes, called claims.
A default Identity Token payload from Entra ID looks like this:
{
"aud": "<Audience>",
"iss": "<Issuer Url>",
"iat": 1720007848,
"nbf": 1720007848,
"exp": 1720011748,
"email": "<email address of identity>",
"name": "<full name of identity>",
"oid": "<object identifier>",
"ver": "2.0",
...
}
For example aud is the claim name and <Audience> the claim value.
For mapping organizational roles (represented as security groups in Microsoft Entra) the first thing we need to do is to create AppRoles in our Entra application registration.
Browse to Azure Portal - App registrations and select the application you created as ODC Identity Provider.
In the menu click on App roles
For each ODC end-user group created, create an App role like the following example for Expense User:
Repeat this step for the two remaining end-user groups
Expense Approver (value: Expense.Approver)
Expense Administrator (value: Expense.Administrator)
To assign security groups or users to the configured App roles switch to Enterprise applications in Azure Portal and select your registered application.
In the menu go Manage - User and groups and click on Add user/group
Select a group or user and one of the configured app roles and commit with Assign.
After assigning groups and users to App roles, the Identity Token will now include an additional claim called "roles" with an array of string values representing the App role values that this particular user belongs to.
{
"aud": "<Audience>",
"iss": "<Issuer Url>",
"iat": 1720007848,
"nbf": 1720007848,
"exp": 1720011748,
"email": "<email address of identity>",
"name": "<full name of identity>",
"oid": "<object identifier>",
"roles": [
"Expense.User"
],
"ver": "2.0",
...
}
Back in ODC Portal End-user groups we can now map the roles claim value Expense.User to our group.
And that's all the magic. After setting up your group mappings, a user who authenticates with your Entra tenant and has the assigned App roles, either directly or through group assignment, will automatically become part of the end-user group and have all the associated roles and permissions.
Summary
In this article, we explored a pattern for implementing end-user roles in OutSystems Developer Cloud. We defined different roles for various ODC application types and grouped them into end-user groups for easier user assignment.
Additionally, we learned how to use the Group Mappings feature of ODC to automatically assign users to end-user groups based on Identity Token claim values issued by Microsoft Entra.
This pattern offers great flexibility in role assignment and clearly separates the responsibilities of OutSystems Platform administrators, developers, and Identity Administrators. With this approach, Identity Administrators have full control over application access, while OutSystems administrators and developers do not need to manage end-user permissions (except for some non-standard permissions ๐).
Thank you for reading. I hope you enjoyed it and that I've explained the important parts clearly. If not, please let me know ๐ Your feedback is greatly appreciated.
Follow me on LinkedIn to receive notifications whenever I publish something new.
Subscribe to my newsletter
Read articles from Stefan Weber directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Stefan Weber
Stefan Weber
As a seasoned Senior Director at Telelink Business Services EAD, a leading IT full-service provider headquartered in Sofia, Bulgaria, I lead the charge in our Application Services Practice. In this role, I spearhead the development of tailored software solutions using no-code/low-code platforms and cutting-edge cloud-ready/cloud-native solutions based on the Microsoft .NET stack. Throughout my diverse career, I've accumulated a wealth of experience in various capacities, both technically and personally. The constant desire to create innovative software solutions led me to the world of Low-Code and the OutSystems platform. I remain captivated by how closely OutSystems aligns with traditional software development, offering a seamless experience devoid of limitations. While my managerial responsibilities primarily revolve around leading and inspiring my teams, my passion for solution development with OutSystems remains unwavering. My personal focus extends to integrating our solutions with leading technologies such as Amazon Web Services, Microsoft 365, Azure, and more. In 2023, I earned recognition as an OutSystems Most Valuable Professional, one of only 80 worldwide, and concurrently became an AWS Community Builder.