Platform Operating Model: Defining Who Owns What in Azure

Post 1 introduced the idea of the Platform Operating Model with service tiers, platform-owned, shared responsibility, workload-owned with guardrails, and the shared operating model that sits behind them. This post is where that gets specific. If you’re defining service tiers when designing your landing zone, here’s what that actually looks like, layer by layer, and what you need to write down for each one. Including the layers where “platform team or workload team” isn’t the right question, because there’s a third team in the room.

Ownership isn’t access

Before going layer by layer, one distinction that holds the rest of this together: ownership and access aren’t the same thing, and conflating them is where a lot of these ambiguities start.

A workload team may have Contributor rights over a resource because they need to operate it day to day. That doesn’t make them accountable for its lifecycle, architecture or compliance. Likewise, a platform team may own a service they rarely touch directly because their responsibility is ensuring it remains operable for everyone else, not because they’re the ones configuring it week to week.

Access answers “who can change this.” Ownership answers “who’s accountable when it goes wrong, or when it needs to change.” They usually sit with the same team. When they don’t, and they often don’t for exactly the shared and cross-cutting layers this post covers, that gap is where the ambiguity actually lives.

Connectivity and the management group hierarchy

Start with the layer where there’s the least argument. Your management group structure, hub networking, core policy assignments, these are platform-owned, full stop. Nobody outside the platform team should have write access, because nobody outside the platform team should need it. This is the anchor point for everything else, the layer where “platform-owned” means exactly what it sounds like.

The guidance here is short because the layer is simple: enforce it with RBAC, not with convention. If a workload team can technically write to your hub VNet and simply doesn’t, that’s not platform-owned, that’s platform-owned until someone is under enough pressure to try.

Identity

Identity is where the tier looks simple on paper and isn’t in practice, partly because the two-party model breaks down here first.

Most organisations of any size have a dedicated identity team, and often a separate security function, both of whom have legitimate authority over this layer. Entra ID, conditional access, PIM, these frequently aren’t the platform team’s to own at all. They belong to identity, and the platform team consumes them. That’s a third party in a model that only had two boxes, and it’s why identity ownership questions so often end in a meeting rather than an answer.

App registrations are where it bites. The workload team creates one so their application can authenticate. The identity team owns the tenant it lives in. The platform team owns the landing zone the application runs in. The security team owns the standard that says credentials must rotate. Four parties with a stake, and Post 1’s expired client secret is what happens when all four assume one of the others is watching.

What to actually do about it: name the accountable team per object type, not per layer. “Identity is owned by the identity team” is too coarse to be useful. “App registrations for workload applications are created by workload teams, against a standard set by the identity team, with expiry monitored by the platform team” is specific enough that a gap becomes visible. Decide whether workload teams can create registrations at all, or whether they request them. Both are defensible. What isn’t defensible is leaving it open and assuming someone is tracking the result. If teams can self-serve, record an owner against every registration and surface expiry before it happens, not after. If they can’t, make the request path fast enough that people don’t route around it.

The gap nobody plans for

There’s a structural reason identity and security ownership gets messy, and it has nothing to do with anyone being bad at their job.

Platform teams are usually cloud native. Many were formed for the cloud programme, hired for cloud skills, or grew out of the people who volunteered to learn it first. They think in subscriptions, policy, identity as a control plane, and infrastructure as code.

Identity and security teams usually aren’t, and often can’t be. They carry the whole estate. Their remit didn’t start when the Azure tenant did and won’t end when the last on-prem workload is decommissioned. They’re operating a hybrid reality where Active Directory and Entra both matter, where the security standard has to cover both, and where the cloud is one of several environments they’re accountable for rather than the only one.

That’s not a knowledge gap on their side, it’s a scope difference. But it does create a real gap in the middle: the platform team has depth in a specific environment, the security and identity teams have breadth across all of them, and the questions that fall between the two are exactly the ownership questions this post is about.

The mistake platform teams make here is assuming the fix is to take over. Cloud is the platform team’s specialism, therefore cloud security decisions should be theirs to make, therefore the fastest path is to decide it themselves and inform everyone afterwards. It’s an understandable instinct, especially under delivery pressure, and it’s wrong in a way that costs you later.

The platform team’s role is to guide, assist and govern. Not to define risk, dictate standards or make risk acceptance decisions

Guide means being the team that explains how a control works in Azure, what the practical options are, and what each one costs operationally, so that the security team can make a properly informed decision. Assist means doing the implementation work and providing the evidence, rather than expecting a security team to learn a new platform’s tooling to verify their own standard. Govern means enforcing what was agreed, consistently, and surfacing when it stops holding.

