EPPC26 Session Recap — Filip Kocevski
European Power Platform Conference, Copenhagen | Thursday, July 2, 2026 | Track: Power Platform | Level 300
Filip Kocevski opened with numbers, not opinions: per the 2025 Gartner report and the New South Benchmark report, 69% of enterprises are still running critical, complex data on legacy systems — and this isn’t a temporary transition state. It’s happening in HR, supply chain, finance, everywhere at once, all the time. The session’s real subject wasn’t Power Platform or Azure individually — it was the layer most solutions skip between them, and what skipping it actually costs.
What Skipping the Integration Layer Actually Costs
Kocevski’s opening picture: an enterprise with, say, 400 Power Automate flows connected point-to-point directly to a legacy system. Change one thing in that legacy system, and someone has to go check all 400 flows to find out which ones broke. That’s spaghetti architecture, and it compounds into a specific, named list of failure modes he’s hit repeatedly:
- No visibility. If your strategy for a legacy-system change is “check every flow one by one,” his line was blunt: “you don’t have architecture, you have hope.”
- Security gaps. Legacy systems often authenticate with something thin — IP whitelisting, basic auth. Connect Power Platform directly to that, and Power Platform inherits the same exposure the legacy system already has.
- Connector limits hit at scale. Every Power Platform connector has a per-request limit. When complex business logic runs directly against connectors at enterprise volume, the fix isn’t a bigger license — it’s not doing the heavy lifting in the connector layer at all.
- Duplicate logic, no source of truth. Ask where the logic for “convert opportunity to lead” actually lives, and if nobody can give you one clean answer, that’s the tell.
And the cost isn’t abstract: in Kocevski’s numbers, the majority of the annual cost of ungoverned integration comes down to exactly this — people manually walking flow by flow, connector by connector, trying to find out what broke, instead of that information being sitting in one place already.
The Unified Integration Model
The one diagram Kocevski asked the room to take away if they took away nothing else: three layers, not two.
- Citizen layer — Power Platform, where citizen developers and Canvas apps live.
- System layer — the legacy systems: on-prem databases, SAP, ERP, whatever’s underneath.
- Integration layer, in between — API Management, Service Bus, Event Grid. His analogy: think of it as the bodyguard at the club door, checking authentication and ID before anything gets through, deciding what’s allowed in and what gets turned away.
Walked through with a concrete example: a citizen submits a purchase order approval through a Canvas app. That’s a 30-second job, and it’s all the Power Platform side needs to do — the API Management layer authenticates the request, transforms the JSON into whatever format the legacy system actually needs, and hands it to a Service Bus queue with retries and a dead-letter queue built in. A Logic App picks it up and applies the routing logic — auto-approve under $10,000, escalate to a finance manager above it — and only then does anything get written to the legacy system. Neither side has to know what format the other one speaks. The system layer doesn’t know it’s connected to a Power App; the Power App doesn’t know or care what the legacy system needs to receive.
Four Patterns That Actually Implement This
- API Facade — put API Management in front of everything: authentication, versioning, and error handling all resolved before a request goes anywhere near the legacy system.
- Service Bus Choreography — the async workhorse. Retries handle a legacy system that’s temporarily offline; dead-letter queues catch anything that still didn’t make it, so nothing silently disappears — it waits for someone to investigate why.
- Custom Connector Bridge — wrap authentication, schema, and throttling limits into a custom connector, so Power Platform talks to the integration layer through something purpose-built rather than an ad hoc HTTP call.
- Event-Driven Triggers — Event Grid catches legacy-system events (create, update, assign) and can fan a single event out to multiple independent consumers — a Logic App and an Azure Function, say — so that if one fails, the other isn’t dragged down with it.
Four Strategies for the Legacy System Itself, Ranked by Risk
This is where the talk got genuinely practical: which strategy to use depends entirely on one question — where is this legacy system on its end-of-life trajectory?
- Wrap — the easiest to implement: put an API Management layer in front and move on. It’s also why most enterprises default here without necessarily meaning to. The catch: it keeps the legacy system alive. Right choice if the system still has life left and you have time; wrong choice if the actual goal is killing it.
- Bridge — connecting directly through a Hybrid Data Gateway, no middleware at all. Kocevski was explicit that he discourages this — it’s slow, heavily limited, and it’s the direct-connection risk described above. He includes it only because it exists and some of his clients have used it when there was genuinely no alternative.
- Strangle — his restaurant analogy: an old kitchen and a new one, slowly moving dishes from one to the other — start with the fast food, work up to the Michelin-star dishes in the new kitchen, until the old one has nothing left to serve and gets shut down. Migrate functionality to the cloud-native side piece by piece, at your own pace. Low risk, appropriate when the legacy system is nearing end-of-life but there’s still runway.
- Replace — full rip-and-replace, delete the old, stand up the cloud-native system from scratch. High risk, and only sound with solid documentation and planning up front — but sometimes it’s the only option when a system needs to die immediately, and Kocevski has run it successfully on real projects.
Governance and Security, from Someone Who Builds This (Not Audits It)
Kocevski was upfront that he’s not a security specialist — this was the practitioner’s checklist, the stuff he’s had to get right to keep his own solutions standing:
- Environment strategy: Dev, UAT, Production, kept separate — never develop directly against UAT or Production.
- DLP policies that keep business and non-business connectors apart in the same flow, since mixing them is exactly how classified business data ends up somewhere it was never supposed to go.
- No secrets in code or in Power Automate environment variables — managed identities for Azure resources, or Azure Key Vault for anything that needs to be a secret. Entra ID handles the rest.
- Observability from day one — Application Insights, with correlation IDs that let you trace a single failure through everything it touched, including whatever an Azure Function did when a Logic App called it. Trying to run genuinely complex logic purely inside Power Automate flows, with no tracing behind it, is a good way to overload the environment the moment something starts failing.
Takeaways
- Always start with the integration layer — it’s easy to add and just as easy to remove, which is exactly why it should be the default rather than an afterthought.
- Never connect Power Automate directly to a legacy system. If you do, you’re running the discouraged Bridge pattern, and you own the security exposure that comes with it.
- Pick your legacy strategy — Wrap, Strangle, or Replace — based on the system’s actual end-of-life trajectory, your available time, and your resources. There’s no universally correct choice, only a correct one for your specific system’s timeline.
- Governance isn’t optional, and neither is Azure middleware. Kocevski’s own framing: the annual cost of skipping both is bigger than the cost of building them in from the start.
- Build for observability from day one — Application Insights and correlation IDs, not a plan to add logging later once something’s already on fire.
Session: “Unified Integrations Done Right: Power Platform, Azure, and Legacy Systems Working Together” — EPPC26, Copenhagen, July 2, 2026
Presenter: Filip Kocevski (Solutionade)