DEV Community

Cover image for Hacking Access to Power Automate
david wyatt
david wyatt Subscriber

Posted on • Edited on

Hacking Access to Power Automate

Accessing Power Automate is controlled by security roles, with the 3 main ones being System Admin, Maker and Basic User. This though is only for Dataverse enabled environments (non just have System Admin and Maker).

So I wanted to look at how secure Power Automate actually is, and I suspected the biggest exposure is the Basic User role. Microsoft states that:

basic user role
https://learn.microsoft.com/

So as you can see, it is required to use an app in an environment (though not always the case, it should be), and it is pushed as good practice to.

use basic user for apps
https://www.matthewdevaney.com

This means a lot of people will have this role and in production environments too.

As a comparison what actual rights does Basic User have:

Basic User
CRUD (Create Read Update Delete) access to records that you create on selected tables. Organisation view rights on some system tables.
Maker
CRUD access to records that you create on selected tables (just more), and selected api's

And now lets dive into what this actually means:

Scenarios

  • Non Dataverse Environment Access Shared Flow
  • Dataverse Environment Access Shared Flow
  • Dataverse Environment Create Flow
  • App calls Flow
  • Read Variables

Additional

  • Learnings
  • How to Protect your Environments

Couple of call outs before we dive in:

One important thing to understand, security should be at the back end, not just the front end. Presuming that everyone will only access the way you expect is just ridiculous. Its like putting up a gate but no fence, the only people who would follow the rules are the polite ones, the ones you worry about would just walk around it.

house with no security

Another key is PoLP (The principle of least privilege), this principle is one of the foundations to good security. It states that you should only have access to something if you need it and at the level you need, nothing more, nothing less. This can add administrative overhead (more roles, less bucketing), but if you don't follow it its the equivalent of giving everyone a 'master key' because its easy then giving them just the keys they need.

polp

Lastly you really should be using Dataverse enabled environment, it is the future for the platform (and is required for solutions). It still allows build flows out side of solutions (like the non Dataverse environments), unless you set 'Create new canvas apps and cloud flows in Dataverse solutions' in the environment options. Then any flow or app created outside are still solution aware, just in a shared solution (normally the Common Data Service Default Solution).

create new in dataverse


Non Dataverse Environment Access Shared Flow

As you may have noticed there is no Basic User role in non Dataverse environments, what does that mean, well it kind of means everyone is a Basic User.

In this scenario the user does not have maker role, but another user with maker role shares their flow with them. They can't see it in the standard UI, but if the url to the environment is shared, guess what, they can see it, edit and run it.

If outside of Dataverse I can access flows shared with me, even if you have no role, you don't need maker role to edit, only create

Dataverse Environment Access Shared Flow

In Dataverse environments it is similar, you just need Basic User role (except if the flow is made outside of a solution, in this case it is treated the same as a flow in a non Dataverse Environment).

If a Dataverse flow (solution aware), I can access flows shared with me if I have Basic User, you don't need maker role to edit

Dataverse Environment Create Flow

What about creating a Dataverse flow in an environment with only Basic User, the role gives me CRUD rights for certain tables, is the workflow table one of those tables, well yes it is.

workflows permissions

Through the UI I can't create a flow, even though I have the permission:
cant create flow in designer

But guess what, through the api I can:
can create flow in api

As a Basic User I have full CRUD rights to the workflows table, it is only the maker UI that stops me creating a flow

It even appears in the UI where I can treat it like a shared flow, editing it, turning it on and off.
created flow

Well kind of, the good news from security side is the above example worked with no connections, what about with connections. So it turns out those selected tables do not include connection references.

cant CRUD connection reference

So even though I can create connections in the environment (this is what happens when we use Power Apps in an environment, and can be done if you have the environment url), I can't create connection references (or even read them).

connection reference permissions

But, lets say I did have maker access before, I created a connection reference, now after dropping to Basic User, I still can't access the connect reference, but I don't need to. The flow runs without checking owners permission to access the connection reference, so now I can create flows through the api as long as I reference one of my connection references. Note even if the connection reference is shared with you, you still cant use it, this is because you don't have rights to the connection within the connection reference.

no access but flow is running
Above shows access error due to missing permissions but it is still running

