Write the package credential only into a build that asks for it

A per-run .npmrc in every build context put a changing credential in COPY . . of
modules that resolve no mesh package — a non-deterministic image (a needless
rollout every build, which recreated the control plane) and a credential in a
build stage. Now it is written only for a package artifact or an image whose
Dockerfile names .npmrc.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-16 12:45:18 +02:00
parent ae55bd7bde
commit 6a7e701629
2 changed files with 71 additions and 28 deletions
+42 -18
View File
@@ -63,10 +63,12 @@ func TestNpmrcDisabledUntilThereIsARegistry(t *testing.T) {
}
}
// The credential reaches an image build as a buildkit secret and never as a file inside the build
// context, because a token copied into a layer is a token published (novox/hq ADR 0076).
func TestAnImageBuildGetsTheCredentialAsASecretNotALayer(t *testing.T) {
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch", "files/x": "y"})
// The credential reaches an image build as an .npmrc inside the build context — for a Dockerfile to
// COPY in a stage it does not publish — and the build runs on the host network so a RUN resolving the
// registry reaches it where the binding says (novox/hq ADR 0076). Not a buildkit secret, because this
// machine's docker may carry no buildx.
func TestAnImageBuildGetsTheCredentialInTheContextAndHostNetwork(t *testing.T) {
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch\nCOPY .npmrc ./", "files/x": "y"})
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm/", Token: "t"}
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, n, nil); err != nil {
@@ -82,33 +84,35 @@ func TestAnImageBuildGetsTheCredentialAsASecretNotALayer(t *testing.T) {
if build == "" {
t.Fatal("no docker build ran")
}
if !strings.Contains(build, "--secret id=npmrc,src=") {
t.Fatalf("the build was not given the credential as a secret: %s", build)
if strings.Contains(build, "--secret") {
t.Fatalf("the build used a buildkit secret, which this path avoids: %s", build)
}
// The .npmrc lives under the workspace, beside the clone, never inside the source tree that is
// the docker context.
if !strings.Contains(build, "--network host") {
t.Fatalf("the build was not given the host network to reach the registry: %s", build)
}
// The .npmrc is written into the build context (the source tree), where a Dockerfile COPYs it.
tree := filepath.Join(workspace, "source")
src := strings.SplitN(strings.SplitN(build, "--secret id=npmrc,src=", 2)[1], " ", 2)[0]
if strings.HasPrefix(src, tree+string(os.PathSeparator)) {
t.Fatalf("the credential file %s is inside the build context %s", src, tree)
}
if _, err := os.Stat(src); err != nil {
t.Fatalf("the credential file the build was pointed at does not exist: %v", err)
npmrc := filepath.Join(tree, ".npmrc")
if _, err := os.Stat(npmrc); err != nil {
t.Fatalf("the credential was not written into the build context: %v", err)
}
}
func TestAnImageBuildWithoutACredentialGetsNoSecret(t *testing.T) {
func TestAnImageBuildWithoutACredentialGetsNoHostNetwork(t *testing.T) {
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch", "files/x": "y"})
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, Npmrc{}, nil); err != nil {
t.Fatalf("the build failed: %v", err)
}
for _, line := range r.ran {
if strings.HasPrefix(line, "docker build") && strings.Contains(line, "--secret") {
t.Fatalf("a build with no credential was still given a secret: %s", line)
if strings.HasPrefix(line, "docker build") && (strings.Contains(line, "--secret") || strings.Contains(line, "--network host")) {
t.Fatalf("a build with no credential was still given build-network or a secret: %s", line)
}
}
tree := filepath.Join(workspace, "source")
if _, err := os.Stat(filepath.Join(tree, ".npmrc")); err == nil {
t.Fatal("an .npmrc was written into a build that has no credential")
}
}
const aPackage = `{"module":"mesh-sdk","version":"1",
@@ -194,3 +198,23 @@ func TestNpmrcRefusesWhenGivenNeitherTokenNorPassword(t *testing.T) {
t.Fatal("a username with no password rendered an .npmrc")
}
}
func TestAnImageThatDoesNotAskForTheCredentialDoesNotGetIt(t *testing.T) {
// A Dockerfile with no .npmrc reference (like the control plane's) must build clean: no .npmrc
// in its context, no host network — so its image stays deterministic and the credential does not
// leak into a build that never resolves a mesh package.
r, workspace := aRepository(t, withBoth, map[string]string{"Dockerfile": "FROM scratch\nCOPY . .", "files/x": "y"})
n := Npmrc{Scope: "@novox", Registry: "https://forge.invalid/api/packages/novox/npm/", Token: "t"}
if _, err := Build(context.Background(), r.run, r,
"https://forge.invalid/meshboard.git", "", "", workspace, nil, n, nil); err != nil {
t.Fatalf("the build failed: %v", err)
}
for _, line := range r.ran {
if strings.HasPrefix(line, "docker build") && strings.Contains(line, "--network host") {
t.Fatalf("a build that does not ask for the credential got the host network: %s", line)
}
}
if _, err := os.Stat(filepath.Join(workspace, "source", ".npmrc")); err == nil {
t.Fatal("an .npmrc was written into a build that does not reference it")
}
}