You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal was written with the help of claude-4.5-opus-high, and despite some quick review, may contain AI-typical flaws 😄
Executive Summary
This proposal outlines the design for a generalized mutating admission webhook for the OpenShift Sandboxed Containers (OSC) Operator. Building on the existing memory overhead annotation work, this webhook will provide a unified, configurable solution for:
Injecting Kata-specific pod annotations (memory, CPU, initdata, etc.)
Automatically adding runtimeClass to pods in designated namespaces
Providing an opt-out mechanism for customers using alternative solutions (OPA, Kyverno)
Background
Previous Discussions
The need for an OSC mutating webhook has come up several times in earlier discussions. The primary driver was to automatically add the runtime class to pods based on some criteria. Until now, users were redirected to use their own mutating webhooks (OPA policy, Kyverno policy, etc.).
Current Drivers
With recent Confidential Containers (CoCo) work, the need for an OSC-specific webhook has become more pressing:
Peer Pods Webhook (cloud-api-adaptor): Handles extended resources for peer pods. This implementation can serve as a reference for resource-based mutations.
Requirements
Functional Requirements
ID
Requirement
Priority
FR1
Inject Kata pod annotations (memory_overhead, default_vcpus, etc.)
High
FR2
Inject initdata annotation for CoCo baremetal pods
High
FR3
Automatically add runtimeClassName to pods in specific namespaces
Medium
FR4
Support multiple runtime classes (kata, kata-remote, kata-cc, etc.)
High
FR5
Ability to disable webhook via KataConfig
High
FR6
Configurable annotation rules per namespace or label selector
Medium
FR7
Preserve existing pod annotations (no overwrite unless configured)
High
Non-Functional Requirements
ID
Requirement
Priority
NFR1
Webhook latency < 50ms per request
High
NFR2
Graceful degradation if webhook is unavailable
High
NFR3
Comprehensive audit logging
Medium
NFR4
Compatible with OPA/Kyverno (can coexist or be disabled)
typeKataConfigSpecstruct {
// ... existing fields ...// Webhook configures the OSC mutating webhook behavior// +optionalWebhook*WebhookConfig`json:"webhook,omitempty"`
}
typeWebhookConfigstruct {
// Enabled controls whether the webhook is active// +optional// +kubebuilder:default:=trueEnabled*bool`json:"enabled,omitempty"`// FailurePolicy determines behavior when webhook fails// +optional// +kubebuilder:default:="Fail"// +kubebuilder:validation:Enum=Fail;IgnoreFailurePolicystring`json:"failurePolicy,omitempty"`// Annotations defines annotation injection rules// +optionalAnnotations*AnnotationConfig`json:"annotations,omitempty"`// RuntimeClassInjection defines rules for automatic runtimeClass injection// +optionalRuntimeClassInjection*RuntimeClassInjectionConfig`json:"runtimeClassInjection,omitempty"`
}
typeAnnotationConfigstruct {
// MemoryOverheadMB specifies memory overhead for Kata pods// +optional// +kubebuilder:default:=350// +kubebuilder:validation:Minimum=1// +kubebuilder:validation:Maximum=2048MemoryOverheadMB*int32`json:"memoryOverheadMB,omitempty"`// DefaultVCPUs specifies default vCPU count// +optionalDefaultVCPUs*int32`json:"defaultVCPUs,omitempty"`// Initdata specifies initdata for CoCo pods// +optionalInitdata*string`json:"initdata,omitempty"`// Custom allows arbitrary annotation injection// +optionalCustommap[string]string`json:"custom,omitempty"`
}
typeRuntimeClassInjectionConfigstruct {
// Enabled controls whether runtimeClass injection is active// +optional// +kubebuilder:default:=falseEnabled*bool`json:"enabled,omitempty"`// DefaultRuntimeClass is the runtimeClass to inject// +optional// +kubebuilder:default:="kata"DefaultRuntimeClassstring`json:"defaultRuntimeClass,omitempty"`// NamespaceSelector selects namespaces for injection// +optionalNamespaceSelector*metav1.LabelSelector`json:"namespaceSelector,omitempty"`// PodSelector selects pods for injection// +optionalPodSelector*metav1.LabelSelector`json:"podSelector,omitempty"`// ExcludeNamespaces lists namespaces to exclude// +optionalExcludeNamespaces []string`json:"excludeNamespaces,omitempty"`
}
Option 2: Separate WebhookConfig CRD
Create a dedicated OSCWebhookConfig CRD for more complex scenarios:
// +kubebuilder:object:root=true// +kubebuilder:subresource:statustypeOSCWebhookConfigstruct {
metav1.TypeMeta`json:",inline"`
metav1.ObjectMeta`json:"metadata,omitempty"`SpecOSCWebhookConfigSpec`json:"spec,omitempty"`StatusOSCWebhookConfigStatus`json:"status,omitempty"`
}
typeOSCWebhookConfigSpecstruct {
// Rules defines mutation rulesRules []MutationRule`json:"rules,omitempty"`
}
typeMutationRulestruct {
// Name is a unique identifier for this ruleNamestring`json:"name"`// Match defines when this rule appliesMatchRuleMatch`json:"match"`// Mutate defines what mutations to applyMutateRuleMutate`json:"mutate"`
}
typeRuleMatchstruct {
// Namespaces to match (empty = all)Namespaces []string`json:"namespaces,omitempty"`// NamespaceSelector for label-based matchingNamespaceSelector*metav1.LabelSelector`json:"namespaceSelector,omitempty"`// PodSelector for pod label matchingPodSelector*metav1.LabelSelector`json:"podSelector,omitempty"`// RuntimeClasses to match (empty = all Kata classes)RuntimeClasses []string`json:"runtimeClasses,omitempty"`
}
typeRuleMutatestruct {
// RuntimeClassName to set (if empty, don't set)RuntimeClassNamestring`json:"runtimeClassName,omitempty"`// Annotations to addAnnotationsmap[string]string`json:"annotations,omitempty"`// Labels to addLabelsmap[string]string`json:"labels,omitempty"`
}
Consider separate OSCWebhookConfig CRD for complex scenarios
Add metrics and observability
Performance optimization
Comparison with Alternatives
Feature
OSC Webhook
OPA/Gatekeeper
Kyverno
OSC-specific logic
✅ Native
❌ Custom policy
❌ Custom policy
KataConfig integration
✅ Direct
❌ External
❌ External
Learning curve
Low
High
Medium
Maintenance
Operator team
User
User
Flexibility
Medium
High
High
Can coexist
✅
✅
✅
Recommendation: Provide the OSC webhook with a disable option. Users with complex requirements or existing policy infrastructure can disable it and use OPA/Kyverno.
This proposal provides a path to evolve the current memory overhead webhook into a generalized OSC webhook that addresses multiple use cases while maintaining simplicity and providing an opt-out mechanism. The phased approach allows incremental delivery while building on proven existing work.
Note: This builds on top of PR #1058.
This proposal was written with the help of claude-4.5-opus-high, and despite some quick review, may contain AI-typical flaws 😄
Executive Summary
This proposal outlines the design for a generalized mutating admission webhook for the OpenShift Sandboxed Containers (OSC) Operator. Building on the existing memory overhead annotation work, this webhook will provide a unified, configurable solution for:
Background
Previous Discussions
The need for an OSC mutating webhook has come up several times in earlier discussions. The primary driver was to automatically add the runtime class to pods based on some criteria. Until now, users were redirected to use their own mutating webhooks (OPA policy, Kyverno policy, etc.).
Current Drivers
With recent Confidential Containers (CoCo) work, the need for an OSC-specific webhook has become more pressing:
Existing Work
Memory Overhead Annotation (this operator): Injects
io.katacontainers.config.hypervisor.memory_overheadfor Kata pods. See MEMORY_OVERHEAD_ANNOTATION_PROPOSAL.md (in controller: Add overhead annotation using pod mutating webhook #1058).Peer Pods Webhook (cloud-api-adaptor): Handles extended resources for peer pods. This implementation can serve as a reference for resource-based mutations.
Requirements
Functional Requirements
Non-Functional Requirements
Proposed Architecture
High-Level Design
Mutation Pipeline
The webhook processes pods through a pipeline of mutators:
runtimeClassNamebased on namespace/label rulesConfiguration Model
Option 1: Extend KataConfig (Recommended)
Option 2: Separate WebhookConfig CRD
Create a dedicated
OSCWebhookConfigCRD for more complex scenarios:Implementation Details
Generalized PodMutator
RuntimeClass Injection
CoCo Initdata Injection
Webhook Disable Feature
Sample Configurations
Basic Configuration (Memory Overhead Only)
CoCo Baremetal Configuration
RuntimeClass Injection for Namespace
Disable Webhook (Use OPA/Kyverno)
Supported Annotations
io.katacontainers.config.hypervisor.memory_overheadannotations.memoryOverheadMBio.katacontainers.config.hypervisor.default_vcpusannotations.defaultVCPUsio.katacontainers.config.runtime.cc_init_dataannotations.initdataio.katacontainers.config.hypervisor.default_memoryannotations.customio.katacontainers.config.hypervisor.virtio_fs_cacheannotations.customannotations.customMigration Path
Phase 1: Generalize Current Implementation
PodMutatorto use mutation pipelineWebhookConfigto KataConfigSpecenabledflag (default: true for backward compatibility)Phase 2: Add New Mutations
Phase 3: RuntimeClass Injection
Phase 4: Advanced Features
OSCWebhookConfigCRD for complex scenariosComparison with Alternatives
Recommendation: Provide the OSC webhook with a disable option. Users with complex requirements or existing policy infrastructure can disable it and use OPA/Kyverno.
Security Considerations
Testing Strategy
References
Conclusion
This proposal provides a path to evolve the current memory overhead webhook into a generalized OSC webhook that addresses multiple use cases while maintaining simplicity and providing an opt-out mechanism. The phased approach allows incremental delivery while building on proven existing work.
The key design decisions are: