Code change:
Graduate seccomp to GA, as defined on the respective . This is an umbrella issue to track all outstanding work. [x] API Server changes (MERGED) [x] Kubelet changes (MERGED) [x] Mark flag as deprecated (MERGED) [x] Update PSP to support seccomp fields (MERGED) [x] Document Kubernetes seccomp support (MERGED)[x] Add seccomp least privilege for docker sandbox (MERGED) [x] Add seccomp least privilege for kuberuntime (MERGED) ) /area kubelet /area kubelet-api /sig node /area security /assign
/cc
just a heads up that we have concluded all the core items for seccomp to go GA. There are still 2 pending PRs that ideally would also go in 1.19, but we are waiting for them to be reviewed: and
needs to be rebased apparently and isn't just waiting in the merge pool as verify is not passing.
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
/remove-lifecycle stale
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
I think the warning mechanism was blocked by a not existing API. This is now tracked in
/remove-lifecycle stale
Updated the description to given that the warning mechanism is now set to that milestone.
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-contributor-experience at . /lifecycle stale
/remove-lifecycle stale
/priority backlog
/triage accepted
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/remove-lifecycle stale
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/remove-lifecycle stale
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/remove-lifecycle stale
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/remove-lifecycle stale
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/remove-lifecycle stale
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs. This bot triages issues and PRs according to the following rules: After 90d of inactivity, is applied After 30d of inactivity since was applied, is applied After 30d of inactivity since was applied, the issue is closed You can: Mark this issue or PR as fresh with Mark this issue or PR as rotten with Close this issue or PR with Offer to help out with [Issue Triage][1] Please send feedback to sig-contributor-experience at . /lifecycle stale [1]:
/lifecycle frozen What is the remaining work here?
I guess we have to follow-up on and implement: I can take care of that if we agree that we want to ship that in 1.27. /cc

