The security dilemma of low-code

Can we just trust how vendors are handling the many keys handed out to them?

When I started working with Microsoft business applications in early 2000’s, there was a clear line between what a functional consultant like me was able to achieve & what was the domain of programmers. Today, the citizen developer revolution has blurred those lines completely. As part of this paradigm shift, alongside the cloud revolution, the role of security in business app development has become much more prominent.

Those of us who have worked on the consulting side, convincing customers to put their data and key business processes into Microsoft’s cloud, we may have gotten used to the idea of saying “it’s secure by design, because it’s from MSFT”. I do still believe that this is probably the one ecosystem with most capabilities to fight security threats at scale. Yet as low-code becomes mainstream and with Power Platform capturing the biggest slice of that pie, it’s going to get adopted by bad actors out there, too.

Today I’ll share my perspectives on why MS BizApps security landscape has grown much broader than before. I’ll also reference some examples of what security professionals see when they examine Power Platform in detail. In particular, the issues in how connections created by makers and users are handled in the product.

“One place for all data” vs. “one platform for any API”

In the early days, what was then called XRM and is now Microsoft Dataverse (with a brief chapter as CDS) provided tech savvy business analysts with a flexible and configurable database. When I saw the first tech demo of MS CRM 3.0 and its customization UI that allowed creating new tables (then called entities) with the click of a mouse button, my mind was blown - for real. That experience is what has lead me to working with Power Platform today.

Still, it was all just a single box of data. Building and extending CRM apps and other apps was about working within the given database. If data needed to move in our out, that was the moment you asked the pro-devs about “how could we build this integration?” Most often, this phase was both slow and expensive to implement. Whether using proprietary code or scary tools like MS BizTalk, integration was something that took us firmly away from the business user’s domain, over to the “Real IT” side of the fence.

That all changed with Power Platform. More precisely, it changed when the previously separate PowerApps (without a space) and Microsoft Flow were put under the same product umbrella as Dynamics 365 in 2018. It was a big win for us XRM folks to see the vision of “one platform, many applications” become an actual Microsoft product.

Power Apps or Power Automate (formerly Flow) didn’t have a database. OK, they had a crappy “CDS V1” that was swiftly swept under the rug once XRM took over the data platform side. But the database was never the selling point. The whole beauty of Power Apps and Automate was connectors. This enabled talking with any data source, as long as there’s a REST API of some sort available for it.

In a way, it was the exact opposite of how Dynamics 365 style apps worked, where building one physical database to store and manage all the relevant business data was the goal. The implications from this are so profound that we haven’t seen the 2 types of Power Apps, canvas apps vs. model-driven apps, merge in any meaningful way 6 years after these new product names were invented. Building apps on top of APIs (canvas) is just very different than generating apps from your data model (model-driven).

Today, the ability to create new database tables via GUI may not be the mind-blowing experience for business users like it was to me in 2005. For the newcomers, that killer feature will likely be the ability to make different cloud systems talk with each other without writing a line of code. Turning APIs into something citizen developers can work with directly is the magic dust of Power Platform.

Handing out the keys to your credentials

Canvas apps and cloud flows are how most people start with Power Platform. This is true for both citizen developers as well as professional developers, given that the CRM & ERP world of Dynamics 365 remains a business niche of its own - compared to mainstream tech like Office 365 / Microsoft 365. The vast majority of apps and automations outside MS 1st party products is therefore leveraging connectors.

So, if these fancy connectors are now making APIs simple enough for citizen developers to use in their apps and automations, what’s really the secret sauce? How did the once so tedious task of integrating business data across different systems become so easy? Was it made possible just because everything moved to cloud? My personal answer would be both “yes” and “no”.

The “yes” part is true in the sense that the SaaS vendors have indeed invested in making it as easy as possible for business users to login to their cloud apps - and remain logged in. Lowering the barrier to access the app is pretty crucial in driving up the usage metrics, getting users hooked on the free/trial tier, convincing them to purchase a subscription with their credit card, put it in as a company expense… You know, the classic Consumerization of IT trend that was a buzzword back when iPhones and iPads initially started sneaking inside the enterprises.

