Skip to content

Commit

Permalink
Update eventlistener podSeurityContext to adhere to restricted pod se…
Browse files Browse the repository at this point in the history
…curity standards

Alter podSecurityContext to include seccompProfile, runAsUser, runAsGroup and fsGroup
when set-security-context is set.

As podSecurityContext only included runAsNonRoot, which could cause injected sidecars
to miss some required restricted pod security standards securityContext
fields.
  • Loading branch information
kristofferchr committed Jul 2, 2024
1 parent 0681097 commit 53e47ba
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 44 deletions.
8 changes: 4 additions & 4 deletions pkg/apis/config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (

const (
defaultServiceAccountKey = "default-service-account"
defaultRunAsUserKey = "default-run-as-user"
defaultRunAsGroupKey = "default-run-as-group"
DefaultRunAsUserKey = "default-run-as-user"
DefaultRunAsGroupKey = "default-run-as-group"
DefaultServiceAccountValue = "default"
defaultRunAsUserValue = 65532
defaultRunAsGroupValue = 65532
Expand Down Expand Up @@ -77,7 +77,7 @@ func NewDefaultsFromMap(cfgMap map[string]string) (*Defaults, error) {
tc.DefaultServiceAccount = defaultServiceAccount
}

if defaultRunAsUser, ok := cfgMap[defaultRunAsUserKey]; ok {
if defaultRunAsUser, ok := cfgMap[DefaultRunAsUserKey]; ok {
if defaultRunAsUser == "" {
tc.DefaultRunAsUser = 0
} else {
Expand All @@ -89,7 +89,7 @@ func NewDefaultsFromMap(cfgMap map[string]string) (*Defaults, error) {
}
}

if defaultRunAsGroup, ok := cfgMap[defaultRunAsGroupKey]; ok {
if defaultRunAsGroup, ok := cfgMap[DefaultRunAsGroupKey]; ok {
if defaultRunAsGroup == "" {
tc.DefaultRunAsGroup = 0
} else {
Expand Down
12 changes: 12 additions & 0 deletions pkg/reconciler/eventlistener/eventlistener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ func makeDeployment(ops ...func(d *appsv1.Deployment)) *appsv1.Deployment {
}},
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: ptr.Bool(true),
RunAsUser: ptr.Int64(65532),
RunAsGroup: ptr.Int64(65532),
FSGroup: ptr.Int64(65532),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
},
},
Expand Down Expand Up @@ -902,6 +908,12 @@ func TestReconcile(t *testing.T) {
deploymentWithSecurityContext := makeDeployment(func(d *appsv1.Deployment) {
d.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
RunAsNonRoot: ptr.Bool(true),
RunAsUser: ptr.Int64(65532),
RunAsGroup: ptr.Int64(65532),
FSGroup: ptr.Int64(65532),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}
d.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
AllowPrivilegeEscalation: ptr.Bool(false),
Expand Down
15 changes: 13 additions & 2 deletions pkg/reconciler/eventlistener/resources/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,22 @@ const (
)

var (
strongerSecurityPolicy = corev1.PodSecurityContext{
baseStrongerSecurityPolicy = corev1.PodSecurityContext{
RunAsNonRoot: ptr.Bool(true),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}
)

func getStrongerSecurityPolicy(cfg *config.Config) corev1.PodSecurityContext {
securityContext := baseStrongerSecurityPolicy
securityContext.RunAsUser = ptr.Int64(cfg.Defaults.DefaultRunAsUser)
securityContext.RunAsGroup = ptr.Int64(cfg.Defaults.DefaultRunAsGroup)
securityContext.FSGroup = ptr.Int64(cfg.Defaults.DefaultRunAsGroup)
return securityContext
}

func MakeDeployment(ctx context.Context, el *v1beta1.EventListener, configAcc reconcilersource.ConfigAccessor, c Config, cfg *config.Config) (*appsv1.Deployment, error) {
opt, err := addDeploymentBits(el, c)
if err != nil {
Expand Down Expand Up @@ -101,7 +112,7 @@ func MakeDeployment(ctx context.Context, el *v1beta1.EventListener, configAcc re

var securityContext corev1.PodSecurityContext
if *c.SetSecurityContext {
securityContext = strongerSecurityPolicy
securityContext = getStrongerSecurityPolicy(cfg)
}

return &appsv1.Deployment{
Expand Down
131 changes: 93 additions & 38 deletions pkg/reconciler/eventlistener/resources/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ func TestDeployment(t *testing.T) {
t.Setenv("METRICS_PROMETHEUS_PORT", "9000")
t.Setenv("SYSTEM_NAMESPACE", "tekton-pipelines")

config := *MakeConfig()
resourcesConfig := *MakeConfig()
labels := map[string]string{
"app.kubernetes.io/managed-by": "EventListener",
"app.kubernetes.io/part-of": "Triggers",
"eventlistener": eventListenerName,
}
expectedSecurityContext := getStrongerSecurityPolicy(cfg.FromContextOrDefaults(context.Background()))

tests := []struct {
name string
el *v1beta1.EventListener
want *appsv1.Deployment
name string
el *v1beta1.EventListener
config *cfg.Config
want *appsv1.Deployment
}{{
name: "vanilla",
el: makeEL(),
Expand All @@ -68,11 +70,11 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
Expand Down Expand Up @@ -103,11 +105,11 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
Expand Down Expand Up @@ -146,11 +148,11 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
Tolerations: []corev1.Toleration{{
Key: "foo",
Value: "bar",
Expand Down Expand Up @@ -192,11 +194,11 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
NodeSelector: map[string]string{
"foo": "bar",
},
Expand Down Expand Up @@ -235,11 +237,11 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "bob",
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
Expand All @@ -265,9 +267,9 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(withTLSEnvFrom("Bill")), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(withTLSEnvFrom("Bill")), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(withTLSEnvFrom("Bill")), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(withTLSEnvFrom("Bill")), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
Volumes: []corev1.Volume{{
Name: "https-connection",
Expand All @@ -277,7 +279,7 @@ func TestDeployment(t *testing.T) {
},
},
}},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
Expand Down Expand Up @@ -319,11 +321,11 @@ func TestDeployment(t *testing.T) {
MaxSkew: 1,
}},
Containers: []corev1.Container{
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
Expand All @@ -349,11 +351,41 @@ func TestDeployment(t *testing.T) {
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(setProbes()), &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(setProbes()), config),
addCertsForSecureConnection(config)),
MakeContainer(makeEL(setProbes()), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
cfg.FromContextOrDefaults(context.Background()), mustAddDeployBits(t, makeEL(setProbes()), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: &strongerSecurityPolicy,
SecurityContext: &expectedSecurityContext,
},
},
},
}}, {
name: "with overridden runAsGroup, runAsUser, fsGroup",
el: makeEL(setProbes()),
config: getConfigWithoverriddenRunAsGroupAndRunAsUser(),
want: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "",
Namespace: namespace,
Labels: labels,
OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(makeEL())},
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: labels,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
},
Spec: corev1.PodSpec{
ServiceAccountName: "sa",
Containers: []corev1.Container{
MakeContainer(makeEL(setProbes()), &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
getConfigWithoverriddenRunAsGroupAndRunAsUser(), mustAddDeployBits(t, makeEL(setProbes()), resourcesConfig),
addCertsForSecureConnection(resourcesConfig)),
},
SecurityContext: getSecurityContextWithoverriddenRunAsGroupAndRunAsUser(expectedSecurityContext),
},
},
},
Expand All @@ -362,8 +394,12 @@ func TestDeployment(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := MakeDeployment(context.Background(), tt.el, &reconcilersource.EmptyVarsGenerator{}, config,
cfg.FromContextOrDefaults(context.Background()))
config := tt.config
if config == nil {
config = cfg.FromContextOrDefaults(context.Background())
}
got, err := MakeDeployment(context.Background(), tt.el, &reconcilersource.EmptyVarsGenerator{}, resourcesConfig,
config)
if err != nil {
t.Fatalf("MakeDeployment() = %v", err)
}
Expand All @@ -374,6 +410,25 @@ func TestDeployment(t *testing.T) {
}
}

func getSecurityContextWithoverriddenRunAsGroupAndRunAsUser(securityContext corev1.PodSecurityContext) *corev1.PodSecurityContext {
securityContextCopy := securityContext.DeepCopy()
securityContextCopy.RunAsUser = ptr.Int64(0)
securityContextCopy.RunAsGroup = ptr.Int64(0)
securityContextCopy.FSGroup = ptr.Int64(0)
return securityContextCopy
}

func getConfigWithoverriddenRunAsGroupAndRunAsUser() *cfg.Config {
config := cfg.FromContextOrDefaults(context.Background())
defaults, err := cfg.NewDefaultsFromMap(map[string]string{cfg.DefaultRunAsGroupKey: "0", cfg.DefaultRunAsUserKey: "0"})
if err != nil {
panic(err)
}

config.Defaults = defaults
return config
}

func TestDeploymentError(t *testing.T) {
t.Setenv("METRICS_PROMETHEUS_PORT", "bad")
got, err := MakeDeployment(context.Background(), makeEL(), &reconcilersource.EmptyVarsGenerator{}, *MakeConfig(),
Expand Down

0 comments on commit 53e47ba

Please sign in to comment.