Capsule lets a cluster administrator forbid specific metadata keys that tenant owners must not place on their own resources: Tenant.spec.namespaceOptions.forbiddenLabels / forbiddenAnnotations (namespaces), Tenant.spec.serviceOptions.forbiddenLabels / forbiddenAnnotations (Services), and the cluster-wide forbidden worker-node labels/annotations. These lists are an isolation control — they exist to stop a tenant owner from setting metadata that other controllers or admission plugins key on (Pod Security Admission labels, kubernetes.io/metadata.name, LoadBalancer/externalIP service annotations, scheduler annotations, vendor labels …
A validation bug in internal/webhook/tenant/validation/forbidden_annotations_regex.go allows an invalid ForbiddenAnnotations.Regex value to bypass Tenant admission on update. The webhook compiles ForbiddenLabels.Regex for both labels and annotations, so a malformed annotations regex can be persisted. Once stored, namespace admission later evaluates the bad regex through pkg/api/forbidden_list.go, where regexp.MustCompile can panic and cause admission failure.
A parameter order bug in internal/webhook/tenant/validation/hostname_regex.go causes the hostnameRegexHandler.OnUpdate webhook to validate the old Tenant object's AllowedHostnames.Regex instead of the new one being submitted. This allows an invalid (malformed) regex to bypass admission validation and be persisted to etcd, causing a Denial of Service for all Ingress operations within the affected tenant.
CapsuleConfiguration.Spec.NodeMetadata.ForbiddenLabels.Regex and ForbiddenAnnotations.Regex are never validated by any admission webhook. A Cluster Admin can persist a malformed regex to etcd without being blocked. Once stored, every Node CREATE, UPDATE, or PATCH request triggers regexp.MustCompile() in pkg/api/forbidden_list.go:36, which panics and crashes the node admission webhook — causing a cluster-wide Denial of Service for all Node operations.
CVE-2026-22872 (GHSA-qjjm-7j9w-pw72) reported that a Tenant Owner could create cluster-scoped resources (e.g. ClusterRole, ValidatingWebhookConfiguration) through a TenantResource, because the controller applies them with its cluster-admin ServiceAccount and SetNamespace is ineffective for cluster-scoped kinds. The v0.13.0 fix added a cluster-scope rejection guard, but only on the NamespacedItems selection path (ResourceReference.LoadResources -> IsNamespacedGVK, error "cluster-scoped kind … is not allowed"). The RawItems create path — the exact vector the original advisory named …
Capsule v0.13.2 webhook rules contain namespace/finalize (singular) instead of namespaces/finalize (plural). K8s requires plural. The finalize defense from CVE-2026-30963 fix is absent.
The Capsule Controller runs with cluster-admin privileges. Although the TenantResource RawItems processing logic forcibly sets the namespace, this is ineffective for cluster-scoped resources. Tenant administrators can leverage the Controller's elevated privileges to create cluster-scoped resources (such as ClusterRole and ValidatingWebhookConfiguration) that they cannot create directly, achieving cross-tenant privilege escalation and cluster-level attacks.
To defend against namespace hijacking achieved through update/patch operations on namespaces, Capsule uses a webhook to validate update requests targeting namespaces. However, in Kubernetes, the namespace/finalize and namespace/status subresource APIs can also modify various fields of a namespace, including the metadata field. The webhook does not define interception rules for these subresources. As a result, if a tenant administrator has permission to modify namespace/status or namespace/finalize, they can successfully perform …