There are several ways how the concept of a group is used in Power Platform services. Many users and admins may be familiar with some of them, but grasping all the variations that a collection of users can have in various parts of the platform is actually pretty challenging.
In this article I will demonstrate how different types of groups/teams can be used together with the some common security features of Power Apps and Dataverse. We’ll examine how groups/teams work on these three main levels of access management in Power Platform:
- Environment level access
- App level access
- Data level access
Our demo users / groups / teams
The demo tenant we’ll be using contains the following user accounts with these roles:
- Marco – Power Platform Service admin
- Jukka – User
- Timo – User
- Antti – User
As for how these users come together, we’ve created the following constructs for grouping them:
- Security Group A: created via Azure AD
- Members: Marco and Jukka
- Microsoft 365 Group B: also created via Azure AD
- Members: Marco and Timo
- Teams Team C: created through the Microsoft Teams app
- Members: Marco and Antti
The above groups/teams reflect the main methods for how users might get grouped with one another in the Microsoft cloud. Whether you create these groups via the Azure Portal or Microsoft 365 Admin Portal shouldn’t matter technically. The Microsoft Teams client is of course one special way of enabling self-service creation of groups associated to Teams teams.
Environment security group
Our first access level exploration is on the environment level. In the world of Power Platform, environments are at the heart of most security settings (which is why environment governance is so critical). Associating a security group with any environments you create is definitely a recommended practice.
This is something you configure in Power Platform Admin Center (PPAC). It’s not required by the system, which means your existing environments may be missing a value here. When either creating or editing an environment, here’s the options we see in the “edit security group” dialog:
All our three groups are available here in the security group picker. You can therefore use anything from a security group to a Microsoft Teams team to control environment level access. Read the Docs page for more details on how to control user access to environments.
In our demo scenario we’ll choose Security Group A here, meaning Marco + Jukka. However, since Jukka doesn’t yet have anything else configured for his account, he can’t actually see or do anything with this environment. This is important to understand: the environment group is only a filter on top of everything else deeper down in the platform.
Sharing Power Apps access to a group
As a best practice, you should always lean towards sharing access to your Canvas apps and Model-driven apps via groups. This will make it much easier to manage app access in the long run, compared to directly sharing each individual app to every user account requiring access to it (or removal of access).
In our demo scenario, we are able to share our Canvas app (the Onboarding Tasks template app) to both the security group and the Microsoft 365 group without any issues. Our Microsoft Teams team doesn’t appear in this sharing dialog, though:
Are we not able to share apps to Microsoft Teams team members then? It is technically possible, but you’ll just need to perform one additional step to enable this. By default, Microsoft Teams doesn’t set the groups behind its teams as security enabled. To change this, an owner of the team needs to run PowerShell scripts to change the Azure AD group property “SecurityEnabled” to “true”. See instructions here. You can also leverage this Power Apps Canvas app from Théophile CHIN-NIN to do the settings update without PowerShell.
Environment security group vs. app sharing
Here’s one fact that may surprise you: users don’t need to be members of the environment security group in order to use the Canvas apps that have been shared to them. They won’t have any access to the Power Apps Maker portal and without belonging to the group, yet app usage is an altogether separate thing technically.
In our environment, Security Group A was associated as the environment security group. Now as we added Security Group A and Microsoft 365 Group B as users for our demo app, both Jukka (from A) and Timo (from B) are able to open the app without any issues via a direct link. (Note: this app is using only Office connectors, not anything from Dataverse.)
Looking at Power Platform Admin Center, we see that Jukka appeared into the environment as a user record when he opened the Canvas app:
However, he will not have any direct access to the environment from the Power Apps Maker portal. After all, he is an app user, not yet an app maker. Remember: the environment security group is just a filter, it doesn’t grant members any actual rights within the environment.
Timo, on the other hand, is using the Canvas app we shared, yet he doesn’t appear as a user in the environment at all. Despite of this, he has been able to create new connections into the environment with his personal credentials. This happens automatically when launching the app and accepting the consent dialogs for the Office connectors, meaning the platform has stored the info on Timo’s behalf.
As for the environment’s list of teams, there is nothing but the default team for the root Business Unit of this environment. None of our demo groups have appeared here automatically.
Let’s recap: sharing the Canvas app works to all group types (Teams requires an additiona step), yet this doesn’t leave any visible traces into the environment’s database for users nor teams.
If this sounds a bit strange to you, then it’s time to talk about how the users and teams in Dataverse have come to be what they are today.
Teams and users inside Dataverse: the background story
If you are leveraging Model-driven apps in your solution architecture, or working with Dataverse as a source for your Canvas apps or Power Automate flows, you will need to have your groups and users represented within the app database physically. This is where the Dataverse tables for Users and Teams come into play.
The first thing you need to understand that the user and team data inside Dataverse is owned by Dataverse, not Azure AD. Yes, the user identities are linked to Active Directory users, but you can extend the systemuser table columns as well as build forms and views, just like with any other table (formerly entity). Here’s a quick example of a customized user form:
Teams as a Dataverse concept have been around since the beginning of “XRM time”, meaning long before Microsoft Teams was invented. For the first ~15 years these teams didn’t talk with AD at all, until in 2019 the ability to create Azure AD groups as teams in Dataverse (then Common Data Service / CDS) was introduced. Today they are a central part of the business application security management practices, but older implementations may not be leveraging them, due to this history.
While you can extend the User and Team tables in Dataverse, the data that will get synchronized between Active Directory and Dataverse is controlled by Microsoft. It is somewhat limited, meaning for a user you’ll get the basic fields like name, job title, email, phone(s), address – all the rest remains unsynced. Even though many organizations would like to get more details in there, MS has not yet offered an out-of-the-box solution for it.
Teams in Dataverse are quite powerful when it comes to fine grained security model configuration. Especially in Dynamics 365 Customer Engagement (CRM) scenarios these have been often used for things like creating non-hierarchical structures to complement the purely hierarchical Business Unit functionality. We won’t dive into that rabbit hole today. For our purposes, let’s think of the Dataverse teams just as a similar grouping of users as our examples A, B and C are.
Adding teams to Dataverse
You could create purely local team records inside Dataverse and manage them there if no suitable group exists within your AD. Since the point of our exercise today is in connecting the groups from Microsoft 365 / Azure admin portal side into Power Platform features, we’ll use the values “AAD Security Group” and “AAD Office Group” in the team type dropdown presented as part of the new team creation process from PPAC:
Team name and description are pure Dataverse properties, but when browsing the values available in the group name field we get to see data from the Azure AD side. Here we are now outsourcing the group member management into AD and will be getting all the user addition and removal information from that service.
We can’t create an AAD linked team without granting a security role, so let’s choose Basic User for demonstration purposes. This won’t give the group members (meaning Jukka and Timo) access to any real apps or data, but it’s still more rights than what they had merely via app sharing or environment security group membership.
Initially when looking at the team members from Dataverse side, the list will be quite short. Why aren’t the users coming through? Is the synchronization not working?
Once our Security Group A member Jukka tries to access the environment via it’s direct URL, the system now retrieves his access rights by using this team. This also triggers the team member to be added as a visible member in Dataverse, even if no actual apps are accessible there yet. So, this is an on-demand process, rather than a bulk synchronization of team members that would happen at the time of linking the AAD group with a Dataverse team.
For Timo, who is not a member of the environment security group, the door is kept shut at an earlier stage already. The filter works just as intended – although the legacy error page for “notMemberOfOrg” from the Dynamics CRM 2011 era might make you wonder about it… While Timo can use Canvas apps in the environment, being added as a user in the Dataverse table is where the line is drawn.
In conclusion, while our groups from Azure AD can be added into the environment as teams in Dataverse, this does not guarantee that the group members would exist in the users table. Even if they would be members of the environment security group, you might have to run the “Force sync users” action via a Power Automate cloud flow to get the user table populated with the missing rows.
Granting groups access to data
Once the user row physically exists in the Dataverse table, it can be used by an application to evaluate what rows from other tables within that environment should be accessible to them. This is what security roles allow you to configure.
While they are quite a powerful feature, the user experience for managing Dataverse security roles hasn’t been updated for close to two decades now. As a result, it looks scary and confusing:
In the earlier example we granted the Basic User security role to all the members of the teams we added to Dataverse. In real life we wouldn’t be leveraging these default security roles but rather creating custom ones for our apps. In the above screenshot, we have a role called “Asset Manager” that has green dots lined up, meaning they have the following organization level privileges to the Asset table: create, read, write, delete, append, append to, assign, share. In short: full rights to every row in that one table – and nothing else, unless they inherit more privileges via other security roles assigned to them.
Time to validate how the data level access control works via groups and these security roles. In our demo environment, let’s open the floodgates by removing the environment security group entirely. We’ll also include Teams Team C into our Dataverse team, meaning all three demo users can now technically be users of our environment. Jukka was already there, Timo can now get through the front door and Antti is also eagerly waiting for some real app to be shared to him.
Let’s share another Canvas app with our 3 demo groups that’s leveraging the above mentioned asset table in Dataverse for its business data storage. Now when we are sharing the app, we need to also specify the data permissions. This means selecting an existing security role that grants sufficient access rights to the underlying tables. We’ll select “Asset Manager” for our example app:
After sharing the app & the security role to our Security group A, Microsoft 365 group B and Teams team C, all three users are able to not just open the Canvas app but also read and edit the asset data via the app. Again, they will not appear in the users table before actually opening an app from within the environment for the first time. After that’s completed, all is good.
We can use this same pattern for also sharing a Model-driven app with our groups. The sharing dialog looks a bit different now. While we can add all 3 group types here, the important thing to note that we’re actually specifying which security roles have visibility to this specific app module. So, as long as this list includes the above shared Asset Manager role, our users will be able to open the Model-driven app, too.
We’ve seen the various different layers of security management available for Power Platform environments, Power Apps applications and the underlying data. There certainly are many settings to consider, which can make things confusing at first. Also, the conceptual differences on how the Microsoft 365 / Azure AD users and groups map to the Dataverse users and teams isn’t by any means obvious.
The good news is that using all the three different group types in our demo scenarios worked consistently, once we went through the necessary steps. Harmonizing and streamlining environment, app and data level access via smart use of Microsoft 365 / Azure AD groups is therefore a goal worth pursuing.
UPDATE 2022-11-07: Starting October 2022, Microsoft has changed the requirements for users to access canvas apps in an environment. If there is an environment security group set, these users will now see the error message: “You can’t open apps in this environment. You are not a member of the environment’s security group.” See this forum thread for more details.