This leads us to the “no” part. Because in a way, low-code/no-code is riding on that same technical wave that gave us cloud apps and shadow IT at the workplace. It’s just that instead of a single user logging into a SaaS service through a username + password combo typed into a web form, now it is being done at scale, via platforms specifically designed to automate it. Note that this is not about RPA style GUI level automation. Instead, the users grant the low-code platforms a right to impersonate them, thanks to what OAuth makes possible.

The concept has been described as Credential Sharing As A Service in the excellent talk by Michael Bargury. I encourage you to check out the video / slides from OWASP 2023 Global AppSec Dublin. Seeing how the concept of low-code/no-code apps is presented to an audience of security professionals is highly interesting for a Power Platform professionals to observe. Because it provides a perspective on things that we may have not paid much attention to.

“Connections are refresh tokens.” This is something we may not be actively thinking about when working with Power Platform connectors. We don’t run into the token term at all when working via the Microsoft provided user interfaces, whether it is as app makers, admins or end users. But what are these tokens anyway?

Refresh tokens enhance security and improve the user experience by allowing longer-lived sessions in a secure manner. They are particularly useful in scenarios where access tokens expire quickly. The refresh token can be used to securely request new access tokens, thus ensuring that the user or the application doesn't frequently need to re-authenticate.

That former paragraph was what ChatGPT had to say about it. In reality, when we leverage connectors and creation connections in our Power Platform solutions, there’s a bunch of different tokens flying around in the cloud. Low-code makers don’t need to understand any of the details since the underlying connectors architecture built by Microsoft handles that. Behind the scenes, Azure API Management and other components make it just work.

Considering how much effort may be spent on implementing OAuth support in traditional custom software projects, the perceived ease of using connectors in low-code app development is surely a big win for Power Platform. With either public or custom connectors in place for the data sources needed, a citizen developer can just breeze through this part. Which leads to the number of connections created in the Microsoft 365 tenant to grow rapidly.

What’s the problem with Power Platform connections management?

First of all, we should remember that just because the maker happy path for adding new connections to apps is a breeze, that doesn’t mean it’s all just a walk in the park. Many Power Platform application developers and architects have surely faced struggles in trying to ensure connectors and connections are all nicely aligned across environments when dealing with Power Apps canvas app and Power Automate cloud flow ALM. Luckily the platform has matured massively on this front in the recent years.

Getting things connected (and remain connected) is one thing. Knowing what connections exist already is a whole different ballgame. I’ve been playing this game in the field of Power Platform governance for a few years now. I imagine that if there was the right way or the easy way to examine or monitor the connections, I would have learned it by now. In reality, it remains a mostly uncharted territory due to the limited visibility Microsoft provides to customers.

Connections are not attached to apps or flows directly, they are a separate construct. They are easy to create, hard to see, and very challenging to manage. One reason being that Power Platform has no mechanism to clean up old connections that are no longer used or have become broken. So, the connection data just piles up in the token store, causing even admin APIs to return errors as the volume grows.

That’s an admin concern for sure. The security concern falls more on the access side: who has been given access to these tokens and where are they being used? This is where the idea of Credential Sharing as a Service becomes a bit troubling. Because if establishing connections is easy, thanks to the UX built into Microsoft’s products, sharing them is super easy! The users building apps and automations might easily choose the “share with everyone” option when not knowing how to ensure that all their colleagues can use the new app they created. After all, they are all working in the same company, so why keep things secret within our internal systems?

In his blog/talk “All You Need Is Guest”, Michael Bargury demonstrates what the potential risk is with overshared connections. Namely the fact that Entra ID guest users are also in the “everyone” scope. For those who know about Power Platform governance in the real world, it is not at all uncommon to have all sorts of scary connectors (SQL Server, Azure blobs, HTTP) being leveraged in the Default environment where every licensed user has Environment Maker rights (by design). Including guests from outside your tenant, that can by default be invited to Teams for very valid collaboration scenarios. Which leads us to this being an issue.

