Repository navigation
Move validation to admission #325
Description
Activity
/assign
If we move validation logic into a webhook, we should ensure it's stateless, i.e. the validation logic only looks at the transmitted object, nothing else (i.e. references to other objects must not be checked).
Why? Because trying to build a webhook that enforces BadACID ontop of Kube is just asking for trouble.
Case 1) Suppose you have two resources, A and B. Objects of A refer to objects of B. So we write a webhook for A checking that the reference to a B object is valid. Sounds cool. But what if the reference is valid, but then later someone deletes object b? Suddenly object a becomes, with no changes to it, invalid.
Case 2) Same scenario, but imagine both objects come from the same YAML file (´kubectl apply -f mythings.yaml`). There is a very, very good chance that in the moment the webhook validates a, b is not yet in the cache and so the webhook might reject the request entirely.
Both scenarios can only be solved with even more validation webhooks that truly validate every single reference everywhere. But on top of Kube, this is difficult to build, makes the system potentially slow down dramatically (What if B in the scenarios above was "Secrets"? Do you want a webhook to validate every single interaction with secrets?) and any missed check will lead to controllers crashing (because after all, the reason we moved all the validation into a webhook was to give better feedback and thin out controllers).
From my own little bits of experience, the road of trying to build a referentially integer system on top of Kube is just the wrong way. To me it's similar to my old (when I was like 17, cut me some slack) desire to have a wait function in JavaScript, trying my darndest to ignore the callback-based nature of the runtime and instead trying to force blocking APIs into the language. You end up constantly fighting with your underlying system, and for what? For a few potentially more helpful error messages?
So my recommendation is that a validation webhook should be stateless and never ever get a (Kube) client to anything. If the object in question contained Postgres credentials, the webhook should also not use a Postgres client to validate them. Yes, this means many things simply cannot be validated by a webhook. Welcome to Kubernetes. It is eventually consistent, by design. Just like you can have a
ClusterRoleBindingthat refers to a nonexistingClusterRole, you should be able to have aBlobobject that refers to a nonexistingTwilightobject.And this conceptual limitation is also why CEL exists. It mostly nicely fills the gap between OpenAPI schema validation rules (that usually just affect a single field) and more complex webhooks.
Thank you for coming to my TED talk.

There is code in permissionClaims PR for
APIServiceExportRequestvalidating if its valid. For now its sets the conditions and sets it terminal. We should just validate this via admission and clean the reconciliation code.Look for the issue link in the code.