bindings: fix handling of env secrets in remote builds

Previously, using --secret=id=foo,env=BAR in remote mode would fail because the client sent the env var name to the server, which tried to resolve it locally. This patch modifies the client to resolve the environment variable locally, write it to a temp file, and send it as a file-based secret.

Fixes #27494

Signed-off-by: ZuhairM7 <ZuhairM7>
Signed-off-by: ZuhairM7 <zuhairmerali@gmail.com>
This commit is contained in:
ZuhairM7 2025-11-29 20:43:20 -06:00 • committed by Matt Heon
parent b17e90703c
commit 4e3dd47967
2 changed files with 26 additions and 2 deletions

View file

@ -626,7 +626,8 @@ func prepareSecrets(secrets []string, contextDir string, tempManager *remote_bui
for _, token := range secretOpt {
opt, val, hasVal := strings.Cut(token, "=")
if hasVal {
if opt == "src" {
switch opt {
case "src":
// read specified secret into a tmp file
// move tmp file to tar and change secret source to relative tmp file
tmpSecretFilePath, err := tempManager.CreateTempSecret(val, contextDir)
@ -639,7 +640,21 @@ func prepareSecrets(secrets []string, contextDir string, tempManager *remote_bui
modifiedSrc := fmt.Sprintf("src=%s", filepath.Base(tmpSecretFilePath))
modifiedOpt = append(modifiedOpt, modifiedSrc)
} else {
case "env":
// read specified env into a tmp file
// move tmp file to tar and change secret source to relative tmp file
secretVal := os.Getenv(val)
tmpSecretFilePath, err := tempManager.CreateTempFileFromReader(contextDir, "podman-build-secret-*", strings.NewReader(secretVal))
if err != nil {
return nil, nil, err
}
// add tmp file to context dir
tarContent = append(tarContent, tmpSecretFilePath)
modifiedSrc := fmt.Sprintf("src=%s", filepath.Base(tmpSecretFilePath))
modifiedOpt = append(modifiedOpt, modifiedSrc)
default:
modifiedOpt = append(modifiedOpt, token)
}
}

View file

@ -99,6 +99,15 @@ var _ = Describe("Podman build", func() {
Expect(session).Should(ExitCleanly())
})
It("podman build with a secret from env", func() {
os.Setenv("MYSECRET", "somesecret")
defer os.Unsetenv("MYSECRET")
session := podmanTest.PodmanExitCleanly("build", "-f", "build/Containerfile.with-secret", "-t", "secret-test", "--secret", "id=mysecret,env=MYSECRET", "build/")
Expect(session.OutputToString()).To(ContainSubstring("somesecret"))
podmanTest.PodmanExitCleanly("rmi", "secret-test")
})
It("podman build with multiple secrets from files", func() {
session := podmanTest.Podman([]string{"build", "-f", "build/Containerfile.with-multiple-secret", "-t", "multiple-secret-test", "--secret", "id=mysecret,src=build/secret.txt", "--secret", "id=mysecret2,src=build/anothersecret.txt", "build/"})
session.WaitWithDefaultTimeout()