From a59144017bcac5c316948e88ac2d86f874e82d30 Mon Sep 17 00:00:00 2001 From: Jeff Mesnil Date: Mon, 13 Mar 2023 12:38:58 +0100 Subject: [PATCH] [#266] Updated Pod security standards * Add a default Security Context if the user does not specify one from the WildFlyServerSpec. * In the CSV, updates the operator's own deployment to comply with the security standards. This fixes #266 Signed-off-by: Jeff Mesnil --- api/v1alpha1/wildflyserver_types.go | 4 ++- api/v1alpha1/zz_generated.openapi.go | 2 +- ...ildfly-operator.clusterserviceversion.yaml | 9 +++++++ go.sum | 2 ++ main.go | 2 +- pkg/resources/statefulsets/statefulset.go | 26 +++++++++++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/api/v1alpha1/wildflyserver_types.go b/api/v1alpha1/wildflyserver_types.go index 758b7ef3..277cc387 100644 --- a/api/v1alpha1/wildflyserver_types.go +++ b/api/v1alpha1/wildflyserver_types.go @@ -67,7 +67,9 @@ type WildFlyServerSpec struct { // ResourcesSpec defines the resources used by the WildFlyServer, ie CPU and memory, use limits and requests. // More info: https://pkg.go.dev/k8s.io/api@v0.18.14/core/v1#ResourceRequirements Resources *corev1.ResourceRequirements `json:"resources,omitempty"` - // SecurityContext + // SecurityContext defines the security capabilities required to run the application. + // If omitted, a default security context is created which runs with a non-root "jboss (185)" user without priviledges + // escalation and all security capabilities dropped. SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"` } diff --git a/api/v1alpha1/zz_generated.openapi.go b/api/v1alpha1/zz_generated.openapi.go index d3f7b6fd..affa7343 100644 --- a/api/v1alpha1/zz_generated.openapi.go +++ b/api/v1alpha1/zz_generated.openapi.go @@ -323,7 +323,7 @@ func schema__api_v1alpha1_WildFlyServerSpec(ref common.ReferenceCallback) common }, "securityContext": { SchemaProps: spec.SchemaProps{ - Description: "SecurityContext", + Description: "SecurityContext defines the security capabilities required to run the application. If omitted, a default security context is created which runs with a non-root \"jboss (185)\" user without priviledges escalation and all security capabilities dropped.", Ref: ref("k8s.io/api/core/v1.SecurityContext"), }, }, diff --git a/bundle/manifests/wildfly-operator.clusterserviceversion.yaml b/bundle/manifests/wildfly-operator.clusterserviceversion.yaml index aa16a597..0ced7284 100644 --- a/bundle/manifests/wildfly-operator.clusterserviceversion.yaml +++ b/bundle/manifests/wildfly-operator.clusterserviceversion.yaml @@ -95,7 +95,16 @@ spec: requests: cpu: 100m memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL serviceAccountName: wildfly-operator + securityContext: + seccompProfile: + type: RuntimeDefault terminationGracePeriodSeconds: 10 permissions: - rules: diff --git a/go.sum b/go.sum index 9bab4bea..a5f77821 100644 --- a/go.sum +++ b/go.sum @@ -696,6 +696,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1089,6 +1090,7 @@ k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= diff --git a/main.go b/main.go index 754966f5..98e08fbf 100644 --- a/main.go +++ b/main.go @@ -74,7 +74,7 @@ func main() { flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") opts := zap.Options{ - // Development: true, // Commented out to use default production options + // Development: true, // Commented out to use default production options } opts.BindFlags(flag.CommandLine) flag.Parse() diff --git a/pkg/resources/statefulsets/statefulset.go b/pkg/resources/statefulsets/statefulset.go index b2e4ddbd..80aec472 100644 --- a/pkg/resources/statefulsets/statefulset.go +++ b/pkg/resources/statefulsets/statefulset.go @@ -56,6 +56,15 @@ func NewStatefulSet(w *wildflyv1alpha1.WildFlyServer, labels map[string]string, wildflyImageTypeAnnotation = resources.ImageTypeBootable } + allowPrivilegeEscalation := new(bool) + *allowPrivilegeEscalation = false + + runAsNonRoot := new(bool) + *runAsNonRoot = true + + jbossUser := new(int64) + *jbossUser = 185 + statefulSet := &appsv1.StatefulSet{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", @@ -84,6 +93,11 @@ func NewStatefulSet(w *wildflyv1alpha1.WildFlyServer, labels map[string]string, }, }, Spec: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, Containers: []corev1.Container{{ Name: w.Name, Image: applicationImage, @@ -119,6 +133,18 @@ func NewStatefulSet(w *wildflyv1alpha1.WildFlyServer, labels map[string]string, // if the user specified the securityContext directive propagate it to the container (required for HPA). if w.Spec.SecurityContext != nil { statefulSet.Spec.Template.Spec.Containers[0].SecurityContext = *&w.Spec.SecurityContext + } else { + // otherwise, use a default security context without any security priviledges + statefulSet.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{ + AllowPrivilegeEscalation: allowPrivilegeEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: runAsNonRoot, + RunAsUser: jbossUser, + } } if len(w.Spec.EnvFrom) > 0 {