From ee75be342b8d22258fc722dd9ae263a0c3a1b289 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 15 Oct 2025 11:10:27 +0200 Subject: [PATCH] Set secret/config uid:gid to match container's USER Signed-off-by: Nicolas De Loof --- pkg/compose/run.go | 9 ++++-- pkg/compose/secrets.go | 40 ++++++++++++++++++++++++ pkg/e2e/fixtures/env-secret/compose.yaml | 17 ++++++++++ pkg/e2e/secrets_test.go | 15 +++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/pkg/compose/run.go b/pkg/compose/run.go index 242f2fc1c..0e454e6a2 100644 --- a/pkg/compose/run.go +++ b/pkg/compose/run.go @@ -133,12 +133,17 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project, return "", err } - err = s.injectSecrets(ctx, project, service, created.ID) + ctr, err := s.apiClient().ContainerInspect(ctx, created.ID) + if err != nil { + return "", err + } + + err = s.injectSecrets(ctx, project, service, ctr.ID) if err != nil { return created.ID, err } - err = s.injectConfigs(ctx, project, service, created.ID) + err = s.injectConfigs(ctx, project, service, ctr.ID) return created.ID, err } diff --git a/pkg/compose/secrets.go b/pkg/compose/secrets.go index e8064cca8..bd5ca1a90 100644 --- a/pkg/compose/secrets.go +++ b/pkg/compose/secrets.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "strconv" + "strings" "time" "github.com/compose-spec/compose-go/v2/types" @@ -29,6 +30,7 @@ import ( ) func (s *composeService) injectSecrets(ctx context.Context, project *types.Project, service types.ServiceConfig, id string) error { + var ctrConfig *container.Config for _, config := range service.Secrets { file := project.Secrets[config.Source] if file.Environment == "" { @@ -53,6 +55,25 @@ func (s *composeService) injectSecrets(ctx context.Context, project *types.Proje } content = env } + + if config.UID == "" && config.GID == "" { + if ctrConfig == nil { + ctr, err := s.apiClient().ContainerInspect(ctx, id) + if err != nil { + return err + } + ctrConfig = ctr.Config + } + + parts := strings.Split(ctrConfig.User, ":") + if len(parts) > 0 { + config.UID = parts[0] + } + if len(parts) > 1 { + config.GID = parts[1] + } + } + b, err := createTar(content, types.FileReferenceConfig(config)) if err != nil { return err @@ -69,6 +90,7 @@ func (s *composeService) injectSecrets(ctx context.Context, project *types.Proje } func (s *composeService) injectConfigs(ctx context.Context, project *types.Project, service types.ServiceConfig, id string) error { + var ctrConfig *container.Config for _, config := range service.Configs { file := project.Configs[config.Source] content := file.Content @@ -91,6 +113,24 @@ func (s *composeService) injectConfigs(ctx context.Context, project *types.Proje config.Target = "/" + config.Source } + if config.UID == "" && config.GID == "" { + if ctrConfig == nil { + ctr, err := s.apiClient().ContainerInspect(ctx, id) + if err != nil { + return err + } + ctrConfig = ctr.Config + } + + parts := strings.Split(ctrConfig.User, ":") + if len(parts) > 0 { + config.UID = parts[0] + } + if len(parts) > 1 { + config.GID = parts[1] + } + } + b, err := createTar(content, types.FileReferenceConfig(config)) if err != nil { return err diff --git a/pkg/e2e/fixtures/env-secret/compose.yaml b/pkg/e2e/fixtures/env-secret/compose.yaml index 51052d36d..ef272419a 100644 --- a/pkg/e2e/fixtures/env-secret/compose.yaml +++ b/pkg/e2e/fixtures/env-secret/compose.yaml @@ -14,6 +14,23 @@ services: mode: 0440 command: cat /run/secrets/bar + bar: + image: alpine + user: "1005" + secrets: + - source: secret + target: bar + command: cat /run/secrets/bar + + zot: + image: alpine + user: "1005:1005" + secrets: + - source: secret + target: bar + command: cat /run/secrets/bar + + secrets: secret: environment: SECRET diff --git a/pkg/e2e/secrets_test.go b/pkg/e2e/secrets_test.go index 3e3895112..febfdd2b7 100644 --- a/pkg/e2e/secrets_test.go +++ b/pkg/e2e/secrets_test.go @@ -40,6 +40,21 @@ func TestSecretFromEnv(t *testing.T) { }) res.Assert(t, icmd.Expected{Out: "-r--r----- 1 1005 1005"}) }) + t.Run("secret uid from user", func(t *testing.T) { + res := icmd.RunCmd(c.NewDockerComposeCmd(t, "-f", "./fixtures/env-secret/compose.yaml", "run", "bar", "ls", "-al", "/var/run/secrets/bar"), + func(cmd *icmd.Cmd) { + cmd.Env = append(cmd.Env, "SECRET=BAR") + }) + res.Assert(t, icmd.Expected{Out: "-r--r--r-- 1 1005 root"}) + }) + t.Run("secret uid:gid from user", func(t *testing.T) { + res := icmd.RunCmd(c.NewDockerComposeCmd(t, "-f", "./fixtures/env-secret/compose.yaml", "run", "zot", "ls", "-al", "/var/run/secrets/bar"), + func(cmd *icmd.Cmd) { + cmd.Env = append(cmd.Env, "SECRET=BAR") + }) + res.Assert(t, icmd.Expected{Out: "-r--r--r-- 1 1005 1005"}) + }) + } func TestSecretFromInclude(t *testing.T) {