Everyone has kubectl. That is the problem. Cluster-admin in three teams’ CI jobs means the landing zone identity model stopped at the API server door. The hub is clean. The subscription is tagged. Inside the cluster it is still Friday.
Draw the line the same way Deployment Model did: platform pipeline for the cluster; workload pipeline for the namespace. The spoke contract from Series 2 said platform owns seams and workloads own apps. AKS is where that contract gets a second control plane.
This is article five of Series 4.

Platform deploys
Platform owns anything that changes blast radius for every tenant of the cluster.
- Cluster and node pools, including version pins and outbound settings from the baseline
- Azure Policy assignments that target AKS and the Policy add-on behavior
- Shared ingress controller or gateway integration config
- Cluster-wide network policy defaults you are willing to support
- Observability agents and the workspace wiring you sized
- Namespace vending as a catalog item: create namespace, resource quotas, limit ranges, RBAC bindings for the app team deploy identity, network policy starter, allowed registry labels
Platform also owns the Terraform (or Bicep) that creates the Azure resources around the cluster: private DNS links, UDR association, budgets, diagnostic settings, role assignments for the cluster identities. That is still the landing zone pipeline. Kubectl does not replace it.
If a change requires editing the hub firewall, the shared private DNS zones, or a Deny policy that blocks a registry, that is a platform change request with canary discipline, not a namespace PR.
Workload deploys
Workloads own what makes their application real inside the namespace they were given.
- Deployments, Services, ConfigMaps, Jobs, CronJobs
- App-level NetworkPolicies that tighten the starter defaults
- Helm charts, Kustomize overlays, or GitOps application objects scoped to their namespace
- Workload identity bindings and federated credentials for their service accounts (within the Azure RBAC you allow)
- Horizontal pod autoscaling and PDB settings their charts need for upgrades
- App alert rules aimed at their telemetry workspace or tables
They do not own ClusterRoles that bind to cluster-admin, admission webhooks that mutate every namespace, CustomResourceDefinitions that redefine cluster behavior, or rewriting the shared ingress class for one app.
Azure resources in the workload subscription, storage, Key Vault, databases the app owns, still deploy through the workload pipeline with Contributor in that subscription, same as Series 2. The cluster namespace is an additional deploy target, not a replacement for Azure RBAC hygiene.
RBAC sketch that survives audit
Use Azure RBAC for Kubernetes authorization when you operate it, aligned with identity.
- Platform humans: Azure Kubernetes Service RBAC Cluster Admin via PIM for emergencies; day-to-day use a narrower admin role
- App team humans: namespace-scoped admin or edit equivalent, time-boxed if your culture allows
- CI workload identity: deploy to the namespace only, never cluster-admin in the pipeline variable group
- Read-only roles for on-call who need to see pods without shipping YAML
Standing kubeconfig files with full rights on laptops fail Series 3 audit questions. Prefer flows that issue short-lived creds after PIM, tied to Entra groups, with Kubernetes audit logs enabled to the platform workspace.
Map Entra groups to Azure role assignments the same way you map groups elsewhere in the landing zone. Do not invent a parallel access spreadsheet that only exists for AKS.
GitOps without giving away the cluster
If you use Flux or Argo CD, platform owns the controllers, the install, the upgrade, and the cluster-wide root that may only point at platform-approved sources. Apps own their application objects in their repo, targeting their namespace.
Do not give every app repo the ability to rewrite cluster-wide sources, add ClusterRoleBindings, or install operators into kube-system. GitOps is automation. It is not a substitute for the deploy split. A pipeline that applies anything in any namespace is the same as cluster-admin with extra steps.
Pin controller versions. Treat GitOps upgrades like addon upgrades. An unowned Argo install is tomorrow’s blocked Kubernetes minor.
Namespace vending is the catalog answer
The ticket that should die: “Platform, deploy my chart.” That is Series 2 platform-as-product failure wearing Helm.
Ship a catalog item instead:
- Request namespace + environment
- Platform pipeline creates namespace, quotas, RBAC, network starter, identity placeholders
- App team receives pipeline credentials or federated deploy identity scoped to that namespace
- Starter chart or cookiecutter repo shows the required labels, probes, resource limits, and PDB
- Optional: bootstrap a repo with CI that already authenticates to the cluster namespace
Measure intake. If half of platform tickets are still “please helm upgrade for us,” the catalog is invisible or the RBAC is too tight for teams to work. Fix the product. Do not staff a human Helm desk forever.
Publish the SLA: how long namespace vending takes, what the requester must provide (Owner, Application, cost center), and what is out of scope (cluster-wide operators, public LoadBalancer Services in prod).
CI identity that can only touch one namespace
Workload CI should authenticate with a principal that Kubernetes authorizes for one namespace, not with a shared deploy identity that can reach every tenant of the cluster. Federation from the pipeline to Entra, then Azure RBAC for Kubernetes scoped to the namespace, is the pattern that survives audit.
I keep finding one service principal in a variable group with cluster-admin “so any team can onboard faster.” That principal is a shared blast radius with a YAML costume. Rotate it into per-namespace deploy identities during the same sprint you vend the namespace. Convenience that outlives the onboarding week becomes permanent risk.
Store kubeconfig nowhere long-lived. Prefer kubelogin / Azure CLI flows that mint short-lived tokens. If a pipeline logs a full admin kubeconfig into build artifacts, treat that as a secrets incident, not a CI quirk.
Kubectl for humans
PIM-activated access, audited, time-boxed. Pair with Azure Activity and Kubernetes audit logs shipping to the platform workspace (logging). If someone changed a ClusterRole at 1 a.m., you need more than a Slack message saying it was fine.
Break-glass to cluster-admin follows article eight: ticket, scribe, time limit, follow-up PR for anything that must remain.
Read access in the Azure portal for the cluster resource is fine. Contributor on the cluster resource for app humans is how node pools get resized outside Terraform. Keep Azure-level and Kubernetes-level permissions consistent with the split.
Two pipelines, same as the landing zone
Platform service principal applies cluster modules at the management group or platform subscription scope it already uses. Workload service principal is Contributor in the app subscription for Azure resources and namespace deploy on the cluster, nothing that edits the hub firewall or the shared ingress install.
I keep finding one mega-pipeline that creates the cluster and also ships every team’s chart because “it was faster.” It works until a hotfix needs to ship while the platform apply is locked, and then someone downloads admin kubeconfig. Draw the line before that story writes itself.
Remote state stays split too. Platform state for the cluster. Workload state for app Azure resources and, if you store Kubernetes manifests in Terraform at all, scoped modules that cannot touch cluster-wide objects. Most teams are happier with Helm/GitOps for app manifests and Terraform for Azure. Pick one app path and document it.
Hotfix path that does not become the real process
Prod will break outside business hours. Document the hotfix path: who can approve namespace-scoped deploy outside the normal promotion gates, how evidence is captured, and how the change returns to git before the next business day.
A hotfix that never becomes a PR is how standing objects appear that Terraform and Helm no longer describe. Platform break-glass for the cluster follows the same rule with a stricter ticket. App hotfix for a Deployment should not require platform to helm-upgrade on the team’s behalf. If it does, namespace RBAC or the catalog is still wrong.
Environments and promotion
Nonprod and prod are different namespaces, usually different clusters, sometimes different subscriptions. Promotion is image digest and config change through the workload pipeline, not kubectl copy from staging to prod.
Platform may vend matching namespace names across environments. Platform does not copy Secrets between clusters. Workload identity federation is per cluster issuer. Your promotion docs should say that explicitly so someone does not “fix” prod with a staging kubeconfig.
Canary deploys inside a namespace (two Deployments, traffic split at ingress) stay workload-owned. Canary node pools during upgrades stay platform-owned (article eight). Keep those words from collapsing into one “canary” ticket.
Operators and CRDs
Cluster-scoped operators are platform products or they are rejected. An app team that needs a CRD installs it only if the catalog lists that operator, with an owner and an upgrade story. Silent helm install of operators into shared clusters is how article two’s thin baseline dies.
If a vendor requires an operator, isolate it: dedicated cluster or dedicated namespace with documented privileges, never default cluster-admin for the vendor chart.
Anti-patterns
- Cluster-admin kubeconfig in the shared variable library
- App teams with Owner on the node resource group
- Platform engineers manually helm-upgrading prod charts every Friday
- GitOps root that trusts every repo in the org
- “Break-glass” users who never leave the admin group
- One pipeline identity that can deploy every namespace “for convenience”
- Promoting by
kubectl apply -ffrom a laptop after a successful CI run
Next: guardrails on the cluster, Azure Policy for AKS, pod security, image provenance, and exemptions with expiry.
Randy Bordeaux
Azure Trainer | Veteran | Engineer
Helping IT professionals grow through cloud, leadership, and shared knowledge.


