Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -488,12 +488,39 @@ func buildContainerSecurityContext(
}

if !needCodeExecIsolation {
return nil
return defaultRestrictedContainerSecurityContext()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forcing runasnonroot true by default breaks byo agents whose images run as root on any cluster, so consider applying these defaults only to kagent owned images or making them opt in.

}

return &corev1.SecurityContext{Privileged: new(true)}
}

// defaultRestrictedContainerSecurityContext returns a restricted-PSS-compliant container SecurityContext.
func defaultRestrictedContainerSecurityContext() *corev1.SecurityContext {
return &corev1.SecurityContext{
RunAsNonRoot: new(true),
AllowPrivilegeEscalation: new(false),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
}
}

// defaultPodSecurityContext returns the provided PodSecurityContext or a restricted-PSS-compliant default if nil.
func defaultPodSecurityContext(provided *corev1.PodSecurityContext) *corev1.PodSecurityContext {
if provided != nil {
return provided
}
return &corev1.PodSecurityContext{
RunAsNonRoot: new(true),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}
}

func buildPodTemplate(
manifestCtx manifestContext,
runtimeInputs *podRuntimeInputs,
Expand Down Expand Up @@ -526,7 +553,7 @@ func buildPodTemplate(
Spec: corev1.PodSpec{
ServiceAccountName: *dep.ServiceAccountName,
ImagePullSecrets: dep.ImagePullSecrets,
SecurityContext: dep.PodSecurityContext,
SecurityContext: defaultPodSecurityContext(dep.PodSecurityContext),
InitContainers: runtimeInputs.initContainers,
Comment on lines 553 to 557
Containers: append([]corev1.Container{{
Name: "kagent",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,15 @@ func TestSecurityContext_OnlyPodSecurityContext(t *testing.T) {
assert.Equal(t, int64(2000), *podSecurityContext.RunAsUser)
assert.Equal(t, int64(2000), *podSecurityContext.RunAsGroup)

// Container security context should be nil if not specified
// Container security context should get restricted-PSS defaults when not specified
containerSecurityContext := podTemplate.Spec.Containers[0].SecurityContext
assert.Nil(t, containerSecurityContext, "Container securityContext should be nil when not specified")
require.NotNil(t, containerSecurityContext, "Container securityContext should get restricted defaults")
assert.True(t, *containerSecurityContext.RunAsNonRoot, "Default runAsNonRoot should be true")
assert.False(t, *containerSecurityContext.AllowPrivilegeEscalation, "Default allowPrivilegeEscalation should be false")
require.NotNil(t, containerSecurityContext.Capabilities)
assert.Contains(t, containerSecurityContext.Capabilities.Drop, corev1.Capability("ALL"), "Default should drop ALL capabilities")
require.NotNil(t, containerSecurityContext.SeccompProfile)
assert.Equal(t, corev1.SeccompProfileTypeRuntimeDefault, containerSecurityContext.SeccompProfile.Type)
}

func TestSecurityContext_OnlyContainerSecurityContext(t *testing.T) {
Expand Down Expand Up @@ -264,9 +270,12 @@ func TestSecurityContext_OnlyContainerSecurityContext(t *testing.T) {
require.NotNil(t, deployment)
podTemplate := &deployment.Spec.Template

// Pod security context should be nil if not specified
// Pod security context should get restricted-PSS defaults when not specified
podSecurityContext := podTemplate.Spec.SecurityContext
assert.Nil(t, podSecurityContext, "Pod securityContext should be nil when not specified")
require.NotNil(t, podSecurityContext, "Pod securityContext should get restricted defaults")
assert.True(t, *podSecurityContext.RunAsNonRoot, "Default runAsNonRoot should be true")
require.NotNil(t, podSecurityContext.SeccompProfile)
assert.Equal(t, corev1.SeccompProfileTypeRuntimeDefault, podSecurityContext.SeccompProfile.Type)

// Container security context should be set
containerSecurityContext := podTemplate.Spec.Containers[0].SecurityContext
Expand Down Expand Up @@ -429,3 +438,78 @@ func TestSecurityContext_SkillsPSSRestricted(t *testing.T) {
assert.Equal(t, int64(1000), *containerSecurityContext.RunAsUser, "User-provided runAsUser should be preserved")
assert.False(t, *containerSecurityContext.AllowPrivilegeEscalation, "AllowPrivilegeEscalation should be preserved as false")
}

// TestSecurityContext_NilSecurityContext_RestrictedDefaults verifies restricted-PSS defaults when no SecurityContext is set.
func TestSecurityContext_NilSecurityContext_RestrictedDefaults(t *testing.T) {
ctx := context.Background()

agent := &v1alpha2.Agent{
ObjectMeta: metav1.ObjectMeta{
Name: "test-agent",
Namespace: "test",
},
Spec: v1alpha2.AgentSpec{
Type: v1alpha2.AgentType_Declarative,
Declarative: &v1alpha2.DeclarativeAgentSpec{
SystemMessage: "Test agent",
ModelConfig: "test-model",
},
},
}

modelConfig := &v1alpha2.ModelConfig{
ObjectMeta: metav1.ObjectMeta{
Name: "test-model",
Namespace: "test",
},
Spec: v1alpha2.ModelConfigSpec{
Provider: "OpenAI",
Model: "gpt-4o",
},
}

scheme := schemev1.Scheme
err := v1alpha2.AddToScheme(scheme)
require.NoError(t, err)

kubeClient := fake.NewClientBuilder().
WithScheme(scheme).
WithObjects(agent, modelConfig).
Build()

defaultModel := types.NamespacedName{
Namespace: "test",
Name: "test-model",
}
translatorInstance := translator.NewAdkApiTranslator(kubeClient, defaultModel, nil, "", nil)

result, err := translator.TranslateAgent(ctx, translatorInstance, agent)
require.NoError(t, err)

var deployment *appsv1.Deployment
for _, obj := range result.Manifest {
if dep, ok := obj.(*appsv1.Deployment); ok {
deployment = dep
break
}
}
require.NotNil(t, deployment)
podTemplate := &deployment.Spec.Template

// Pod-level restricted defaults
podSC := podTemplate.Spec.SecurityContext
require.NotNil(t, podSC, "Pod securityContext should have restricted defaults")
assert.True(t, *podSC.RunAsNonRoot, "Pod runAsNonRoot should default to true")
require.NotNil(t, podSC.SeccompProfile)
assert.Equal(t, corev1.SeccompProfileTypeRuntimeDefault, podSC.SeccompProfile.Type)

// Container-level restricted defaults
containerSC := podTemplate.Spec.Containers[0].SecurityContext
require.NotNil(t, containerSC, "Container securityContext should have restricted defaults")
assert.True(t, *containerSC.RunAsNonRoot, "Container runAsNonRoot should default to true")
assert.False(t, *containerSC.AllowPrivilegeEscalation, "Container allowPrivilegeEscalation should default to false")
require.NotNil(t, containerSC.Capabilities)
assert.Contains(t, containerSC.Capabilities.Drop, corev1.Capability("ALL"), "Should drop ALL capabilities")
require.NotNil(t, containerSC.SeccompProfile)
assert.Equal(t, corev1.SeccompProfileTypeRuntimeDefault, containerSC.SeccompProfile.Type)
}
Loading