fix(hooks): redact Docker's auth values in activity summaries

A raw Docker configuration, as `cat ~/.docker/config.json` prints it, keeps its credential under `"auth":`, which only the auth_config name matched. Count `auth` as a credential word when it ends the word, so `"auth":`, `AUTH=` and `oauth=` are redacted while `author` and `auth_method` are not.
This commit is contained in:
L4XB committed 2026-10-22 23:13:01 +02:00
1 parent bc5a38a1a0
commit abff545aa8
2 files changed
+8 -5

No files matched your search

+6 -5
View File
@@ -41,11 +41,12 @@ function redactSecrets(value) {
// The rest covers what governance-capture detects, since tool output such as
// `cat .env` lands in these summaries too.
// A name that carries a credential word anywhere (`AWS_SECRET_ACCESS_KEY`,
// `DOCKER_AUTH_CONFIG`), but not `max_tokens` or `tokenizer`. The name parts
// around the word are bounded, which keeps long output linear. A quoted value
// may hold escaped quotes; a JSON value can hold spaces, so one that opens with
// { or [ is redacted to the end; a bare value ends at the next field.
.replace(/\b([\w.-]{0,64}(?:secret|token(?!s|iz)|passw(?:or)?d|api[_-]?key|access[_-]?key|private[_-]?key|credential|auth[_-]?config)[\w.-]{0,64})(["']?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[{[].*|[^\s,;}\]"']+)/gi, '$1$2<REDACTED>')
// `DOCKER_AUTH_CONFIG`, Docker's `"auth":`), but not `max_tokens`, `tokenizer`
// or `author`. The name parts around the word are bounded, which keeps long
// output linear. A quoted value may hold escaped quotes; a JSON value can hold
// spaces, so one that opens with { or [ is redacted to the end; a bare value
// ends at the next field.
.replace(/\b([\w.-]{0,64}(?:secret|token(?!s|iz)|passw(?:or)?d|api[_-]?key|access[_-]?key|private[_-]?key|credential|auth\b|auth[_-]?config)[\w.-]{0,64})(["']?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[{[].*|[^\s,;}\]"']+)/gi, '$1$2<REDACTED>')
.replace(/\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g, '<REDACTED>')
.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----.*/g, '<REDACTED>')
.replace(/\bgh[pousr]_[A-Za-z0-9_]+\b/g, '<REDACTED>')
@@ -518,6 +518,8 @@ function runTests() {
assert.strictEqual(summarizeOutput('AWS_SECRET_ACCESS_KEY=example-secret-value'), 'AWS_SECRET_ACCESS_KEY=<REDACTED>');
assert.strictEqual(summarizeOutput('DOCKER_AUTH_CONFIG={"auths":{"registry":{}}}'), 'DOCKER_AUTH_CONFIG=<REDACTED>');
assert.strictEqual(summarizeOutput('DOCKER_AUTH_CONFIG={"auths": {"registry": {"auth": "dXNlcjpwYXNz"}}}'), 'DOCKER_AUTH_CONFIG=<REDACTED>');
assert.strictEqual(summarizeOutput('{"auths":{"registry":{"auth":"dXNlcjpwYXNz"}}}'), '{"auths":{"registry":{"auth":<REDACTED>}}}');
assert.strictEqual(summarizeOutput('auth_method=oidc author=Jane'), 'auth_method=oidc author=Jane');
assert.strictEqual(summarizeOutput('{"token": "abc.def", "user": "bob"}'), '{"token": <REDACTED>, "user": "bob"}');
const jwt = ['eyJ' + 'a'.repeat(12), 'eyJ' + 'b'.repeat(12), 'c'.repeat(12)].join('.');
assert.strictEqual(summarizeOutput(`Bearer ${jwt} done`), 'Bearer <REDACTED> done');