Skip to content

Commit b71ef06

Browse files
authored
fix(trace): use CHAINLOOP_TRACE_REDACTED as the redaction placeholder (#3574)
1 parent 7dcee12 commit b71ef06

11 files changed

Lines changed: 43 additions & 43 deletions

File tree

‎app/cli/internal/policydevel/eval_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func TestEvaluateReadsRedactedMaterial(t *testing.T) {
301301
for _, input := range result.DebugInfo.Inputs {
302302
assert.NotContains(t, string(input), fixtureGitHubPAT,
303303
"the policy engine must never receive the un-redacted credential")
304-
assert.Contains(t, string(input), "[REDACTED:")
304+
assert.Contains(t, string(input), "[CHAINLOOP_TRACE_REDACTED:")
305305
}
306306
})
307307
}

‎app/cli/internal/policydevel/testdata/ai-coding-session-no-secrets-policy.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
# replaced it. Unanchored counterpart of
1818
# internal/redaction.IsDefaultPlaceholder.
1919
violations contains msg if {
20-
regex.match(`\[REDACTED(:[^\]\s]*)?\]`, json.marshal(input))
20+
regex.match(`\[CHAINLOOP_TRACE_REDACTED(:[^\]\s]*)?\]`, json.marshal(input))
2121
msg := "secrets were found and redacted in the coding session"
2222
}
2323

‎app/cli/internal/trace/skill/skill_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,17 @@ func TestCopyAndPackage(t *testing.T) {
100100
assert.True(t, strings.HasPrefix(info.Digest, "sha256:"))
101101

102102
redact := func(doc []byte) ([]byte, error) {
103-
return bytes.ReplaceAll(doc, []byte("SECRET"), []byte("[REDACTED]")), nil
103+
return bytes.ReplaceAll(doc, []byte("SECRET"), []byte("[CHAINLOOP_TRACE_REDACTED]")), nil
104104
}
105105

106106
pkg, err := MakePackage(dst, redact)
107107
require.NoError(t, err)
108108

109-
assert.Equal(t, "# Skill\nuse token [REDACTED]\n", string(pkg.Definition))
109+
assert.Equal(t, "# Skill\nuse token [CHAINLOOP_TRACE_REDACTED]\n", string(pkg.Definition))
110110
assert.Equal(t, map[string]string{
111-
DefinitionFile: "# Skill\nuse token [REDACTED]\n",
111+
DefinitionFile: "# Skill\nuse token [CHAINLOOP_TRACE_REDACTED]\n",
112112
"references/rules.md": "the rules",
113-
"scripts/lint.py": "print('[REDACTED]')",
113+
"scripts/lint.py": "print('[CHAINLOOP_TRACE_REDACTED]')",
114114
"examples/before-after.txt": "before and after",
115115
}, archiveFiles(t, pkg.Archive), "version-control folders and files are left out")
116116
})

