Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type PodTenantQuotaValidator ¶
type PodTenantQuotaValidator struct {
Decoder admission.Decoder
Client client.Client
MaxWorkspacesPerTenant int
MaxCPUMillisPerTenant int64
MaxMemoryMiPerTenant int64
}
PodTenantQuotaValidator enforces per-tenant resource quotas on workspace pods (Epic 51 S51.2). It prevents noisy-neighbor resource exhaustion in multi-tenant deployments by rejecting pod creation when the tenant's aggregate running resource usage would exceed configured limits.
The webhook is keyed on the llmsafespaces.dev/tenant pod label (set by the controller's pod builder per S51.3). Pods without this label are allowed unconditionally (filtered by objectSelector in the webhook config).
Quota limits are instance-level defaults from operator flags:
- MaxWorkspacesPerTenant: maximum concurrent workspace pods per tenant
- MaxCPUMillisPerTenant: maximum aggregate CPU requests per tenant
- MaxMemoryMiPerTenant: maximum aggregate memory requests per tenant
Org-specific quota overrides (from org_policies) are a follow-up; billing tier → quota mapping is tracked under Epic 43.
Race window: the check-and-schedule gap between admission and pod scheduling is acceptable — workspace pods are long-lived; this guards against gross overage, not precise concurrency control.
type RuntimeEnvironmentValidator ¶
type RuntimeEnvironmentValidator struct {
Decoder admission.Decoder
AllowedImageRegistries []string // mirrors WorkspaceValidator
}
RuntimeEnvironmentValidator validates RuntimeEnvironment resources.
F1.2.10 (Epic 17): pre-fix the validator only checked that Spec.Image was non-empty. A user with permission to create RuntimeEnvironment CRDs could supply `image: evil.example.com/malicious:latest` and any subsequent Workspace using that runtime would pull and run the attacker image. The validator now applies the same registry allow-list the workspace webhook uses (see workspace_webhook.go).
The Decoder MUST be set at construction time (controller-runtime v0.15+ removed the InjectDecoder DI callback). A nil Decoder causes Handle to panic with nil-pointer-deref on every admission request.
func (*RuntimeEnvironmentValidator) Handle ¶
func (v *RuntimeEnvironmentValidator) Handle(ctx context.Context, req admission.Request) admission.Response
Handle validates the RuntimeEnvironment resource.
func (*RuntimeEnvironmentValidator) InjectDecoder ¶
func (v *RuntimeEnvironmentValidator) InjectDecoder(d admission.Decoder) error
InjectDecoder retained for backwards compatibility (see RuntimeEnvironmentValidator).
type WorkspaceValidator ¶
type WorkspaceValidator struct {
Decoder admission.Decoder
AllowedImageRegistries []string
AllowedStorageClassNames []string
MaxStorageGi int64
MaxCPUMillicores int64
MaxMemoryMi int64
}
WorkspaceValidator is a ValidatingAdmissionWebhook for Workspace resources.
It closes the following pentest findings (Epic 17):
- F1.2.1 / RT-2.18 / RT-6.10 (Critical): Spec.Runtime arbitrary image pull. Without an allow-list, a user could create a Workspace with `runtime: "evil.example.com/malicious:latest"` and the controller would pull and run that image.
- F1.2.2 (Critical): Status forge. On CREATE the kube-apiserver does NOT yet apply status-subresource semantics, so a malicious user can stamp `status.podIP` / `status.podName` / `status.endpoint` and the API proxy will route requests to the attacker-supplied pod-IP. Defense in depth: also reject status mutations on UPDATE through the spec endpoint (the kube-apiserver subresource split normally enforces this, but failure-modes during CRD upgrades have surfaced it as a real risk).
- F1.2.9 (Medium): Spec.Storage.StorageClassName had no allow-list, letting users target hostPath / NFS / arbitrary CSIs.
- RT-6.1 (High): Webhook accepted `runtime: "../../etc/passwd"` and `storage.size: "999999Gi"` (CRD pattern allowed any digit count).
The validator is configurable so the same chart works for every deployment topology — operators decide which registries and storage classes are safe in their environment.
Field reference (set by the controller manager at construction):
- Decoder: required; nil decoder makes Handle deny with a clear error rather than panic on nil-pointer-deref.
- AllowedImageRegistries: list of registry prefixes (e.g. "ghcr.io/lenaxia/", "registry.k8s.io/"). A Workspace whose Runtime contains "/" (i.e. is shaped like an explicit image reference) must match at least one prefix.
- AllowedStorageClassNames: optional. If non-nil, the Spec.Storage. StorageClassName must be in this list (empty StorageClassName always passes — that means "use cluster default").
- MaxStorageGi: maximum requested workspace storage in GiB. Any storage size above this is rejected. Set 0 to disable.
- MaxCPUMillicores / MaxMemoryMi: maximum spec.resources.{cpu,memory} accepted at admission. Closes F1.2.3 secondary surface (a user can declare 999999999m CPU; the CRD pattern allows it; the pod stays Pending forever, wasting tenant quota — DoS at the API/etcd layer). Set 0 to disable each cap individually.
func (*WorkspaceValidator) Handle ¶
Handle validates the Workspace resource. Errors are returned as admission.Denied with a human-readable message rather than as 5xx admission errors so kubectl shows the operator the precise reason.
func (*WorkspaceValidator) InjectDecoder ¶
func (v *WorkspaceValidator) InjectDecoder(d admission.Decoder) error
InjectDecoder retained for backwards compatibility (see WorkspaceValidator).