Logical isolation by default with a physical escape hatch, rather than a namespace and cluster per tenant. Forty tenants would otherwise mean forty Service Bus namespaces and forty scaling decisions, and the cost curve breaks long before the security argument does.
tenantId is part of every partition key, cache key, container name and message property. Isolation enforced in the data layer rather than in each query is the difference between a boundary and a code review convention.
Layer 4 is bought, not default. A tenant that needs a blast radius of one gets a dedicated namespace, node pool, container and Key Vault, and pays for it as a premium tier.
What each layer stops
Layer 1 stops a tenant acting as another: no tenant claim, no request. Layer 2 stops cross-tenant data access even given a bug in one query path. Layer 3 stops a noisy tenant starving others. Layer 4 stops a shared-infrastructure fault reaching a specific tenant.
Concurrency by tier — gold 500, silver 100, bronze 20 — makes fairness a commercial parameter rather than an engineering constant.
Per-tenant circuit breakers mean one tenant's failing downstream cannot open the circuit for everyone using that task type.
What is shared, stated plainly
Control plane pods, the AKS cluster, the Cosmos RU pool and the Monitor workspace are shared. A fault in any of them is a fault for every tenant, and no amount of layer 1 to 3 isolation changes that.
The Cosmos RU ceiling is shared, so an extreme tenant can consume autoscale headroom others expected. Per-tenant RU throttling is a V2 item; today it is monitored, not enforced.
The Monitor workspace is RBAC-filtered, not separated. A tenant requiring physically separated telemetry cannot be served by this model without layer 4.