From ca82e8fa73bff00653e63c6bb985c774b78bf8a8 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Mon, 19 Oct 2026 06:24:29 +0000 Subject: [PATCH] fix(channel): redact GitHub App tokens from run error replies --- app/channel-helpers.test.ts | 12 ++++++++++++ app/channel-helpers.ts | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/channel-helpers.test.ts b/app/channel-helpers.test.ts index 9d7815aa..360549fa 100644 --- a/app/channel-helpers.test.ts +++ b/app/channel-helpers.test.ts @@ -154,4 +154,16 @@ describe("userFacingRunError", () => { expect(text).not.toContain("ghp_LIVESECRET99"); expect(text).toContain("ghp_[redacted]"); }); + + it.each(["ghs", "ghu", "ghr"])( + "redacts a %s_ GitHub App token from the reason", + (prefix) => { + const secret = `${prefix}_LIVESECRET99`; + const text = userFacingRunError( + new Error(`git push failed for https://x-access-token:${secret}@github.com/o/r`), + ); + expect(text).not.toContain(secret); + expect(text).toContain(`${prefix}_[redacted]`); + }, + ); }); diff --git a/app/channel-helpers.ts b/app/channel-helpers.ts index db0393e8..7e9c034b 100644 --- a/app/channel-helpers.ts +++ b/app/channel-helpers.ts @@ -69,7 +69,9 @@ export function reportRecoverableError( }); } -const TOKEN_RE = /(ghp|github_pat|gho)_[A-Za-z0-9_]+/g; +// Same families as `agent/coding/sandbox.py`. GitHub App auth mints `ghs_` +// installation tokens, so the narrower pattern let those through to Slack. +const TOKEN_RE = /(ghp|github_pat|gho|ghs|ghu|ghr)_[A-Za-z0-9_]+/g; function errorText(error: unknown): string { if (error instanceof AggregateError) {