Skip to main content

Control admission

Inspect 1.36

Syself Autopilot ships built-in admission protection that prevents a broken webhook from locking your cluster, and it lets you write your own hard gates that cannot be taken offline. Admission control is the step where the Kubernetes API server checks or modifies an object (such as a Pod or Deployment) before saving it, and can reject it, change it, or both. With it you enforce cluster-wide rules on every object before it is saved: "no privileged pods," "images must be signed," or "every Deployment needs a cost label." Beyond the built-in protection, one further platform policy rejects network-policy rules the platform cannot enforce correctly.

How a broken webhook can lock your cluster#

An admission webhook is a pod that the API server calls on every matching request. A ValidatingWebhookConfiguration is a Kubernetes object that connects an external service to the admission process. If you register one with failurePolicy: Fail and that service becomes slow or unreachable, the API server rejects every request it cannot check.

That includes requests from the platform components that manage your cluster, so the control plane itself is locked out.

The problem is not a permissions issue. RBAC (Role-Based Access Control) decides who can do what in the cluster. system:masters is its most privileged group and skips RBAC checks. But even system:masters does not skip admission webhooks. A webhook with failurePolicy: Fail blocks everyone, including cluster admins. A single broken webhook can make the whole cluster unusable.

How the platform's admission protection works#

The platform's admission protection uses ValidatingAdmissionPolicies (VAPs). A VAP is written in CEL (Common Expression Language, a small rule language built into Kubernetes) and runs inside the API server itself. Because it runs inside the API server, there is no pod to crash and no service to overload. VAPs cannot be taken offline.

Note

If kubectl apply fails with a syself-restrict-tenant-webhooks error, remove any rule that targets admissionregistration.k8s.io, authentication.k8s.io, or authorization.k8s.io, or that uses a wildcard apiGroup. Also make sure any webhook matching roles, role bindings, or service accounts is namespace-scoped: it must not match cluster roles or cluster role bindings, and must not use resource wildcards.

Who is exempt#

The webhook policies (syself-restrict-tenant-webhooks and syself-protect-platform-policies) exempt the system:masters group and the platform's internal cluster-admin group; for those, platform components and the cluster admin identity are unrestricted. Everyone else is subject to the rules. syself-restrict-l7-proxy-policies has no exemption: it applies to every caller, including cluster admins and platform components.

This creates a security requirement: tenants must never be granted system:masters or the platform's internal cluster-admin role on a workload cluster. If they are, they can bypass those webhook policies. Keep tenants off those groups using RBAC. See .

Upgrade safety#

The platform deploys these admission policies as part of cluster setup and upgrades. If a policy ever fails to deploy, the cluster keeps working.

Running your own admission policies#

You can enforce your own policies in two ways. The choice determines how strongly they block.

Use ValidatingAdmissionPolicy for hard gates#

A native VAP is a CEL (Common Expression Language: a compact rule language built into Kubernetes) policy that runs inside the API server. It has no backend pod to go down, so it does not carry the reliability trade-off that a webhook-based tool does. A native VAP can hard-deny (fail closed) and cannot be taken offline.

For rules that must block without exception, such as "reject privileged pods, always," write a native VAP. Do not name it syself-*; that prefix is reserved for platform policies.

Webhook-based tools are a trade-off#

Tools like Kyverno and use a ValidatingWebhookConfiguration to validate resources. The platform does not force these webhooks to failurePolicy: Ignore; you can set failurePolicy: Fail as long as the webhook stays out of the admission-registration, authentication/authorization, and cluster-scoped RBAC APIs described above. Those restrictions are what keep a cluster admin able to authenticate and delete a broken webhook.

That still leaves a trade-off for your own workloads. A webhook-based tool is only as reliable as its backend pod. With failurePolicy: Fail, if the Kyverno pod goes down, requests that match its rules are blocked. Admin recovery still works, but your own workloads are stuck. With failurePolicy: Ignore, a Kyverno outage lets those requests through instead of blocking them.

Practical guidance:

  • Use Kyverno mutate and generate rules freely. Those do not gate admission the same way.
  • For rules that must hard-block without depending on a pod staying up, write a native VAP in CEL instead of a Kyverno validating policy.
  • If you want validation that never blocks your workloads during a Kyverno outage, run it with failurePolicy: Ignore and keep Kyverno highly available so that path rarely triggers.

See for Kyverno-specific guidance.

What the platform already enforces#

Beyond the admission guardrails, the API server runs these admission plugins by default:

NodeRestriction: a node agent can only modify its own node and its own pods. It cannot touch other nodes or pods on other nodes.

EventRateLimit: caps how many events per second the API server records. This stops a misbehaving workload from flooding the API server with events.