diff --git a/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts b/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts index a7fbbd4a..5500233b 100644 --- a/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts +++ b/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts @@ -41,6 +41,28 @@ describe("redactBody", () => { expect(redactBody(`\`${sha}\``).reasons).toEqual([]); }); + test("redacts the credential after an auth scheme, not just the scheme", () => { + const jwt = "eyJhbGciOiJIUzI1NiJ9.SECRETPAYLOAD.sig"; + const result = redactBody(`Authorization: Bearer ${jwt}`); + + expect(result.text).toBe("Authorization=[redacted]"); + expect(result.text).not.toContain(jwt); + expect(result.reasons).toContain("contains sensitive key"); + }); + + test("redacts a quoted value containing spaces", () => { + const result = redactBody('export TOKEN="my secret value"'); + + expect(result.text).toBe("export TOKEN=[redacted]"); + expect(result.text).not.toContain("secret value"); + }); + + test("redacts only the offending line", () => { + const result = redactBody("password: hunter2\nnext line stays"); + + expect(result.text).toBe("password=[redacted]\nnext line stays"); + }); + test("allows concise operational context", () => { const result = redactBody("blocked: docker rate-limit on redis:7"); diff --git a/orchestrate/skills/orchestrate/scripts/core/redact-body.ts b/orchestrate/skills/orchestrate/scripts/core/redact-body.ts index 4623f107..0f0b98fb 100644 --- a/orchestrate/skills/orchestrate/scripts/core/redact-body.ts +++ b/orchestrate/skills/orchestrate/scripts/core/redact-body.ts @@ -1,7 +1,9 @@ const MAX_BODY_CHARS = 2_048; const SENSITIVE_KEY_RE = /token|secret|password|api[_-]?key|authorization/i; +// Value runs to end of line: `\S+` stopped at the first space, which left the +// credential behind in `Authorization: Bearer ` and in quoted values. const SENSITIVE_ASSIGNMENT_RE = - /\b(token|secret|password|api[_-]?key|authorization)\b\s*[:=]\s*\S+/gi; + /\b(token|secret|password|api[_-]?key|authorization)\b\s*[:=]\s*\S.*/gi; const PATH_PATTERNS = [ { re: /^\/workspace\/\S*/gm, reason: "contains /workspace path" }, { re: /^\/Users\/\S*/gm, reason: "contains /Users path" },