Related discussion:
text: } } <del> func TestApplySeccompVersionSkew(t *testing.T) { const containerName = "container" testProfile := "test" for _, test := range []struct { description string pod         *api.Pod validation  func(*testing.T, *api.Pod) }{ { description: "Security context nil", pod:         &api.Pod{}, validation: func(t *testing.T, pod *api.Pod) { require.NotNil(t, pod) }, }, { description: "Security context not nil", pod: &api.Pod{ Spec: api.PodSpec{SecurityContext: &api.PodSecurityContext{}}, }, validation: func(t *testing.T, pod *api.Pod) { require.NotNil(t, pod) }, }, { description: "Field set and no annotation present", pod: &api.Pod{ Spec: api.PodSpec{ SecurityContext: &api.PodSecurityContext{ SeccompProfile: &api.SeccompProfile{ Type: api.SeccompProfileTypeUnconfined, }, }, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Len(t, pod.Annotations, 0) }, }, { description: "Annotation 'unconfined' and no field present", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, }, }, Spec: api.PodSpec{}, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeUnconfined, pod.Spec.SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'runtime/default' and no field present", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, }, }, Spec: api.PodSpec{SecurityContext: &api.PodSecurityContext{}}, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeRuntimeDefault, pod.Spec.SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'docker/default' and no field present", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault, }, }, Spec: api.PodSpec{SecurityContext: &api.PodSecurityContext{}}, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeRuntimeDefault, pod.Spec.SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'localhost/test' and no field present", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompPodAnnotationKey: v1.SeccompLocalhostProfileNamePrefix + testProfile, }, }, Spec: api.PodSpec{SecurityContext: &api.PodSecurityContext{}}, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeLocalhost, pod.Spec.SecurityContext.SeccompProfile.Type) require.Equal(t, testProfile, *pod.Spec.SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'localhost/' has zero length", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompPodAnnotationKey: v1.SeccompLocalhostProfileNamePrefix, }, }, Spec: api.PodSpec{SecurityContext: &api.PodSecurityContext{}}, }, validation: func(t *testing.T, pod *api.Pod) { require.Nil(t, pod.Spec.SecurityContext.SeccompProfile) }, }, { description: "Security context nil (container)", pod: &api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{{}}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.NotNil(t, pod) }, }, { description: "Security context not nil (container)", pod: &api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{{ SecurityContext: &api.SecurityContext{}, }}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.NotNil(t, pod) }, }, { description: "Field set and no annotation present (container)", pod: &api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{ { Name: containerName, SecurityContext: &api.SecurityContext{ SeccompProfile: &api.SeccompProfile{ Type: api.SeccompProfileTypeUnconfined, }, }, }, }, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Len(t, pod.Annotations, 0) }, }, { description: "Multiple containers with fields (container)", pod: &api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{ { Name: containerName + "1", SecurityContext: &api.SecurityContext{ SeccompProfile: &api.SeccompProfile{ Type: api.SeccompProfileTypeUnconfined, }, }, }, { Name: containerName + "2", }, { Name: containerName + "3", SecurityContext: &api.SecurityContext{ SeccompProfile: &api.SeccompProfile{ Type: api.SeccompProfileTypeRuntimeDefault, }, }, }, }, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Len(t, pod.Annotations, 0) }, }, { description: "Annotation 'unconfined' and no field present (container)", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompContainerAnnotationKeyPrefix + containerName: v1.SeccompProfileNameUnconfined, }, }, Spec: api.PodSpec{ Containers: []api.Container{{ Name: containerName, }}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeUnconfined, pod.Spec.Containers[0].SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.Containers[0].SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'runtime/default' and no field present (container)", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompContainerAnnotationKeyPrefix + containerName: v1.SeccompProfileRuntimeDefault, }, }, Spec: api.PodSpec{ Containers: []api.Container{{ Name:            containerName, SecurityContext: &api.SecurityContext{}, }}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeRuntimeDefault, pod.Spec.Containers[0].SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.Containers[0].SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Annotation 'docker/default' and no field present (container)", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompContainerAnnotationKeyPrefix + containerName: v1.DeprecatedSeccompProfileDockerDefault, }, }, Spec: api.PodSpec{ Containers: []api.Container{{ Name:            containerName, SecurityContext: &api.SecurityContext{}, }}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeRuntimeDefault, pod.Spec.Containers[0].SecurityContext.SeccompProfile.Type) require.Nil(t, pod.Spec.Containers[0].SecurityContext.SeccompProfile.LocalhostProfile) }, }, { description: "Multiple containers by annotations (container)", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompContainerAnnotationKeyPrefix + containerName + "1": v1.SeccompLocalhostProfileNamePrefix + testProfile, v1.SeccompContainerAnnotationKeyPrefix + containerName + "3": v1.SeccompProfileRuntimeDefault, }, }, Spec: api.PodSpec{ Containers: []api.Container{ {Name: containerName + "1"}, {Name: containerName + "2"}, {Name: containerName + "3"}, }, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeLocalhost, pod.Spec.Containers[0].SecurityContext.SeccompProfile.Type) require.Equal(t, testProfile, *pod.Spec.Containers[0].SecurityContext.SeccompProfile.LocalhostProfile) require.Equal(t, api.SeccompProfileTypeRuntimeDefault, pod.Spec.Containers[2].SecurityContext.SeccompProfile.Type) }, }, { description: "Annotation 'localhost/test' and no field present (container)", pod: &api.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ v1.SeccompContainerAnnotationKeyPrefix + containerName: v1.SeccompLocalhostProfileNamePrefix + testProfile, }, }, Spec: api.PodSpec{ Containers: []api.Container{{ Name:            containerName, SecurityContext: &api.SecurityContext{}, }}, }, }, validation: func(t *testing.T, pod *api.Pod) { require.Equal(t, api.SeccompProfileTypeLocalhost, pod.Spec.Containers[0].SecurityContext.SeccompProfile.Type) require.Equal(t, testProfile, *pod.Spec.Containers[0].SecurityContext.SeccompProfile.LocalhostProfile) }, }, } { output := &api.Pod{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{}}, } for i, ctr := range test.pod.Spec.Containers { output.Spec.Containers = append(output.Spec.Containers, api.Container{}) if ctr.SecurityContext != nil && ctr.SecurityContext.SeccompProfile != nil { output.Spec.Containers[i].SecurityContext = &api.SecurityContext{ SeccompProfile: &api.SeccompProfile{ Type:             api.SeccompProfileType(ctr.SecurityContext.SeccompProfile.Type), LocalhostProfile: ctr.SecurityContext.SeccompProfile.LocalhostProfile, }, } } } applySeccompVersionSkew(test.pod) test.validation(t, test.pod) } } </del> func newPodWithHugePageValue(resourceName api.ResourceName, value resource.Quantity) *api.Pod { return &api.Pod{