Redact common credential patterns from published run output (#1595)

* Redact common credential patterns from published run output

* Handle color codes and escape sequences ahead of redacted values

Vendor-prefixed formats no longer require a leading word boundary, so a
value that follows an ANSI SGR terminator or a serialized JSON escape is
still matched. AWS key ids keep a boundary but also accept those cases.
sanitizeContent goes back to GitHub-only redaction for inbound content,
and the failure annotation is redacted like the tracking comment.

* Coerce non-string text content before redacting tool results

No-Verification-Needed: one-line coercion in a formatting helper plus regression test
This commit is contained in:
Ashwin Bhat
2026-08-06 10:17:25 -07:00
committed by GitHub
parent c038e4dcde
commit 0aee57ab82
6 changed files with 296 additions and 20 deletions
+3 -2
View File
@@ -34,6 +34,7 @@ import { collectActionInputsPresence } from "./collect-inputs";
import { updateCommentLink } from "./update-comment-link";
import { formatTurnsFromData } from "./format-turns";
import type { Turn } from "./format-turns";
import { redactSecrets } from "../github/utils/sanitizer";
// Base-action imports (used directly instead of subprocess)
import { setupWorkloadIdentity } from "../../base-action/src/workload-identity";
import type { WorkloadIdentityHandle } from "../../base-action/src/workload-identity";
@@ -137,7 +138,7 @@ async function writeStepSummary(executionFile: string): Promise<void> {
fallback +=
"Failed to format output (please report). Here's the raw JSON:\n\n";
fallback += "```json\n";
fallback += readFileSync(executionFile, "utf-8");
fallback += redactSecrets(readFileSync(executionFile, "utf-8"));
fallback += "\n```\n";
await appendFile(summaryFile, fallback);
} catch {
@@ -317,7 +318,7 @@ async function run() {
prepareSuccess = false;
prepareError = errorMessage;
}
core.setFailed(`Action failed with error: ${errorMessage}`);
core.setFailed(`Action failed with error: ${redactSecrets(errorMessage)}`);
} finally {
// Phase 4: Cleanup (always runs)