‎app/cli/pkg/action/trace_spec_materials_test.go‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ func TestAttachSpecs(t *testing.T) {
188188
require.Len(t, adder.added, 1)
189189
// The address is scanned like the text: a token in a URL must not
190190
// survive in the stored file, the annotation or the reference.
191-
wantURI := "https://tracker.example.com/issue/1?token=[REDACTED:github-pat]"
192-
assert.Equal(t, "---\nkind: ticket\nuri: "+wantURI+"\n---\nconfigured with the token [REDACTED:github-pat] and still a 401", adder.added[0].content)
191+
wantURI := "https://tracker.example.com/issue/1?token=[CHAINLOOP_TRACE_REDACTED:github-pat]"
192+
assert.Equal(t, "---\nkind: ticket\nuri: "+wantURI+"\n---\nconfigured with the token [CHAINLOOP_TRACE_REDACTED:github-pat] and still a 401", adder.added[0].content)
193193
assert.Equal(t, wantURI, adder.added[0].annotations[specAnnotationURI])
194194
require.Len(t, entries, 1)
195195
assert.Equal(t, wantURI, entries[0].URI)
@@ -306,8 +306,8 @@ func TestAttachSpecs(t *testing.T) {
306306
entries, _, _, _ := attachSpecs(context.Background(), adder, newSpecRedactor(t.TempDir()), materials.NewNameAllocator(nil), sessionID, []spec.Capture{withSecret}, zerolog.Nop())
307307

308308
require.Len(t, entries, 1)
309-
assert.Equal(t, "token [REDACTED:github-pat] fails", entries[0].Title)
310-
assert.Equal(t, "uses [REDACTED:github-pat]", entries[0].Description)
309+
assert.Equal(t, "token [CHAINLOOP_TRACE_REDACTED:github-pat] fails", entries[0].Title)
310+
assert.Equal(t, "uses [CHAINLOOP_TRACE_REDACTED:github-pat]", entries[0].Description)
311311
assert.Equal(t, entries[0].Title, adder.added[0].annotations[specAnnotationTitle])
312312
assert.Equal(t, entries[0].Description, adder.added[0].annotations[specAnnotationDescription])
313313
})
@@ -328,7 +328,7 @@ func TestAttachSpecs(t *testing.T) {
328328
assert.Equal(t, string(pngBytes), adder.added[0].content, "the binary file is still stored as it is")
329329
require.Len(t, entries, 1)
330330
assert.Equal(t, aicodingsession.SpecRoleReference, entries[0].Role)
331-
assert.Equal(t, "mockup for [REDACTED:github-pat]", entries[0].Title)
331+
assert.Equal(t, "mockup for [CHAINLOOP_TRACE_REDACTED:github-pat]", entries[0].Title)
332332
assert.Equal(t, "Where the button goes.", entries[0].Description)
333333
assert.Equal(t, aicodingsession.SpecRoleReference, adder.added[0].annotations[specAnnotationRole])
334334
assert.Equal(t, entries[0].Title, adder.added[0].annotations[specAnnotationTitle])
@@ -482,6 +482,6 @@ func TestSpecRedactor(t *testing.T) {
482482
t.Run("the default scanner removes secrets", func(t *testing.T) {
483483
got, err := newSpecRedactor(t.TempDir()).Redact(context.Background(), []byte("the token "+pat+" fails"))
484484
require.NoError(t, err)
485-
assert.Equal(t, "the token [REDACTED:github-pat] fails", string(got))
485+
assert.Equal(t, "the token [CHAINLOOP_TRACE_REDACTED:github-pat] fails", string(got))
486486
})
487487
}

‎internal/redaction/betterleaks_test.go‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func TestDefaultPlaceholderIsNotDetectable(t *testing.T) {
153153
for id := range cfg.Rules {
154154
ruleIDs = append(ruleIDs, id)
155155
}
156-
// The empty rule id yields the bare "[REDACTED]" placeholder.
156+
// The empty rule id yields the bare "[CHAINLOOP_TRACE_REDACTED]" placeholder.
157157
ruleIDs = append(ruleIDs, "")
158158

159159
for _, id := range ruleIDs {
@@ -270,7 +270,7 @@ func TestRedactCredentialInURIConverges(t *testing.T) {
270270
require.NoError(t, err)
271271
require.True(t, report.Changed())
272272
assert.NotContains(t, string(once), fakeGitHubPAT)
273-
assert.Contains(t, string(once), "[REDACTED:github-pat]")
273+
assert.Contains(t, string(once), "[CHAINLOOP_TRACE_REDACTED:github-pat]")
274274
// Two passes: one that redacts, one that confirms nothing is left.
275275
assert.Equal(t, 2, report.Passes)
276276

@@ -301,29 +301,29 @@ func TestRedactJWTKeepsSurroundingText(t *testing.T) {
301301
// the JWT is escaped in the leaf.
302302
name: "followed by an escaped quote in a nested JSON string",
303303
leaf: `{"url":"https://uploads.example.com/o/a/b?signature=` + fakeJWT + `"}`,
304-
want: `{"url":"https://uploads.example.com/o/a/b?signature=[REDACTED:jwt]"}`,
304+
want: `{"url":"https://uploads.example.com/o/a/b?signature=[CHAINLOOP_TRACE_REDACTED:jwt]"}`,
305305
},
306306
{
307307
name: "followed by an escaped newline",
308308
leaf: "https://uploads.example.com/o/a/b?signature=" + fakeJWT + "\nnext line",
309-
want: "https://uploads.example.com/o/a/b?signature=[REDACTED:jwt]\nnext line",
309+
want: "https://uploads.example.com/o/a/b?signature=[CHAINLOOP_TRACE_REDACTED:jwt]\nnext line",
310310
},
311311
{
312312
name: "followed by an escaped carriage return",
313313
leaf: "https://uploads.example.com/o/a/b?signature=" + fakeJWT + "\rnext line",
314-
want: "https://uploads.example.com/o/a/b?signature=[REDACTED:jwt]\rnext line",
314+
want: "https://uploads.example.com/o/a/b?signature=[CHAINLOOP_TRACE_REDACTED:jwt]\rnext line",
315315
},
316316
{
317317
name: "followed by an escaped tab",
318318
leaf: "https://uploads.example.com/o/a/b?signature=" + fakeJWT + "\tnext line",
319-
want: "https://uploads.example.com/o/a/b?signature=[REDACTED:jwt]\tnext line",
319+
want: "https://uploads.example.com/o/a/b?signature=[CHAINLOOP_TRACE_REDACTED:jwt]\tnext line",
320320
},
321321
{
322322
// The literal backslash is a complete `\\` escape, which is kept in
323323
// the secret: the leaf loses that one character but not its context.
324324
name: "followed by a literal backslash",
325325
leaf: `https://uploads.example.com/o/a/b?signature=` + fakeJWT + `\"`,
326-
want: `https://uploads.example.com/o/a/b?signature=[REDACTED:jwt]"`,
326+
want: `https://uploads.example.com/o/a/b?signature=[CHAINLOOP_TRACE_REDACTED:jwt]"`,
327327
},
328328
}
329329

@@ -745,7 +745,7 @@ func TestLineSpansRoundTrip(t *testing.T) {
745745
func TestDocumentScannerMatchesFreshScan(t *testing.T) {
746746
replaceFirst := func(text string) string {
747747
i := strings.Index(text, "ghp_")
748-
return text[:i] + "[REDACTED:github-pat]" + text[i+len(fakeGitHubPAT):]
748+
return text[:i] + "[CHAINLOOP_TRACE_REDACTED:github-pat]" + text[i+len(fakeGitHubPAT):]
749749
}
750750

751751
testCases := []struct {
@@ -802,7 +802,7 @@ func TestDocumentScannerRescansOnlyChangedChunks(t *testing.T) {
802802
require.NoError(t, err)
803803

804804
i := strings.Index(text, "ghp_")
805-
edited := text[:i] + "[REDACTED:github-pat]" + text[i+len(fakeGitHubPAT):]
805+
edited := text[:i] + "[CHAINLOOP_TRACE_REDACTED:github-pat]" + text[i+len(fakeGitHubPAT):]
806806

807807
before := scanner.detector.TotalBytes.Load()
808808
_, err = doc.Scan(context.Background(), edited)

‎internal/redaction/redaction.go‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,14 @@ func New(s Scanner, opts ...Option) *Redactor {
207207
// present without being able to recover it.
208208
func DefaultPlaceholder(ruleID string) string {
209209
if ruleID == "" {
210-
return "[REDACTED]"
210+
return "[CHAINLOOP_TRACE_REDACTED]"
211211
}
212-
return "[REDACTED:" + ruleID + "]"
212+
return "[CHAINLOOP_TRACE_REDACTED:" + ruleID + "]"
213213
}
214214

215215
// defaultPlaceholderPattern recognises the output of DefaultPlaceholder for any
216216
// rule id, including ids this build has never seen.
217-
var defaultPlaceholderPattern = regexp.MustCompile(`^\[REDACTED(?::[^\]\s]*)?\]$`)
217+
var defaultPlaceholderPattern = regexp.MustCompile(`^\[CHAINLOOP_TRACE_REDACTED(?::[^\]\s]*)?\]$`)
218218

219219
// IsDefaultPlaceholder reports whether s is a placeholder DefaultPlaceholder
220220
// could have produced.

‎internal/redaction/redaction_test.go‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func TestRedact(t *testing.T) {
116116
wantReplacements: 1,
117117
wantByRule: map[string]int{"aws-access-token": 1},
118118
mustNotContain: []string{"FAKE-AWS-KEY-NOT-A-REAL-PATTERN"},
119-
mustContain: []string{"[REDACTED:aws-access-token]", "untouched", "run ", " now"},
119+
mustContain: []string{"[CHAINLOOP_TRACE_REDACTED:aws-access-token]", "untouched", "run ", " now"},
120120
},
121121
{
122122
name: "same secret across three leaves",
@@ -148,23 +148,23 @@ func TestRedact(t *testing.T) {
148148
findings: []Finding{{RuleID: "r1", Secret: "nSEC"}},
149149
wantReplacements: 1,
150150
mustNotContain: []string{"before", "after"},
151-
mustContain: []string{"[REDACTED:r1]"},
151+
mustContain: []string{"[CHAINLOOP_TRACE_REDACTED:r1]"},
152152
},
153153
{
154154
name: "secret ending on the backslash of an escape keeps the leaf",
155155
doc: `{"a":"{\"url\":\"https://h/x?sig=SEC\"}"}`,
156156
findings: []Finding{{RuleID: "r1", Secret: `SEC\`}},
157157
wantReplacements: 1,
158158
wantByRule: map[string]int{"r1": 1},
159-
mustContain: []string{`{"a":"{\"url\":\"https://h/x?sig=[REDACTED:r1]\"}"}`},
159+
mustContain: []string{`{"a":"{\"url\":\"https://h/x?sig=[CHAINLOOP_TRACE_REDACTED:r1]\"}"}`},
160160
},
161161
{
162162
name: "secret ending on a complete escaped backslash keeps it",
163163
doc: `{"a":"SEC\\ after"}`,
164164
findings: []Finding{{RuleID: "r1", Secret: `SEC\\`}},
165165
wantReplacements: 1,
166166
wantByRule: map[string]int{"r1": 1},
167-
mustContain: []string{`{"a":"[REDACTED:r1] after"}`},
167+
mustContain: []string{`{"a":"[CHAINLOOP_TRACE_REDACTED:r1] after"}`},
168168
},
169169
{
170170
name: "protected path is left alone and recorded",
@@ -188,7 +188,7 @@ func TestRedact(t *testing.T) {
188188
// The copy left in the protected leaf is still found on the next
189189
// pass, where no eligible leaf holds it any more.
190190
wantUnlocated: map[string]int{"r1": 1},
191-
mustContain: []string{`"keepme":"SEC"`, `"other":"x [REDACTED:r1]"`},
191+
mustContain: []string{`"keepme":"SEC"`, `"other":"x [CHAINLOOP_TRACE_REDACTED:r1]"`},
192192
},
193193
{
194194
name: "finding present nowhere is classified as an artifact",
@@ -368,7 +368,7 @@ func TestRedactOpaqueLeaves(t *testing.T) {
368368
{
369369
name: "secret in opaque data and in text",
370370
doc: `{"img":{"type":"base64","data":"aaSECaa"},"t":"y SEC y"}`,
371-
want: `{"img":{"data":"aaSECaa","type":"base64"},"t":"y [REDACTED:r1] y"}`,
371+
want: `{"img":{"data":"aaSECaa","type":"base64"},"t":"y [CHAINLOOP_TRACE_REDACTED:r1] y"}`,
372372
},
373373
{
374374
name: "secret only in opaque data",
@@ -378,7 +378,7 @@ func TestRedactOpaqueLeaves(t *testing.T) {
378378
{
379379
name: "data that is not opaque is still redacted",
380380
doc: `{"img":{"type":"url","data":"aaSECaa"}}`,
381-
want: `{"img":{"data":"aa[REDACTED:r1]aa","type":"url"}}`,
381+
want: `{"img":{"data":"aa[CHAINLOOP_TRACE_REDACTED:r1]aa","type":"url"}}`,
382382
dataScanned: true,
383383
},
384384
}
@@ -455,9 +455,9 @@ func TestRedactText(t *testing.T) {
455455
want string
456456
wantChanged bool
457457
}{
458-
{name: "a secret is replaced", text: "use " + secret + " now", want: "use [REDACTED:test-token] now", wantChanged: true},
458+
{name: "a secret is replaced", text: "use " + secret + " now", want: "use [CHAINLOOP_TRACE_REDACTED:test-token] now", wantChanged: true},
459459
{name: "text without secrets comes back unchanged", text: "nothing to see", want: "nothing to see"},
460-
{name: "line breaks and quotes survive", text: "a \"quoted\"\nline " + secret, want: "a \"quoted\"\nline [REDACTED:test-token]", wantChanged: true},
460+
{name: "line breaks and quotes survive", text: "a \"quoted\"\nline " + secret, want: "a \"quoted\"\nline [CHAINLOOP_TRACE_REDACTED:test-token]", wantChanged: true},
461461
}
462462

463463
for _, tc := range testCases {

‎pkg/attestation/crafter/api/attestation/v1/crafting_state_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -504,8 +504,8 @@ func TestGetEvaluableContentRedactedNeverReadsDisk(t *testing.T) {
504504
// Any distinguishable values work here; this test is about which source
505505
// the content is read from, not about detection.
506506
onDiskSecret = "the-unredacted-original"
507-
inlineSecret = "[REDACTED:aws-access-token]"
508-
suppliedTag = "[REDACTED:supplied]"
507+
inlineSecret = "[CHAINLOOP_TRACE_REDACTED:aws-access-token]"
508+
suppliedTag = "[CHAINLOOP_TRACE_REDACTED:supplied]"
509509

510510
onDisk = `{"secret":"` + onDiskSecret + `"}`
511511
inline = `{"secret":"` + inlineSecret + `"}`
@@ -675,7 +675,7 @@ func TestGetEvaluableContentInjectsMetadata(t *testing.T) {
675675
},
676676
}
677677

678-
content, err := m.GetEvaluableContent("", []byte(`{"secret":"[REDACTED:jwt]"}`))
678+
content, err := m.GetEvaluableContent("", []byte(`{"secret":"[CHAINLOOP_TRACE_REDACTED:jwt]"}`))
679679
require.NoError(t, err)
680680

681681
var decoded struct {
@@ -686,7 +686,7 @@ func TestGetEvaluableContentInjectsMetadata(t *testing.T) {
686686
}
687687
require.NoError(t, json.Unmarshal(content, &decoded))
688688

689-
assert.Equal(t, "[REDACTED:jwt]", decoded.Secret)
689+
assert.Equal(t, "[CHAINLOOP_TRACE_REDACTED:jwt]", decoded.Secret)
690690
assert.Equal(t, AnnotationValueTrue, decoded.Metadata.Annotations[AnnotationMaterialRedacted])
691691
assert.Equal(t, "2", decoded.Metadata.Annotations[AnnotationMaterialRedactionCount])
692692
assert.Equal(t, "jwt", decoded.Metadata.Annotations[AnnotationMaterialRedactionRules])

‎pkg/attestation/crafter/materials/aicodingsession/redact_test.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func TestRedact(t *testing.T) {
233233

234234
// Surrounding prose in a redacted leaf must be preserved.
235235
assert.Contains(t, string(got), "deploy this, use AWS_ACCESS_KEY_ID=")
236-
assert.Contains(t, string(got), "[REDACTED:aws-access-token]")
236+
assert.Contains(t, string(got), "[CHAINLOOP_TRACE_REDACTED:aws-access-token]")
237237
assert.Contains(t, string(got), "and a <config> block with \\\"quoted\\\" values. Done ✅")
238238
})
239239
}
@@ -405,7 +405,7 @@ func TestRedactSpecText(t *testing.T) {
405405
// credential, and the text around it must survive.
406406
name: "a secret in a ticket body is replaced",
407407
text: "The runner is configured with the token " + fixtureGitHubPAT + " and still gets a 401.",
408-
wantText: "The runner is configured with the token [REDACTED:github-pat] and still gets a 401.",
408+
wantText: "The runner is configured with the token [CHAINLOOP_TRACE_REDACTED:github-pat] and still gets a 401.",
409409
wantChanged: true,
410410
mustNotContain: fixtureGitHubPAT,
411411
},

‎pkg/attestation/crafter/materials/chainloop_ai_coding_session_redaction_test.go‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import (
4242
func TestUploadAndCraftContentOverride(t *testing.T) {
4343
const (
4444
onDisk = `{"original":"content that is definitely longer"}`
45-
redacted = `{"original":"[REDACTED]"}`
45+
redacted = `{"original":"[CHAINLOOP_TRACE_REDACTED]"}`
4646
)
4747

4848
testCases := []struct {
@@ -294,12 +294,12 @@ func TestChainloopAICodingSessionCrafterRedaction(t *testing.T) {
294294
require.NotNil(t, content, "a redacted session must hand back its sanitized copy")
295295
assert.Equal(t, sha256Digest(string(content)), got.GetArtifact().Digest)
296296
assert.NotContains(t, string(content), awsKey)
297-
assert.Contains(t, string(content), "[REDACTED:aws-access-token]")
297+
assert.Contains(t, string(content), "[CHAINLOOP_TRACE_REDACTED:aws-access-token]")
298298

299299
if stored != nil {
300300
assert.Equal(t, string(stored), string(content))
301301
assert.NotContains(t, string(stored), awsKey)
302-
assert.Contains(t, string(stored), "[REDACTED:aws-access-token]")
302+
assert.Contains(t, string(stored), "[CHAINLOOP_TRACE_REDACTED:aws-access-token]")
303303
}
304304
case tc.skipRedaction:
305305
assert.Equal(t, "true", got.Annotations[api.AnnotationMaterialRedactionSkipped])

0 commit comments

Comments
 (0)