Connection References are the only blocker to Basic Users creating flows.

But wait a second, we already know about differences between solution aware and non solution flows, the latter does not have connection references. So what happens if we send a flow which uses legacy connections (no connection references):



"connectionReferences": {
    "shared_sharepointonline": {
        "connectionName": "shared-sharepointonl-594ec2f7-b783-4358-8a34-901d2cf18e0e",
        "source": "Embedded",
        "id": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
        "tier": "NotSpecified"
    }
},


Enter fullscreen mode Exit fullscreen mode

instead of



"connectionReferences": {
    "shared_sharepointonline": {
        "runtimeSource": "embedded",
        "connection": {
            "connectionReferenceLogicalName": "crb89_sharedsharepointonline_684e9"
        },
        "api": {
            "name": "shared_sharepointonline"
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

Yep, that works!!!

create flow no connection references

It creates a non connection reference connection.

connection

If you can create legacy connections then you can create a flow with just Basic User

App calls Flow

I looked into if you could see any flows that you have access through a app (so the app calls the flow). Good news on this front, for both Solution aware and non solution apps/flows, you cant see the flow or logs. This is the same for both on behalf and owner connections.

cant access flow from app

Although you have permission to call the flow but you have no ability to see the flow or its logs, let alone edit it

Read Environment Variables

Variables are stored in 2 tables, Definition (name and type) and Value (the actual value in the variable). Checking the permissions for the tables shows that Basic User has full read access.

read all environment variables

Good news they can't edit them, but it does mean we can see every environment variable in the environment.

all environment variable values

Environment variables are public to all Basic Users

App shared

I know this is Power Automate but as a bonus what about Power Apps? With flows the flow owner could share the flow and the new maker can make changes without the right license. What about with apps. Well if you share edit access they can open and edit the app, but good news, they cant save any changes.

app cant save changes

But that's only non solution apps, solution aware apps are even better, you cant even open it.

cant open app

Even if shared ownership you cant save edits to Power Apps without maker permissions


Learnings

Because the Basic security role gives the ability to CRUD your own records it means that its only the UI that is stopping you. The maker role gives access to additional tables that are generally needed, but there are workarounds to work out of just the workflows table. I understand that the Basic Role may require read access to the workflow table (Instant Cloud Flows), but whey give them create rights? This does not feel like PoLP (The principle of least privilege).
And if you really want to give edit rights (to turn flows on off etc), then there should be column level security on the clientdata field (where the flow definition is stored).

Additionally it feels like we need a 'shared with' with permission, so that we can block records being shared with the user (The 'share' permission allows you to share, 'shared with' allows you to receive that share).

The connection reference table is our one key to stopping a Basic User creating a flow in an unapproved environment, but unfortunately you can use legacy connections within Dataverse (bypassing that key).

We know Environment Variables are public, do not store anything confidential in there (that could have impact on email address/contact numbers stored for notifications).

And finally apps are done right, you have the minimum permissions needed and thats for both the app and connected flows.

How to Protect your Environments

So what can we do to protect our enviroments. Well the good news is this is limited to creating/editing flows only. Data can't be accessed unless explicit sharing, and they still need a Basic User role (except in those legacy environments). But it still allows bypassing controls, so you should:

  • Switch to Dataverse environments, at least that forces everyone to require a Basic User license
  • Purge all of a users data when they lose access (especially connection references)
  • Train developers not to share flows (use repository process instead)
  • Secure developer environments with a security group where possible
  • Don't give out Basic Security Role without consideration
  • Use 'Block unmanaged customizations' in Test/Prod so no one can edit (managed is not enough as you can bypass it with solution layers)

And the basics:

  • Don't give developers access to prod, use service accounts/spn's
  • Monitor your flows, check for unapproved flow owners

And what about Microsoft, well they could:

  • Remove Create rights for Basic User from workflows table
  • Add column level security to clientdata field
  • Get Create new canvas apps and cloud flows in Dataverse solutions out of preview and into GA
  • Add controls on sharing

Top comments (1)

Collapse
 
balagmadhu profile image
Bala Madhusoodhanan

Thank you for the thorough explanation...Specially the fence analogy