From 14391108763ea81e30c6e8da094e67a0161a95cd Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Sat, 12 Sep 2026 00:03:33 -0400 Subject: [PATCH] fix(e2e): default protected images to sandbox user Signed-off-by: Julie Yaunches --- .../checks/build-protected-managed-images.sh | 2 +- ...otected-managed-image-build-script.test.ts | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/scripts/checks/build-protected-managed-images.sh b/scripts/checks/build-protected-managed-images.sh index 89be5293d6..602d1f13da 100755 --- a/scripts/checks/build-protected-managed-images.sh +++ b/scripts/checks/build-protected-managed-images.sh @@ -20,7 +20,7 @@ source_root="$PWD" cache_to="" cache_from="" audit_evidence_from="" -runtime_user="root" +runtime_user="sandbox" while (($# > 0)); do case "$1" in --audit-evidence-from) diff --git a/test/platform/images/protected-managed-image-build-script.test.ts b/test/platform/images/protected-managed-image-build-script.test.ts index f1908755e5..6f7c61222c 100644 --- a/test/platform/images/protected-managed-image-build-script.test.ts +++ b/test/platform/images/protected-managed-image-build-script.test.ts @@ -305,7 +305,7 @@ beforeEach(() => { registryLog = path.join(testRoot, "registry.log"); registryStatus = "404"; teeFailureMode = ""; - imageUser = "root"; + imageUser = "sandbox"; mkdirSync(stubBin); writeExecutable( "docker", @@ -353,37 +353,42 @@ describe("protected managed-image source-root boundary", () => { }); describe("protected managed-image build-cache boundary", () => { - it("keeps the legacy root runtime contract unless a reviewed transition selects sandbox", () => { - stubBuildInvocation(); + it.each(["linux/amd64", "linux/arm64"])( + "builds every agent as sandbox by default on %s", + (platform) => { + stubBuildInvocation(); + + const result = runBuild(REPO_ROOT, [], platform); + + expect(result.status, result.stderr).toBe(0); + expect(recordedBuildInvocations()).toHaveLength(3); + expect( + recordedBuildInvocations().every((invocation) => + invocation.includes("--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox"), + ), + ).toBe(true); + }, + ); - const legacy = runBuild(REPO_ROOT); + it("preserves an explicitly selected runtime user", () => { + stubBuildInvocation(); + imageUser = "root"; + const result = runBuild(REPO_ROOT, ["--runtime-user", "root"]); - expect(legacy.status, legacy.stderr).toBe(0); + expect(result.status, result.stderr).toBe(0); expect(recordedBuildInvocations()).toHaveLength(3); expect( recordedBuildInvocations().every((invocation) => invocation.includes("--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=root"), ), ).toBe(true); - - writeFileSync(dockerLog, "", "utf8"); - imageUser = "sandbox"; - const transitioned = runBuild(REPO_ROOT, ["--runtime-user", "sandbox"]); - - expect(transitioned.status, transitioned.stderr).toBe(0); - expect(recordedBuildInvocations()).toHaveLength(3); - expect( - recordedBuildInvocations().every((invocation) => - invocation.includes("--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox"), - ), - ).toBe(true); }); it("rejects an image whose final Config.User does not match the selected runtime user", () => { stubBuildInvocation(); imageUser = "root"; - const result = runBuild(REPO_ROOT, ["--runtime-user", "sandbox"]); + const result = runBuild(REPO_ROOT); expect(result.status, result.stderr).toBe(1); expect(recordedBuildInvocations()).toHaveLength(1); @@ -411,12 +416,12 @@ describe("protected managed-image build-cache boundary", () => { expect(recordedBuildInvocation("openclaw")).toContain("--platform linux/arm64"); expect(recordedBuildInvocation("openclaw")).toContain("--build-arg TARGETARCH=arm64"); expect(recordedBuildInvocation("openclaw")).toContain( - "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=root", + "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox", ); expect(recordedBuildInvocation("hermes")).toContain("--platform linux/arm64"); expect(recordedBuildInvocation("hermes")).toContain("--build-arg TARGETARCH=arm64"); expect(recordedBuildInvocation("hermes")).toContain( - "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=root", + "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox", ); expect(recordedBuildInvocation("langchain-deepagents-code")).toContain( "--platform linux/arm64", @@ -425,7 +430,7 @@ describe("protected managed-image build-cache boundary", () => { "--build-arg TARGETARCH=arm64", ); expect(recordedBuildInvocation("langchain-deepagents-code")).toContain( - "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=root", + "--build-arg NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox", ); });