From a67d5592bcb577235c743cf8bbfdc8db39615a98 Mon Sep 17 00:00:00 2001 From: Lukas Piwowarski Date: Mon, 12 Oct 2026 15:22:46 +0200 Subject: [PATCH] fix: Goose pod security context When .spec.storage is configured, Goose uses the mounted volume as its working directory. A root-owned PVC prevents the Goose process, which runs as UID/GID 1000, from writing its home-directory data under /home/goose, including configuration and transcripts: mkdir: cannot create directory '/home/goose/.config': Permission denied Apply the standard restrictive pod and container security contexts with Goose UID/GID 1000, matching openstackclient. Set fsGroup to 1000 so supported PVC-backed working directories are group-writable and Goose can persist its home-directory data. Depends-On: https://github.com/openstack-k8s-operators/lib-common/pull/780 --- go.mod | 2 +- go.sum | 4 ++-- internal/openstackassistant/funcs.go | 23 +++++++++-------------- internal/openstackassistant/funcs_test.go | 11 +++++++++++ 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index f123f99433..a41de19703 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261010081703-9c4377961aa3 github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261010081703-9c4377961aa3 github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20261010081703-9c4377961aa3 - github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261010081703-9c4377961aa3 + github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261013151427-9b94821abb9f github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20261009185949-45a01e060edc github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260927135032-f0eb46b149d8 github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20261010070417-2d01164c96e3 diff --git a/go.sum b/go.sum index d503156915..a7a231209c 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.202610100 github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261010081703-9c4377961aa3/go.mod h1:zPIkK2aNVGCxyf8Yg2iAaiCH3Wu2G/kjft+CAVs1cgQ= github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20261010081703-9c4377961aa3 h1:MdMKJX/i1N4v8AA3Fb2EcysrBmGEoXJE5QdMltE0s2E= github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20261010081703-9c4377961aa3/go.mod h1:enei+rhzWgyEqqcrh/1V42M9exsotXPnmsj48g1nqD0= -github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261010081703-9c4377961aa3 h1:WKWVyxCkEtqHND8TTEiJsl8R8fcDNXZS7zDzmHgFQFQ= -github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261010081703-9c4377961aa3/go.mod h1:jmVVRfwuFQ3fHLIOAkUrtLgOwEL6j45POzS3PBJuwyM= +github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261013151427-9b94821abb9f h1:S7PrjI50BUnpU8MWYQdFC5j8KGUqengL+AqovnCzC5U= +github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261013151427-9b94821abb9f/go.mod h1:jmVVRfwuFQ3fHLIOAkUrtLgOwEL6j45POzS3PBJuwyM= github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20261009185949-45a01e060edc h1:m+T2nPcN3RkV8rnrwLaZzeEu3kTjffOja97IoA4g/F4= github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20261009185949-45a01e060edc/go.mod h1:4ii2iCFBbSd3Ns3OxwmtxLg0Vm/zX+ZGKUDuBRoJ+Xg= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260927135032-f0eb46b149d8 h1:83bv+O9Xoiio4bUrjno/Z1QgfWF/BnF3TPY25gChU4k= diff --git a/internal/openstackassistant/funcs.go b/internal/openstackassistant/funcs.go index 2369b7840e..8bbeb9d31d 100644 --- a/internal/openstackassistant/funcs.go +++ b/internal/openstackassistant/funcs.go @@ -20,7 +20,9 @@ import ( "unicode" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" + "github.com/openstack-k8s-operators/lib-common/modules/common/pod" "github.com/openstack-k8s-operators/lib-common/modules/common/tls" + "github.com/openstack-k8s-operators/lib-common/modules/users" assistantv1 "github.com/openstack-k8s-operators/openstack-operator/api/assistant/v1beta1" corev1 "k8s.io/api/core/v1" @@ -143,23 +145,16 @@ func AssistantPodSpecWithCABundle( podSpec := corev1.PodSpec{ TerminationGracePeriodSeconds: ptr.To[int64](0), ServiceAccountName: instance.RbacResourceName(), + SecurityContext: pod.RestrictivePodSecurityContext(users.OpenStackAssistantUID, users.OpenStackAssistantGID), Volumes: volumes, Containers: []corev1.Container{ { - Name: "assistant", - Image: instance.Spec.ContainerImage, - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: ptr.To(true), - AllowPrivilegeEscalation: ptr.To(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - Env: containerEnvs, - VolumeMounts: volumeMounts, - Resources: instance.Spec.Resources, + Name: "assistant", + Image: instance.Spec.ContainerImage, + SecurityContext: pod.RestrictiveSecurityContext(users.OpenStackAssistantUID, users.OpenStackAssistantGID), + Env: containerEnvs, + VolumeMounts: volumeMounts, + Resources: instance.Spec.Resources, }, }, } diff --git a/internal/openstackassistant/funcs_test.go b/internal/openstackassistant/funcs_test.go index 5be79396f0..d650d71ac7 100644 --- a/internal/openstackassistant/funcs_test.go +++ b/internal/openstackassistant/funcs_test.go @@ -17,10 +17,12 @@ import ( "github.com/onsi/gomega" "github.com/openstack-k8s-operators/lib-common/modules/common/tls" + "github.com/openstack-k8s-operators/lib-common/modules/users" assistantv1 "github.com/openstack-k8s-operators/openstack-operator/api/assistant/v1beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" ) func newTestInstance() *assistantv1.OpenStackAssistant { @@ -111,8 +113,17 @@ func TestAssistantPodSpec_SecurityContext(t *testing.T) { instance := newTestInstance() spec := AssistantPodSpec(instance, "hash", nil) + podSC := spec.SecurityContext sc := spec.Containers[0].SecurityContext + g.Expect(podSC.RunAsUser).To(gomega.Equal(ptr.To(users.OpenStackAssistantUID))) + g.Expect(podSC.RunAsGroup).To(gomega.Equal(ptr.To(users.OpenStackAssistantGID))) + g.Expect(podSC.FSGroup).To(gomega.Equal(ptr.To(users.OpenStackAssistantGID))) + g.Expect(podSC.SeccompProfile).To(gomega.Equal(&corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + })) + g.Expect(sc.RunAsUser).To(gomega.Equal(ptr.To(users.OpenStackAssistantUID))) + g.Expect(sc.RunAsGroup).To(gomega.Equal(ptr.To(users.OpenStackAssistantGID))) g.Expect(*sc.RunAsNonRoot).To(gomega.BeTrue()) g.Expect(*sc.AllowPrivilegeEscalation).To(gomega.BeFalse()) g.Expect(sc.Capabilities.Drop).To(gomega.ContainElement(corev1.Capability("ALL")))