From d69b757135c824e174b79cd9c589a596364e75d2 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Tue, 2 Jun 2026 03:54:03 +0000 Subject: [PATCH] fix(admin-images): use StdEncoding for Docker RegistryAuth header ghcrAuthHeader() used base64.URLEncoding, but Docker's RegistryAuth field expects standard base64 (StdEncoding). URL-safe encoding uses -_ instead of +/ and omits padding, which the Docker daemon may not accept for authenticated GHCR pulls. Tests updated to decode with StdEncoding. Fixes #2030 Co-Authored-By: Claude Opus 4.7 --- .../internal/handlers/admin_workspace_images.go | 2 +- .../internal/handlers/admin_workspace_images_test.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/workspace-server/internal/handlers/admin_workspace_images.go b/workspace-server/internal/handlers/admin_workspace_images.go index c408f149c..9e5dacd96 100644 --- a/workspace-server/internal/handlers/admin_workspace_images.go +++ b/workspace-server/internal/handlers/admin_workspace_images.go @@ -97,7 +97,7 @@ func ghcrAuthHeader() string { log.Printf("workspace-images: failed to marshal GHCR auth: %v", err) return "" } - return base64.URLEncoding.EncodeToString(js) + return base64.StdEncoding.EncodeToString(js) } // Refresh pulls the requested runtimes' template images from GHCR and (if diff --git a/workspace-server/internal/handlers/admin_workspace_images_test.go b/workspace-server/internal/handlers/admin_workspace_images_test.go index 411cba5a4..16e4508be 100644 --- a/workspace-server/internal/handlers/admin_workspace_images_test.go +++ b/workspace-server/internal/handlers/admin_workspace_images_test.go @@ -40,9 +40,9 @@ func TestGHCRAuthHeader_EncodesDockerEnginePayload(t *testing.T) { if got == "" { t.Fatal("expected non-empty auth header") } - raw, err := base64.URLEncoding.DecodeString(got) + raw, err := base64.StdEncoding.DecodeString(got) if err != nil { - t.Fatalf("auth header is not valid base64-url: %v", err) + t.Fatalf("auth header is not valid base64: %v", err) } var payload map[string]string if err := json.Unmarshal(raw, &payload); err != nil { @@ -73,9 +73,9 @@ func TestGHCRAuthHeader_RespectsRegistryEnv(t *testing.T) { if got == "" { t.Fatal("expected non-empty auth header") } - raw, err := base64.URLEncoding.DecodeString(got) + raw, err := base64.StdEncoding.DecodeString(got) if err != nil { - t.Fatalf("auth header is not valid base64-url: %v", err) + t.Fatalf("auth header is not valid base64: %v", err) } var payload map[string]string if err := json.Unmarshal(raw, &payload); err != nil { @@ -100,7 +100,7 @@ func TestGHCRAuthHeader_TrimsWhitespace(t *testing.T) { t.Setenv("GHCR_USER", " alice ") t.Setenv("GHCR_TOKEN", "\tfake-tok-value\n") got := ghcrAuthHeader() - raw, _ := base64.URLEncoding.DecodeString(got) + raw, _ := base64.StdEncoding.DecodeString(got) var payload map[string]string _ = json.Unmarshal(raw, &payload) if payload["username"] != "alice" { -- 2.52.0