skip to content

Should tenants own Kyverno Policy objects in their own namespaces on a shared cluster?

level: principalimportance: nice to knowfreq 31%

answer

  1. the constraint model is additive, not overriding
  2. namespace boundary is the object, not the match block
  3. grant the namespaced verb, never the cluster one
  4. who gets paged when their rule fires
  5. delegation needs a documented break-glass

basics

~20 s

Usually yes, with limits. A namespaced Kyverno Policy can only add constraints inside its own namespace and cannot relax a platform ClusterPolicy, so the security downside is small. The real cost is operational: tenants can block themselves.

solid answer

~50 s

The security argument for delegation is strong because Kyverno's model is additive: every matching rule from every policy is evaluated, so a tenant's namespaced `Policy` can only make their own namespace stricter. It cannot cancel a platform `ClusterPolicy`, cannot reach another tenant, and cannot match cluster-scoped kinds. What you are actually delegating is *operational* risk. A tenant rule can block their own controllers, add admission latency and fill policy reports the platform team is on call for — and when their Deployment is rejected at 5pm, the first page still comes to the platform team. So grant `create` on `Policy` in their namespace only, never `ClusterPolicy`; require the object to arrive through their reviewed GitOps repo; make the denial message name the owning policy so the page routes correctly; and keep a documented way for the platform to disable a tenant policy that is causing an outage.

go deeper

for a junior

Know the fact underneath the debate: a namespaced Kyverno Policy only affects resources in its own namespace. That single boundary is what makes handing one to a team thinkable at all.

for a middle

Explain why the model is additive — every matching rule from every policy is evaluated with no precedence — and what that means for a tenant rule, which can only make its own namespace stricter.

for a senior

Demonstrate the operational side: tenant rules can block the tenant's own controllers, they consume shared admission and reporting budget, and denial messages must name the policy so the page routes to the right team.

for a principal

Own the delegation contract. Separate the authorization risk, which is low and provable, from the on-call risk, which is real; decide the RBAC boundary, the review path, who is paged, and the break-glass — and be willing to say no when the tenant cannot operate it.

## The question behind the question "Can tenants write their own policies?" sounds like an RBAC question and is really an on-call question. The safety analysis is easy; the operations are not. ## Why delegation is safe: the model is additive Kyverno evaluates **every** matching rule from **every** installed policy for a given request. There is no precedence, no override, no allow rule that cancels a deny. A tenant's namespaced `Policy` therefore has exactly one power: it can add constraints to resources in its own namespace. Concretely, a tenant-owned `Policy` **cannot**: - relax, shadow or exempt anything in a platform `ClusterPolicy` that also matches their workloads; - reach resources in another namespace, however its match block is written; - match cluster-scoped kinds such as Namespace, ClusterRole or CustomResourceDefinition; - change the platform's exclusion list, or add itself to one. That is a genuinely rare property in platform delegation: the failure mode of a tenant writing a bad policy is that the *tenant* is worse off, not that the cluster's guardrails weaken. ## Why it is still not free: the costs land on the platform **The tenant can block themselves in ways they do not understand.** Kubernetes creates a lot of objects on a user's behalf, and a rule matching a kind that a tenant's own controller or operator creates will reject those creations with a message the tenant did not write. The result looks like a broken cluster, and the first page goes to the platform team. **Admission cost is shared.** More installed rules means more work per request, and the engine sits in the request path for everyone. A tenant with a broadly matched rule is spending a budget the platform owns. **Report volume is shared.** A tenant rule running in Audit produces findings in that namespace's report, but the reporting pipeline, the storage and the dashboards belong to the platform. **Debuggability.** When someone says "my Deployment was rejected", the platform engineer now has to consider both platform policies and any tenant-authored ones. The denial message is the thing that saves you: it should name the policy and rule so the responder can tell instantly whose rule fired. ## The shape of a delegation that works **Grant the narrow verb.** `create`, `update` and `delete` on `Policy` in the tenant's own namespace. Never `ClusterPolicy` — that verb lets a tenant write a rule that blocks the whole cluster, which is the one thing the additive model does not protect you from. **Route it through review.** The Policy object arrives via the tenant's existing GitOps repository like any other manifest, so it is reviewed, versioned and revertable. A tenant policy applied by hand is a change nobody can reconstruct at 2am. **Publish the contract.** Say plainly which guardrails the platform owns and will not remove, that tenant rules are additive only, and — the important half — that a rejection caused by a tenant's own policy is the tenant's incident. Without that line written down in advance, every rejection is the platform's problem by default. **Keep a break-glass.** The platform must be able to disable a tenant's policy object that is causing an outage, and must be able to say afterwards exactly what was disabled, when and by whom. This is about the *tenant's own* rule, not about waiving a platform guardrail. **Give them a starting point.** Most tenants do not want to author policy; they want one or two local rules. A small library of reviewed rule shapes — for example the availability guardrail requiring a readiness probe on multi-replica Deployments — that a team can copy into their namespace and narrow gets you most of the value with a fraction of the novel YAML. ## When to say no Delegation stops making sense when the tenant is not the operator: if the team has no on-call rotation and no ability to debug an admission rejection, handing them a mechanism whose failure mode is "nothing can be deployed" is not empowerment. In that case the better answer is that the platform authors the rule on the tenant's behalf, scoped to their namespace, and owns it — which costs the platform a small amount of work and saves it an unbounded amount of paging. ## What a strong answer sounds like It separates the two risks explicitly. The *authorization* risk is low and provably so, because of the additive evaluation model and the namespace boundary on the object. The *operational* risk is real and is paid by whoever answers the page. The decision is therefore not about trust; it is about whether the tenant can operate what they are being handed, and about writing down who is paged when it misfires.

  • What is the strongest argument that tenant-authored policies cannot weaken your guardrails?
    Kyverno evaluates every matching rule from every policy and accumulates the results, with no precedence and no allow rule. A namespaced Policy can therefore only add constraints inside its own namespace; there is no syntax by which it exempts its workloads from a platform ClusterPolicy that also matches them.
  • A tenant's own policy is rejecting objects created by their operator. Who owns that incident?
    The tenant, if you wrote that down before it happened. The platform's job is to make the denial message name the offending policy and rule so the routing is obvious, and to hold a documented break-glass to disable that policy if the tenant cannot. Deciding ownership during the outage is how the platform inherits every tenant rule.
  • Which single RBAC grant would you refuse a tenant, and why?
    `create` on ClusterPolicy. It is the one grant the additive model does not protect against: a cluster-scoped policy can match every namespace, so a tenant with it can block other teams' deployments — accidentally or otherwise. Namespaced Policy carries no equivalent reach.

It is like letting a tenant fit an extra lock on their own flat door. They cannot unlock the building's front door, but if they lock themselves out, the building manager still gets the call.

saying these in an interview costs you the question

  • Assumes a tenant policy could exempt itself from a platform rule
  • Grants ClusterPolicy creation to tenants for convenience
  • Ignores that tenant rules add admission cost for everyone
  • Has no documented owner for a tenant-caused rejection
  • Allows tenant policies applied by hand outside review

context