Admission
The webhook answers from cache. Scanning never runs in the admission path, which is why a slow registry cannot slow down a deployment.
How a decision is made
- The API server asks about a pod.
- The tag is resolved to a digest. That resolution is cached for a minute, so a burst of identical deployments makes one registry call rather than a hundred.
- The digest's scan result and signature verdict are read from cache.
- The policy is evaluated against them and the answer is allow or deny, with a reason.
- The decision is recorded — including the allows, because evidence that only lists denials cannot show a control was operating.
Nothing in that list waits on a scan. If the digest has never been seen, step three has no answer, and what happens next is the setting below.
The two settings that decide your posture
| Value | Default | What it means |
|---|---|---|
webhook.failurePolicy | Ignore |
What the API server does when the operator does not answer. Ignore means an outage leaves you unguarded, never blocked. Fail denies until the operator answers. |
webhook.coldImagePolicy | allowAndScan |
What happens to a digest never seen before. The alternative denies it and scans it, which is Fail's natural companion. |
These two are the whole posture decision, and the honest framing is that neither answer is universally right.
Ignore keeps your cluster deployable during an outage of ours and leaves a gap in the evidence: for that window nothing was reviewed, and the evidence package says so rather than quietly showing a clean quarter.
Fail gives you a control that provably never had a gap, and it means an operator outage stops deployments. That is a real cost and you should choose it on purpose, not inherit it.
Fail and deny-on-cold are paid capabilities. They are not withheld to make Community weaker for its own sake — they are the posture that needs someone answerable when it blocks a deployment at two in the morning.
Exemptions
webhook.bypassNamespaces lists namespaces admission does not review. The operator's own namespace is always exempt, because a webhook that can block its own replacement pod is a webhook that can lock you out of fixing it.
Per-workload exceptions are not a chart value. They are made in the console, with an owner and an expiry, because an exception nobody approved and nothing expires is indistinguishable from a policy hole — and an auditor will read it as one.
Timeouts
webhook.timeoutSeconds defaults to 15. Since admission decides from cache, that is a ceiling rather than a budget: the normal answer is milliseconds, and the timeout exists for the pathological case rather than the usual one.
Serving certificate
By default the operator issues and rotates its own webhook certificate, and every replica picks up a new one without a restart — the pair lives in a Secret, not on each pod. Set webhook.tls.certManager.enabled if you would rather cert-manager owned it.