What it doesn’t mean is deciding what level of risk the organisation accepts. That’s not the platform team’s call however deep their Azure knowledge is, and a platform team that starts making it has taken on accountability it can’t actually carry.

Practically, this changes how you write things down. If your ownership matrix says the platform team owns a security control, be clear about whether that means they defined it or they enforce it. Those are different jobs, and the gap between cloud-native depth and hybrid breadth is exactly where they get conflated.

Who owns security?

This question gets asked as if it has one answer, and it doesn’t, which is why it keeps getting asked.

Where it works, the split looks like this. The security function defines what good looks like: encryption requirements, credential lifetimes, network exposure standards, what has to be logged and for how long. The platform team translates that into enforced technical controls, Azure Policy, RBAC, network topology, and reports back on where the estate actually stands. Security owns the standard and the risk acceptance. Platform owns the enforcement mechanism and the evidence.

Two things break this in practice.

The first is when the security team has no visibility into the platform except through audit. If the only time security learns about the state of the estate is a quarterly report or a pen test, they’ll write standards disconnected from what’s actually operable, and the platform team will spend their time explaining why a control isn’t feasible instead of implementing it. Give security teams read access to the compliance data continuously, not periodically.

The second is Defender for Cloud, or whatever your equivalent is. It sits awkwardly between the two, generating findings that are security’s domain to interpret and platform’s domain to fix, usually with no agreement on who triages the queue. Someone has to own that triage. If nobody does, the findings accumulate until the number is large enough that the number itself becomes the problem, and then everyone agrees it’s someone else’s.

The practical version: put security requirements in the same place as the ownership matrix. If a control is required, record which team defined it, which team enforces it, and which team gets the alert when it fails. Three columns, and most security ownership arguments stop being arguments.

Management: policy, monitoring, patching

This is the layer where shared responsibility does the most work, and where it breaks down the most often. Platform team sets the baseline, workload team operates inside it, and the seams between the two are where things go quiet.

Policy exemptions are the clearest version of this I see, repeatedly. A workload team needs an exception to a platform policy, usually urgent, usually framed as “just for now.” The platform team grants it to unblock them, because refusing a live incident-adjacent request isn’t a great look, and there isn’t always time to build the proper conditional path. No expiry date gets set. No review cycle gets attached. No ticket exists to revisit it.

Months later, nobody remembers why the exemption exists, whether the reason still applies, or whose job it was to check. It sits there, quietly making the baseline slightly less enforced, for a workload nobody’s actively tracking against it anymore. The tier hasn’t changed on paper, the platform team still “owns” the policy layer, but ownership without a review mechanism isn’t really ownership, it’s just where the responsibility was left last.

The fix is unglamorous and it works: every exemption gets an expiry date at the point it’s granted, and no exemption gets granted without one. Azure Policy exemptions support an expiry natively, so this is a process decision rather than a tooling problem. Pair it with a standing review, monthly or quarterly, where the list of active exemptions gets looked at by someone whose job it is to ask whether each one still needs to exist. An exemption that expires and gets renewed deliberately is fine. An exemption that never expires is a policy you’ve quietly stopped enforcing.

Shared workload resources

This is the layer that causes the most confusion, and it’s the one most ownership models skip entirely.

Across workload subscriptions, you almost certainly run shared infrastructure to control cost and avoid duplicating resources for every project. A single Front Door in front of multiple solutions rather than one per application. An elastic pool instead of dozens of individual databases each carrying their own server and compute. Shared App Service Plans hosting the dev and test web apps for several teams. The networking components that every workload in that subscription depends on.

All of these should sit with the platform team. They’re shared infrastructure, they have cross-workload blast radius, and no single workload team is in a position to make decisions about them. But they cross into workload territory constantly, because workload teams are the ones configuring routes on that Front Door, adding databases to that elastic pool, and deploying apps onto that plan.

That’s a genuinely different problem to the other layers, and it needs different guidance. Three things to get right:

Separate the resource from what’s deployed onto it. The platform team owns the Front Door instance, its WAF policy, its capacity and its availability. The workload team owns their own routes and origins within it. The platform team owns the elastic pool and its compute allocation. The workload team owns the databases they place in it. Draw the line at the container, not the contents, and write down which side of it every configurable thing sits on.

Decide who owns capacity, explicitly. This is the failure mode nobody plans for. A shared App Service Plan or elastic pool has finite compute, and it’s shared. When one team’s workload starts consuming disproportionately, the impact lands on teams who did nothing wrong and have no visibility into why their performance changed. If the platform team owns capacity, they need monitoring at the shared resource level, not just per-application, and they need a threshold at which they act. If nobody owns capacity, the first sign of a problem is a workload team raising an incident about someone else’s application.

