Skip to content

Commit 2474af6

Browse files
kristofferchrtekton-robot
authored andcommitted
Add new flag set-read-only-root-filesystem to set readOnlyRootFilesysem for EventListener
Add new flag set-read-only-root-filesystem. Sets container securityContext readOnlyRootFilesystem to true when new flag is set to true Prior to this it was not possible to set readOnlyRootFilesystem for EventListener container. Aligns security towards azure aks best practices and industry
1 parent 8d22a77 commit 2474af6

File tree

7 files changed

+122
-60
lines changed

7 files changed

+122
-60
lines changed

cmd/controller/main.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,16 @@ const (
3939
)
4040

4141
var (
42-
image = flag.String("el-image", elresources.DefaultImage, "The container image for the EventListener Pod.")
43-
port = flag.Int("el-port", elresources.DefaultPort, "The container port for the EventListener to listen on.")
44-
setSecurityContext = flag.Bool("el-security-context", elresources.DefaultSetSecurityContext, "Add a security context to the event listener deployment.")
45-
setEventListenerEvent = flag.String("el-events", elresources.DefaultEventListenerEvent, "Enable events for event listener deployment.")
46-
readTimeOut = flag.Int64("el-readtimeout", elresources.DefaultReadTimeout, "The read timeout for EventListener Server.")
47-
writeTimeOut = flag.Int64("el-writetimeout", elresources.DefaultWriteTimeout, "The write timeout for EventListener Server.")
48-
idleTimeOut = flag.Int64("el-idletimeout", elresources.DefaultIdleTimeout, "The idle timeout for EventListener Server.")
49-
timeOutHandler = flag.Int64("el-timeouthandler", elresources.DefaultTimeOutHandler, "The timeout for Timeout Handler of EventListener Server.")
50-
httpClientReadTimeOut = flag.Int64("el-httpclient-readtimeout", elresources.DefaultHTTPClientReadTimeOut,
42+
image = flag.String("el-image", elresources.DefaultImage, "The container image for the EventListener Pod.")
43+
port = flag.Int("el-port", elresources.DefaultPort, "The container port for the EventListener to listen on.")
44+
setSecurityContext = flag.Bool("el-security-context", elresources.DefaultSetSecurityContext, "Add a security context to the event listener deployment.")
45+
setReadOnlyRootFilesystem = flag.Bool("el-read-only-root-filesystem", elresources.DefaultSetReadOnlyRootFilesystem, "Sets readOnlyRootFilesystem to the provided value for the event listener deployment. Note: only applied when flag el-security-context is set to true.")
46+
setEventListenerEvent = flag.String("el-events", elresources.DefaultEventListenerEvent, "Enable events for event listener deployment.")
47+
readTimeOut = flag.Int64("el-readtimeout", elresources.DefaultReadTimeout, "The read timeout for EventListener Server.")
48+
writeTimeOut = flag.Int64("el-writetimeout", elresources.DefaultWriteTimeout, "The write timeout for EventListener Server.")
49+
idleTimeOut = flag.Int64("el-idletimeout", elresources.DefaultIdleTimeout, "The idle timeout for EventListener Server.")
50+
timeOutHandler = flag.Int64("el-timeouthandler", elresources.DefaultTimeOutHandler, "The timeout for Timeout Handler of EventListener Server.")
51+
httpClientReadTimeOut = flag.Int64("el-httpclient-readtimeout", elresources.DefaultHTTPClientReadTimeOut,
5152
"The HTTP Client read timeout for EventListener Server.")
5253
httpClientKeepAlive = flag.Int64("el-httpclient-keep-alive", elresources.DefaultHTTPClientKeepAlive,
5354
"The HTTP Client read timeout for EventListener Server.")
@@ -71,6 +72,7 @@ func main() {
7172
Image: image,
7273
Port: port,
7374
SetSecurityContext: setSecurityContext,
75+
SetReadOnlyRootFilesystem: setReadOnlyRootFilesystem,
7476
SetEventListenerEvent: setEventListenerEvent,
7577
ReadTimeOut: readTimeOut,
7678
WriteTimeOut: writeTimeOut,

config/controller.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ spec:
6060
"-el-port",
6161
"8080",
6262
"-el-security-context=true",
63+
"-el-read-only-root-filesystem=true",
6364
"-el-events",
6465
"disable",
6566
"-el-readtimeout",

pkg/reconciler/eventlistener/eventlistener_test.go

+49-9
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,10 @@ func makeDeployment(ops ...func(d *appsv1.Deployment)) *appsv1.Deployment {
281281
Drop: []corev1.Capability{"ALL"},
282282
},
283283
// 65532 is the distroless nonroot user ID
284-
RunAsUser: ptr.Int64(65532),
285-
RunAsGroup: ptr.Int64(65532),
286-
RunAsNonRoot: ptr.Bool(true),
284+
RunAsUser: ptr.Int64(65532),
285+
RunAsGroup: ptr.Int64(65532),
286+
RunAsNonRoot: ptr.Bool(true),
287+
ReadOnlyRootFilesystem: ptr.Bool(true),
287288
SeccompProfile: &corev1.SeccompProfile{
288289
Type: corev1.SeccompProfileTypeRuntimeDefault,
289290
},
@@ -442,9 +443,10 @@ func makeWithPod(ops ...func(d *duckv1.WithPod)) *duckv1.WithPod {
442443
Drop: []corev1.Capability{"ALL"},
443444
},
444445
// 65532 is the distroless nonroot user ID
445-
RunAsUser: ptr.Int64(65532),
446-
RunAsGroup: ptr.Int64(65532),
447-
RunAsNonRoot: ptr.Bool(true),
446+
RunAsUser: ptr.Int64(65532),
447+
RunAsGroup: ptr.Int64(65532),
448+
RunAsNonRoot: ptr.Bool(true),
449+
ReadOnlyRootFilesystem: ptr.Bool(true),
448450
SeccompProfile: &corev1.SeccompProfile{
449451
Type: corev1.SeccompProfileTypeRuntimeDefault,
450452
},
@@ -593,6 +595,10 @@ func TestReconcile(t *testing.T) {
593595
c.SetSecurityContext = ptr.Bool(false)
594596
})
595597

598+
configWithSetReadOnlyRootFilesystemFalse := resources.MakeConfig(func(c *resources.Config) {
599+
c.SetReadOnlyRootFilesystem = ptr.Bool(false)
600+
})
601+
596602
configWithSetSecurityContext := resources.MakeConfig(func(c *resources.Config) {
597603
c.SetSecurityContext = ptr.Bool(true)
598604
})
@@ -891,6 +897,24 @@ func TestReconcile(t *testing.T) {
891897
d.Spec.Template.Spec.Containers[0].VolumeMounts = nil
892898
})
893899

900+
deploymentMissingReadOnlyRootFilesystem := makeDeployment(func(d *appsv1.Deployment) {
901+
d.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
902+
RunAsNonRoot: ptr.Bool(true),
903+
}
904+
d.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
905+
AllowPrivilegeEscalation: ptr.Bool(false),
906+
Capabilities: &corev1.Capabilities{
907+
Drop: []corev1.Capability{"ALL"},
908+
},
909+
RunAsNonRoot: ptr.Bool(true),
910+
RunAsUser: ptr.Int64(65532),
911+
RunAsGroup: ptr.Int64(65532),
912+
SeccompProfile: &corev1.SeccompProfile{
913+
Type: corev1.SeccompProfileTypeRuntimeDefault,
914+
},
915+
}
916+
})
917+
894918
deploymentMissingSecurityContext := makeDeployment(func(d *appsv1.Deployment) {
895919
d.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{}
896920
d.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
@@ -908,9 +932,10 @@ func TestReconcile(t *testing.T) {
908932
Capabilities: &corev1.Capabilities{
909933
Drop: []corev1.Capability{"ALL"},
910934
},
911-
RunAsNonRoot: ptr.Bool(true),
912-
RunAsUser: ptr.Int64(65532),
913-
RunAsGroup: ptr.Int64(65532),
935+
RunAsNonRoot: ptr.Bool(true),
936+
ReadOnlyRootFilesystem: ptr.Bool(true),
937+
RunAsUser: ptr.Int64(65532),
938+
RunAsGroup: ptr.Int64(65532),
914939
SeccompProfile: &corev1.SeccompProfile{
915940
Type: corev1.SeccompProfileTypeRuntimeDefault,
916941
},
@@ -1371,6 +1396,21 @@ func TestReconcile(t *testing.T) {
13711396
Deployments: []*appsv1.Deployment{elDeployment},
13721397
Services: []*corev1.Service{elService},
13731398
},
1399+
}, {
1400+
name: "eventlistener with SetReadOnlyRootFilesystem false",
1401+
key: reconcileKey,
1402+
config: configWithSetReadOnlyRootFilesystemFalse,
1403+
startResources: test.Resources{
1404+
Namespaces: []*corev1.Namespace{namespaceResource},
1405+
EventListeners: []*v1beta1.EventListener{elWithStatus},
1406+
Deployments: []*appsv1.Deployment{elDeployment},
1407+
},
1408+
endResources: test.Resources{
1409+
Namespaces: []*corev1.Namespace{namespaceResource},
1410+
EventListeners: []*v1beta1.EventListener{elWithStatus},
1411+
Deployments: []*appsv1.Deployment{deploymentMissingReadOnlyRootFilesystem}, // ReadOnlyRootFilesystem is not set for container
1412+
Services: []*corev1.Service{elService},
1413+
},
13741414
}, {
13751415
name: "eventlistener with SetSecurityContext false",
13761416
key: reconcileKey,

pkg/reconciler/eventlistener/resources/config.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ var (
2323
DefaultPort = 8080
2424
// DefaultSetSecurityContext is the SetSecurityContext value used by default.
2525
DefaultSetSecurityContext = true
26+
// DefaultSetReadOnlyRootFilesystem is the SetReadOnlyRootFilesystem value used by default.
27+
DefaultSetReadOnlyRootFilesystem = true
2628
// DefaultEventListenerEvent is the EventListenerEvent value used by default.
2729
DefaultEventListenerEvent = "disable"
2830
// DefaultReadTimeout is the ReadTimeout used by default.
@@ -63,6 +65,8 @@ type Config struct {
6365
Port *int
6466
// SetSecurityContext defines if the security context is set.
6567
SetSecurityContext *bool
68+
// SetReadOnlyRootFilesystem defines the value for readOnlyRootFilesystem
69+
SetReadOnlyRootFilesystem *bool
6670
// SetEventListenerEvent defines to enable or disable of emitting events for EventListener.
6771
SetEventListenerEvent *string
6872
// ReadTimeOut defines the read timeout for EventListener Server.
@@ -99,11 +103,11 @@ type ConfigOption func(d *Config)
99103
// It generates a default Config for the EventListener without any flags set and accepts functions for modification.
100104
func MakeConfig(ops ...ConfigOption) *Config {
101105
c := &Config{
102-
Image: &DefaultImage,
103-
Port: &DefaultPort,
104-
SetSecurityContext: &DefaultSetSecurityContext,
105-
SetEventListenerEvent: &DefaultEventListenerEvent,
106-
106+
Image: &DefaultImage,
107+
Port: &DefaultPort,
108+
SetSecurityContext: &DefaultSetSecurityContext,
109+
SetEventListenerEvent: &DefaultEventListenerEvent,
110+
SetReadOnlyRootFilesystem: &DefaultSetReadOnlyRootFilesystem,
107111
ReadTimeOut: &DefaultReadTimeout,
108112
WriteTimeOut: &DefaultWriteTimeout,
109113
IdleTimeOut: &DefaultIdleTimeout,

pkg/reconciler/eventlistener/resources/container.go

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ func MakeContainer(el *v1beta1.EventListener, configAcc reconcilersource.ConfigA
6262
Type: corev1.SeccompProfileTypeRuntimeDefault,
6363
},
6464
}
65+
66+
if *c.SetReadOnlyRootFilesystem {
67+
containerSecurityContext.ReadOnlyRootFilesystem = ptr.Bool(true)
68+
}
6569
}
6670

6771
if !cfg.Defaults.IsDefaultRunAsUserEmpty {

pkg/reconciler/eventlistener/resources/container_test.go

+28-21
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,10 @@ func TestContainer(t *testing.T) {
9292
Drop: []corev1.Capability{"ALL"},
9393
},
9494
// 65532 is the distroless nonroot user ID
95-
RunAsUser: ptr.Int64(65532),
96-
RunAsGroup: ptr.Int64(65532),
97-
RunAsNonRoot: ptr.Bool(true),
95+
RunAsUser: ptr.Int64(65532),
96+
RunAsGroup: ptr.Int64(65532),
97+
RunAsNonRoot: ptr.Bool(true),
98+
ReadOnlyRootFilesystem: ptr.Bool(true),
9899
SeccompProfile: &corev1.SeccompProfile{
99100
Type: corev1.SeccompProfileTypeRuntimeDefault,
100101
},
@@ -166,9 +167,10 @@ func TestContainer(t *testing.T) {
166167
Drop: []corev1.Capability{"ALL"},
167168
},
168169
// 65532 is the distroless nonroot user ID
169-
RunAsUser: ptr.Int64(65532),
170-
RunAsGroup: ptr.Int64(65532),
171-
RunAsNonRoot: ptr.Bool(true),
170+
RunAsUser: ptr.Int64(65532),
171+
RunAsGroup: ptr.Int64(65532),
172+
RunAsNonRoot: ptr.Bool(true),
173+
ReadOnlyRootFilesystem: ptr.Bool(true),
172174
SeccompProfile: &corev1.SeccompProfile{
173175
Type: corev1.SeccompProfileTypeRuntimeDefault,
174176
},
@@ -219,9 +221,10 @@ func TestContainer(t *testing.T) {
219221
Drop: []corev1.Capability{"ALL"},
220222
},
221223
// 65532 is the distroless nonroot user ID
222-
RunAsUser: ptr.Int64(65532),
223-
RunAsGroup: ptr.Int64(65532),
224-
RunAsNonRoot: ptr.Bool(true),
224+
RunAsUser: ptr.Int64(65532),
225+
RunAsGroup: ptr.Int64(65532),
226+
RunAsNonRoot: ptr.Bool(true),
227+
ReadOnlyRootFilesystem: ptr.Bool(true),
225228
SeccompProfile: &corev1.SeccompProfile{
226229
Type: corev1.SeccompProfileTypeRuntimeDefault,
227230
},
@@ -281,9 +284,10 @@ func TestContainer(t *testing.T) {
281284
Drop: []corev1.Capability{"ALL"},
282285
},
283286
// 65532 is the distroless nonroot user ID
284-
RunAsUser: ptr.Int64(65532),
285-
RunAsGroup: ptr.Int64(65532),
286-
RunAsNonRoot: ptr.Bool(true),
287+
RunAsUser: ptr.Int64(65532),
288+
RunAsGroup: ptr.Int64(65532),
289+
RunAsNonRoot: ptr.Bool(true),
290+
ReadOnlyRootFilesystem: ptr.Bool(true),
287291
SeccompProfile: &corev1.SeccompProfile{
288292
Type: corev1.SeccompProfileTypeRuntimeDefault,
289293
},
@@ -344,9 +348,10 @@ func TestContainer(t *testing.T) {
344348
Drop: []corev1.Capability{"ALL"},
345349
},
346350
// 65532 is the distroless nonroot user ID
347-
RunAsUser: ptr.Int64(65532),
348-
RunAsGroup: ptr.Int64(65532),
349-
RunAsNonRoot: ptr.Bool(true),
351+
RunAsUser: ptr.Int64(65532),
352+
RunAsGroup: ptr.Int64(65532),
353+
RunAsNonRoot: ptr.Bool(true),
354+
ReadOnlyRootFilesystem: ptr.Bool(true),
350355
SeccompProfile: &corev1.SeccompProfile{
351356
Type: corev1.SeccompProfileTypeRuntimeDefault,
352357
},
@@ -407,9 +412,10 @@ func TestContainer(t *testing.T) {
407412
Drop: []corev1.Capability{"ALL"},
408413
},
409414
// 65532 is the distroless nonroot user ID
410-
RunAsUser: ptr.Int64(65532),
411-
RunAsGroup: ptr.Int64(65532),
412-
RunAsNonRoot: ptr.Bool(true),
415+
RunAsUser: ptr.Int64(65532),
416+
RunAsGroup: ptr.Int64(65532),
417+
RunAsNonRoot: ptr.Bool(true),
418+
ReadOnlyRootFilesystem: ptr.Bool(true),
413419
SeccompProfile: &corev1.SeccompProfile{
414420
Type: corev1.SeccompProfileTypeRuntimeDefault,
415421
},
@@ -471,9 +477,10 @@ func TestContainer(t *testing.T) {
471477
Drop: []corev1.Capability{"ALL"},
472478
},
473479
// 65532 is the distroless nonroot user ID
474-
RunAsUser: ptr.Int64(65532),
475-
RunAsGroup: ptr.Int64(65532),
476-
RunAsNonRoot: ptr.Bool(true),
480+
RunAsUser: ptr.Int64(65532),
481+
RunAsGroup: ptr.Int64(65532),
482+
RunAsNonRoot: ptr.Bool(true),
483+
ReadOnlyRootFilesystem: ptr.Bool(true),
477484
SeccompProfile: &corev1.SeccompProfile{
478485
Type: corev1.SeccompProfileTypeRuntimeDefault,
479486
},

pkg/reconciler/eventlistener/resources/custom_test.go

+20-16
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ func TestCustomObject(t *testing.T) {
155155
"allowPrivilegeEscalation": false,
156156
"capabilities": map[string]interface{}{
157157
"drop": []interface{}{string("ALL")}},
158-
"runAsGroup": int64(65532),
159-
"runAsNonRoot": bool(true),
160-
"runAsUser": int64(65532),
161-
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
158+
"runAsGroup": int64(65532),
159+
"runAsNonRoot": bool(true),
160+
"readOnlyRootFilesystem": bool(true),
161+
"runAsUser": int64(65532),
162+
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
162163
},
163164
"resources": map[string]interface{}{},
164165
"readinessProbe": map[string]interface{}{
@@ -231,10 +232,11 @@ func TestCustomObject(t *testing.T) {
231232
"allowPrivilegeEscalation": false,
232233
"capabilities": map[string]interface{}{
233234
"drop": []interface{}{string("ALL")}},
234-
"runAsGroup": int64(65532),
235-
"runAsNonRoot": bool(true),
236-
"runAsUser": int64(65532),
237-
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
235+
"runAsGroup": int64(65532),
236+
"runAsNonRoot": bool(true),
237+
"readOnlyRootFilesystem": bool(true),
238+
"runAsUser": int64(65532),
239+
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
238240
},
239241
"resources": map[string]interface{}{},
240242
"readinessProbe": map[string]interface{}{
@@ -308,10 +310,11 @@ func TestCustomObject(t *testing.T) {
308310
"allowPrivilegeEscalation": false,
309311
"capabilities": map[string]interface{}{
310312
"drop": []interface{}{string("ALL")}},
311-
"runAsGroup": int64(65532),
312-
"runAsNonRoot": bool(true),
313-
"runAsUser": int64(65532),
314-
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
313+
"runAsGroup": int64(65532),
314+
"runAsNonRoot": bool(true),
315+
"readOnlyRootFilesystem": bool(true),
316+
"runAsUser": int64(65532),
317+
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
315318
},
316319
"readinessProbe": map[string]interface{}{
317320
"httpGet": map[string]interface{}{
@@ -425,10 +428,11 @@ func TestCustomObject(t *testing.T) {
425428
"allowPrivilegeEscalation": false,
426429
"capabilities": map[string]interface{}{
427430
"drop": []interface{}{string("ALL")}},
428-
"runAsGroup": int64(65532),
429-
"runAsNonRoot": bool(true),
430-
"runAsUser": int64(65532),
431-
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
431+
"runAsGroup": int64(65532),
432+
"runAsNonRoot": bool(true),
433+
"readOnlyRootFilesystem": bool(true),
434+
"runAsUser": int64(65532),
435+
"seccompProfile": map[string]interface{}{"type": string("RuntimeDefault")},
432436
},
433437
"readinessProbe": map[string]interface{}{
434438
"httpGet": map[string]interface{}{

0 commit comments

Comments
 (0)