From 48eddb08bd0a534f0dae34fdbd6b0f8a9ae32deb Mon Sep 17 00:00:00 2001 From: core-devops Date: Thu, 18 Jun 2026 22:44:53 -0700 Subject: [PATCH] fix(concierge): authenticate the on-box plugin gitea fetch (core#3065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After #872 the concierge runs the standard claude-code image and its plugin boot-install RUNS — but the fetch of the PRIVATE management-MCP plugin repo (molecule-ai-plugin-molecule-platform-mcp) 404s because the on-box curl is UNAUTHENTICATED: setup-gitea-netrc.sh builds ~/.netrc from GIT_HTTP_USERNAME/ GIT_HTTP_PASSWORD, and the concierge has neither (applyAgentGitHTTPCreds reads a per-persona token file; the concierge isn't a fleet persona). Verified live: the archive returns 200 with a valid token, but the box's fetch logs "GIT_HTTP_USERNAME/PASSWORD not set; skipping ~/.netrc" → 404 → plugin never installs → no create_workspace. Fix: conciergePlatformMCPEnv now seeds GIT_HTTP_USERNAME/GIT_HTTP_PASSWORD from the read-only MOLECULE_TEMPLATE_REPO_TOKEN the box already holds, in the SAME basic-auth shape the Go gitea resolver uses (PAT as username + "x-oauth-basic" password — plugins/gitea.go). setIfAbsent so an operator GIT_HTTP_* or a real persona token still wins. The token is read-only and the GIT_HTTP_* names are off the SCM-write denylist (forensic #145), so this grants fetch-only auth. Next link in the concierge→create_workspace chain (after ECR/#3049/#3055/#872). Follow-up (general): setup-gitea-netrc.sh could fall back to MOLECULE_TEMPLATE_REPO_TOKEN so ANY workspace can fetch private declared plugins. Refs core#3065, #872, RFC #3045. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../internal/handlers/platform_agent.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/workspace-server/internal/handlers/platform_agent.go b/workspace-server/internal/handlers/platform_agent.go index 651bb49fb..a081168aa 100644 --- a/workspace-server/internal/handlers/platform_agent.go +++ b/workspace-server/internal/handlers/platform_agent.go @@ -168,6 +168,24 @@ func conciergePlatformMCPEnv(env map[string]string) { } setIfAbsent("MOLECULE_API_URL", apiURL) setIfAbsent("MOLECULE_ORG_ID", os.Getenv("MOLECULE_ORG_ID")) + + // Authenticate the on-box plugin boot-install's gitea fetch (core#3065). + // The concierge declares its management MCP as a PRIVATE gitea:// plugin + // (molecule-ai-plugin-molecule-platform-mcp). The runtime's boot-install + // fetches it via curl + ~/.netrc, which setup-gitea-netrc.sh builds from + // GIT_HTTP_USERNAME / GIT_HTTP_PASSWORD. The concierge has no per-persona git + // token (applyAgentGitHTTPCreds no-ops for it), so without these the fetch is + // UNAUTHENTICATED → 404 on the private repo → plugin never installs → no + // create_workspace (verified live post-#872). Use the read-only + // MOLECULE_TEMPLATE_REPO_TOKEN the box already holds for fetching template/ + // plugin repos, in the SAME basic-auth shape the Go gitea resolver uses (the + // PAT as the username + literal "x-oauth-basic" password — see + // plugins/gitea.go resolveURL). setIfAbsent so an operator-supplied GIT_HTTP_* + // or a real persona token still wins. + if tok := strings.TrimSpace(os.Getenv("MOLECULE_TEMPLATE_REPO_TOKEN")); tok != "" { + setIfAbsent("GIT_HTTP_USERNAME", tok) + setIfAbsent("GIT_HTTP_PASSWORD", "x-oauth-basic") + } } // applyConciergeProvisionConfig is the provision-time hook for the platform -- 2.52.0