Control the change path into shared resources. A workload team adding a route to a shared Front Door is making a change to platform-owned infrastructure. That doesn’t mean it needs a change board, but it does mean it shouldn’t happen through portal access nobody’s tracking. Route it through IaC and pull requests so the platform team can see what landed on their resource and when, which also means the change is recoverable when it turns out to be the cause of something.

The general principle: a shared resource is platform-owned, but the platform team’s job is to make workload teams’ use of it safe and self-service, not to become a ticket queue standing between teams and their own deployments.

Workload subscriptions and application infrastructure

The least controversial layer, and deliberately so. This is workload-owned, with the platform team enforcing guardrails through policy rather than doing the operational work themselves. Application code, app-tier configuration, workload-specific resources, day-to-day operation of these belongs to the team that owns the application.

The platform team’s job here isn’t to run it, it’s to make sure it can’t drift outside the guardrails without something noticing. Which means the guardrails have to actually be enforced. A guardrail that exists as documentation is a suggestion, and suggestions do not survive delivery pressure.

The ownership matrix

Putting the layers against the three tiers gives you something closer to a working reference than a set of examples:

Layer Default tier Where it commonly breaks
Connectivity / management groups Platform-owned Rarely, this boundary tends to hold
Core policy assignments Platform-owned Exemptions granted without expiry or review
Entra ID tenant configuration Identity team owned, platform consumed Platform team assumed to own it, identity team assumed to be watching
App registrations (workload apps) Workload-created, identity standard, platform-monitored No single owner recorded, expiry goes unwatched
Security standards and risk acceptance Security team owned Written without platform context, or platform team making risk calls by default
Security control enforcement Platform-owned Standard exists, enforcement doesn’t, gap only visible at audit
Defender for Cloud findings Shared, needs explicit triage owner Nobody owns the queue, findings accumulate until the backlog is the problem
Shared Front Door / WAF Platform-owned, workload-configured Route and origin changes made without platform visibility
Elastic pools, shared App Service Plans Platform-owned, workload-consumed Capacity ownership undefined, noisy neighbour surfaces as someone else’s incident
Workload subscription networking Platform-owned Workload teams need changes faster than the platform team can deliver them
AVD and shared platform services Shared responsibility Image and network platform-owned, assignment and packages workload-owned, boundary undocumented
Monitoring and alerting Shared responsibility Workload team mutes noisy alerts without telling platform team, visibility silently lost
Application infrastructure Workload-owned, with guardrails Guardrails not enforced consistently, or standing portal access granted “just in case”

This is a starting point, not a template to copy without thinking. Your landing zone, your org structure and your risk appetite will all shift where some of these sit.

What matters more than where each row lands is that every row has an answer at all, and that the answer is recorded somewhere a new starter can find it.

Where the matrix isn’t enough

A matrix assumes the tier was decided deliberately. Not everything gets there by design. Post 1’s AVD example, some pools domain-joined, some Entra-joined, no documentation of which or why, is what happens when a layer was built as if it were workload-owned and became platform-owned by circumstance, the moment the person who understood it left. No exemption was granted, no decision was made, the tier just changed underneath everyone without anyone deciding it should.

The matrix tells you where things should sit. It doesn’t catch the layer that’s quietly moved without anyone updating the map.

What holds this together

None of this matters if the mapping goes stale. A tier decided at design time and never revisited is exactly as fragile as no tier at all, just with better documentation of the moment it stopped being true.

If you take one operational habit from this post, make it the exemption expiry. It’s the smallest change on this list, it takes an afternoon to implement, and it turns the most common silent ownership failure into something that surfaces on a schedule instead of during an audit.

But the habit only matters because of what it’s protecting against. Every production incident eventually becomes an ownership question.

Sometimes it’s obvious. Sometimes it’s buried beneath layers of technology and organisational boundaries. Either way, someone eventually asks, “Who was supposed to be looking after this?”

If your operating model can’t answer that question before the incident happens, it probably won’t answer it afterwards either.

Next time we’ll look at what happens when operating models drift over time, and why the platform you designed slowly becomes different from the platform you’re actually running.

Your subscription could not be saved. Please try again.
Your subscription to deniscooper.co.uk has been successful.

Join Cloud Engineers Who Build Smarter on Azure

Free checklists, practical guides and the latest posts — built for cloud engineers working with Azure and Terraform.

Leave a Comment