Keep the forge credential out of what a check's container sees, and redact what a check publishes (issue 462)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without …
mesh/repo-check pass: its merge-check.sh passed

The toolchain container mounts the workspace as HOME, so the credential kept
there, and a clone's recorded userinfo, were readable by any pull request; its
output is kept on the bus for days. The credential now lives in a private
directory outside the workspace only while cloning, clones record their URL
without userinfo, and every line said to the build's log and the verdict
passes a redactor copied from the journal tool (sharing it: issue 471).
This commit is contained in:
2026-10-11 11:20:10 +02:00
parent 3b6b54a501
commit c494ed03a7
5 changed files with 497 additions and 33 deletions
+19 -15
View File
@@ -438,30 +438,34 @@ func TestABuildOffersTheForgesCredentialThroughGitsOwnStore(t *testing.T) {
if err != nil {
t.Fatal(err)
}
stored := filepath.Join(workspace, "git-credentials")
clone := r.ran[0]
if !strings.Contains(clone, "credential.helper=store --file="+stored) {
t.Fatalf("the clone does not name the credential store: %s", clone)
}
stored := storeNamedIn(t, clone)
for _, line := range r.ran {
if strings.Contains(line, "sw0rdfi5h") {
t.Fatalf("the secret is in a command line, readable by anything that can list processes: %s", line)
}
}
raw, err := os.ReadFile(stored)
if err != nil {
t.Fatal(err)
// Outside the workspace a check's container mounts, and gone once the build is (novox/hq issue 462); what
// it held while git read it is checked with the check's clones (TestACheckContainerSeesNoForgeCredential).
if withinDir(workspace, stored) {
t.Fatalf("the credential store %s is inside the workspace %s", stored, workspace)
}
if strings.TrimSpace(string(raw)) != "http://mesh_novox_builder:sw0rdfi5h@forge.invalid:20000" {
t.Fatalf("the store does not hold the credential as given: %q", raw)
if _, err := os.Stat(stored); !os.IsNotExist(err) {
t.Fatalf("the credential store outlives the build: %v", err)
}
info, err := os.Stat(stored)
if err != nil {
t.Fatal(err)
if _, err := os.Stat(filepath.Join(workspace, "git-credentials")); !os.IsNotExist(err) {
t.Fatal("a credential file is left in the workspace")
}
if info.Mode().Perm() != 0o600 {
t.Fatalf("the credential file is readable beyond its owner: %v", info.Mode())
}
// storeNamedIn is the credential store a git command line offers.
func storeNamedIn(t *testing.T, line string) string {
t.Helper()
_, after, ok := strings.Cut(line, "credential.helper=store --file=")
if !ok {
t.Fatalf("the clone does not name the credential store: %s", line)
}
return strings.Fields(after)[0]
}
// Without a credential, a clone is exactly the invocation it always was, and no credential file
@@ -506,7 +510,7 @@ func TestAContextCloneCarriesTheSameCredentialStore(t *testing.T) {
if err != nil {
t.Fatal(err)
}
stored := filepath.Join(workspace, "git-credentials")
stored := storeNamedIn(t, r.ran[0])
var contextClone string
for _, line := range r.ran {
if strings.Contains(line, "clone") && strings.Contains(line, "source.git") {