“No problem, we’ve got proper DLP policies in place now for our Power Platform environments.” Nice, but what about everything that has been built before you planned your low-code platform governance model? Remember, the tokens aren’t cleared away by the system. Because one connection can be used in many apps and flows, it would take extra effort from the platform side to control this automatically.

What I had not known about Power Platform DLP policies is that they are applied only on the app/automation layer. “What other useful layer is there for connectors”, you might ask. The answer is the pile of tokens that are called connections, and which you can reference independently if you just modify the API Hub call in the browser. In the “Power Platform DLP Bypass via Copy-And-Paste” article you can see how the technique allows using a connection for a connector blocked by DLP. Because those DLP rules are not evaluated on the connection level in reality.

This feels… messy. Even if no malicious actor ever finds their way into leveraging the tokens (and how would you notice if they did?), I do not like the way they are handled. If a low-code platform vendor builds a place where all these keys to thousands of systems are collected from users, I’m expecting it to be systematically guarded and monitored.

How did it get so messy to begin with?

Michael calls the handling of connections/credentials “a fundamental design flaw” in Power Platform. But is it a bug or a feature? Without being a security professional, my perspective on this is leaning towards it all being an unavoidable result from the pressure to allow users and customers to use technology in a way that they want to. It’s not ideal, but if there had been no compromises made, probably there wouldn’t be much of a low-code product in place for a vendor today. Because the users would not have been able to create that first app or flow, independently from IT, to see the power of these platforms with their own eyes.

This isn’t specific to Microsoft when looking at the big picture. While the M365 guest features, Entra ID, Power Platform DLP, Azure API Management of course are technologies from Redmond, I bet the other big industry players in low-code/no-code face a similar dilemma in how to balance user empowerment vs. data protection. None of the others are covering as a broad a piece of the enterprise technology stack as Microsoft, though, which makes their situation different.

The primary target audience of low-code platforms is the business user. Therefore vendors will naturally shape their marketing message to underline the “do more with less” productivity mantra. Most product demo scripts will be about a lone citizen developer hero being able to single-handedly build an app in a few clicks (or chat with AI to generate it). They don’t show requesting for resources like service accounts or non-prod environments. There’s no evaluation of identity and access management strategies. You just pick a connector, point it to a business data source and design a wonderful app/automation on top of it.

If this experience wasn’t possible, adoption simply wouldn’t happen. That’s because especially with Power Platform, it’s all about the bottom-up movement of business users leveraging their O365/M365 subscription to solve problems that IT has failed to solve. The top-down part only comes afterwards, once the initial apps and flows have been built and the organization starts to realize some new governance guardrails are needed to protect users from themselves.

The new meaning of security in business applications

During the era in which I worked with CRM systems exclusively, there was in practice never a situation where the work of security researchers was relevant for me to dig deeper into. Once I stepped out into the broader Power Platform world, it required a change in perspective when it comes to security. Suddenly the world outside of the specific application matters a whole lot more.

When we are building a system that stores the business information inside a Dataverse database, the work in security model design is all about configuring the internal settings of the platform. Which security role can do what operations on which tables, how are business units and teams leveraged, where do we need exceptions like column level security or sharing. The specificity of Dynamics 365 CRM/CE security features always made it a challenging to explain the platform capabilities and map them into business requirements. Still, it was critical work for solution architecture design to succeed in projects.

Today it feels like we need to look both ways before crossing the security street. Both inside the system’s business logic, as well as outside where the surrounding environments, policies, user identities, tokens and other elements live. It’s a lot to tackle and I’m sure few people can comfortably discuss both the intricacies of Dataverse security models and the attack vectors for web applications in general.

The path towards more secure low-code solutions will thus require dialogue between professionals of different fields. It should ultimately be in everyone’s interest to raise awareness of how the platforms manage access to resources and data, and what gaps & risks can be identified. After all, we do want to get the business data away from random Excel sheets, cross-tenant email attachments, shadow IT apps and other places that are much harder to monitor and control than Power Platform.

Join the conversation

or to participate.