diff --git a/test/e2e/common/node/security_context.go b/test/e2e/common/node/security_context.go index 0a8fd653c55..bcf60fd20c3 100644 --- a/test/e2e/common/node/security_context.go +++ b/test/e2e/common/node/security_context.go @@ -35,6 +35,7 @@ import ( imageutils "k8s.io/kubernetes/test/utils/image" admissionapi "k8s.io/pod-security-admission/api" "k8s.io/utils/pointer" + "k8s.io/utils/ptr" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" @@ -635,6 +636,39 @@ var _ = SIGDescribe("Security Context", func() { }) }) +var _ = SIGDescribe("User Namespaces for Pod Security Standards [LinuxOnly]", func() { + f := framework.NewDefaultFramework("user-namespaces-pss-test") + f.NamespacePodSecurityEnforceLevel = admissionapi.LevelRestricted + + ginkgo.Context("with UserNamespacesSupport and UserNamespacesPodSecurityStandards enabled", func() { + f.It("should allow pod", feature.UserNamespacesPodSecurityStandards, func(ctx context.Context) { + name := "pod-user-namespaces-pss-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + HostUsers: ptr.To(false), + SecurityContext: &v1.PodSecurityContext{}, + Containers: []v1.Container{ + { + Name: name, + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"whoami"}, + SecurityContext: &v1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + Capabilities: &v1.Capabilities{Drop: []v1.Capability{"ALL"}}, + SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}, + }, + }, + }, + }, + } + + e2epodoutput.TestContainerOutput(ctx, f, "RunAsUser-RunAsNonRoot", pod, 0, []string{"root"}) + }) + }) +}) + // waitForFailure waits for pod to fail. func waitForFailure(ctx context.Context, f *framework.Framework, name string, timeout time.Duration) { gomega.Expect(e2epod.WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, diff --git a/test/e2e/feature/feature.go b/test/e2e/feature/feature.go index b100ad67f8e..f7cae943d15 100644 --- a/test/e2e/feature/feature.go +++ b/test/e2e/feature/feature.go @@ -328,6 +328,12 @@ var ( // TODO: document the feature (owning SIG, when to use this feature for a test) UserNamespacesSupport = framework.WithFeature(framework.ValidFeatures.Add("UserNamespacesSupport")) + // Owned by SIG Node + // Can be used when the UserNamespacesPodSecurityStandards kubelet feature + // gate is enabled to relax the application of Pod Security Standards in a + // controlled way. + UserNamespacesPodSecurityStandards = framework.WithFeature(framework.ValidFeatures.Add("UserNamespacesPodSecurityStandards")) + // TODO: document the feature (owning SIG, when to use this feature for a test) ValidatingAdmissionPolicy = framework.WithFeature(framework.ValidFeatures.Add("ValidatingAdmissionPolicy"))