diff --git a/README.md b/README.md index 5b3b18867..c6057390f 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ expect - see [Known Issues](#known-issues). - [Flag `FF_KANIKO_SECUREJOIN_EXTRACTION`](#flag-ff_kaniko_securejoin_extraction) - [Flag `FF_KANIKO_RESOLVE_CACHE_KEY`](#flag-ff_kaniko_resolve_cache_key) - [Flag `FF_KANIKO_UNTAR_SKIP_ROOT`](#flag-ff_kaniko_untar_skip_root) + - [Flag `FF_KANIKO_RUN_HONOR_GROUP`](#flag-ff_kaniko_run_honor_group) - [Assertion Overrides](#assertion-overrides) - [Debug Image](#debug-image) - [Security](#security) @@ -1305,6 +1306,13 @@ Set this flag to `true` to skip the root `.` entry when untarring. Defaults to `false`. Becomes default in `v1.29.0`. +#### Flag `FF_KANIKO_RUN_HONOR_GROUP` + +When a stage sets `USER user:group`, `RUN` applies only the user and the gid falls back to the user's primary group, so an explicit group is silently dropped. +Set this flag to `true` to pass the full `user:group` to the command so `RUN` runs with the requested group, matching docker. +Defaults to `false`. +Becomes default in `v1.29.0`. + ### Assertion Overrides Kaniko checks internal invariants at runtime. If one is violated the build stops with a message like: diff --git a/integration/dockerfiles/Dockerfile_test_issue_mz839 b/integration/dockerfiles/Dockerfile_test_issue_mz839 new file mode 100644 index 000000000..334f728a8 --- /dev/null +++ b/integration/dockerfiles/Dockerfile_test_issue_mz839 @@ -0,0 +1,7 @@ +# mz839: USER user:group must run RUN with the explicit group. +# kaniko v1.27.6 drops the group and the gid falls back to the user's primary +# group, so the recorded gid is 0 instead of 4242. +FROM debian:12.10 +RUN groupadd -g 4242 testgroup +USER root:testgroup +RUN echo "gid=$(id -g)" > /result.txt diff --git a/integration/images.go b/integration/images.go index d562468ee..d41dedbf2 100644 --- a/integration/images.go +++ b/integration/images.go @@ -112,6 +112,7 @@ var KanikoEnv = []string{ "FF_KANIKO_RESOLVE_CACHE_KEY=1", "FF_KANIKO_UNTAR_SKIP_ROOT=1", "FF_KANIKO_REPRODUCIBLE_PRESERVE_BASE_LAYERS=1", + "FF_KANIKO_RUN_HONOR_GROUP=1", "KANIKO_PRINT_PLAN=1", } diff --git a/pkg/commands/run.go b/pkg/commands/run.go index bc2638e3e..cab1301c8 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -357,9 +357,17 @@ func runCommandInExec(config *v1.Config, buildArgs *dockerfile.BuildArgs, cmdRun return fmt.Errorf("resolving user %s: %w", userAndGroup[0], err) } + credential := userStr + if kConfig.EnvBool("FF_KANIKO_RUN_HONOR_GROUP") { + credential, err = util.ResolveEnvironmentReplacement(u, replacementEnvs, false) + if err != nil { + return fmt.Errorf("resolving user %s: %w", u, err) + } + } + // If specified, run the command as a specific user - if userStr != "" { - cmd.SysProcAttr.Credential, err = util.SyscallCredentials(userStr) + if credential != "" { + cmd.SysProcAttr.Credential, err = util.SyscallCredentials(credential) if err != nil { return fmt.Errorf("credentials: %w", err) }