@@ -18,11 +18,24 @@ const API_KEY_PATTERNS: RegExp[] = [
1818 / \b B a s i c \s + [ a - z A - Z 0 - 9 + / ] { 8 , } = { 0 , 2 } / g,
1919] ;
2020
21- const SECRET_QUERY_PARAMETER =
22- / ( [ ? & ] (?: a p i [ _ - ] ? k e y | a c c e s s [ _ - ] ? t o k e n | t o k e n | p a s s w o r d | s e c r e t | c r e d e n t i a l | [ ^ & # \s = ' " ] * _ k e y ) = ) (? ! \[ r e d a c t e d : l o o k s l i k e a c r e d e n t i a l \] ) [ ^ & # \s " ' ] + / gi;
23-
24- const JSON_CREDENTIAL_FIELD =
25- / ( " (?: a p i [ _ - ] ? k e y | a c c e s s [ _ - ] ? t o k e n | t o k e n | p a s s w o r d | s e c r e t | c r e d e n t i a l | a u t h o r i z a t i o n | [ ^ " ] + _ k e y ) " \s * : \s * " ) ( [ ^ " \r \n ] + ) ( " ) / gi;
21+ // A *_key name is a credential only when a secret marker is its own
22+ // underscore-separated segment (api_key, MY_API_KEY, private_key, OPENAI_KEY).
23+ // Storage roles such as partition_key, sort_key, primary_key, cache_key, and
24+ // prompt_cache_key have no such segment, so they stay. Marker-free vendor keys
25+ // are left alone on purpose: missing a rare key beats wiping database keys.
26+ const CREDENTIAL_KEY_MARKER =
27+ "api|secret|private|access|auth|token|password|credential|openai" ;
28+ const MARKER_KEY_SUFFIX = `(?:[a-z0-9]+_)*(?:${ CREDENTIAL_KEY_MARKER } )_key` ;
29+
30+ const SECRET_QUERY_PARAMETER = new RegExp (
31+ `([?&](?:api[_-]?key|access[_-]?token|token|password|secret|credential|${ MARKER_KEY_SUFFIX } )=)(?!\\[redacted: looks like a credential\\])[^&#\\s]+` ,
32+ "gi" ,
33+ ) ;
34+
35+ const JSON_CREDENTIAL_FIELD = new RegExp (
36+ `("(?:api[_-]?key|access[_-]?token|token|password|secret|credential|authorization|${ MARKER_KEY_SUFFIX } )"\\s*:\\s*")([^"\\r\\n]+)(")` ,
37+ "gi" ,
38+ ) ;
2639
2740// Grep/shell lines often look like path:line:KEY=value
2841const ENV_ASSIGNMENT = / (?: ^ | : ) ( [ A - Z ] [ A - Z 0 - 9 _ ] + ) = ( [ ^ \n ] + ) / gm;
@@ -76,11 +89,13 @@ export function scrubSecretShapedContent(text: string): string {
7689}
7790
7891const JSON_SAFE_ERROR = "Tool result is not JSON-safe" ;
79- // Bare-KEY class (OPENAI_KEY, MY_API_KEY): the underscore boundary keeps
80- // MONKEY-style words out, and the required prefix keeps an ordinary field
81- // named exactly "key" readable.
82- const CREDENTIAL_FIELD =
83- / ^ (?: a p i [ _ - ] ? k e y | a c c e s s [ _ - ] ? t o k e n | t o k e n | p a s s w o r d | s e c r e t | c r e d e n t i a l | a u t h o r i z a t i o n | a u t h | .+ _ k e y ) $ / i;
92+ // Bare-KEY class (OPENAI_KEY, MY_API_KEY). The marker segment keeps storage
93+ // roles (partition_key, sort_key, cache_key) readable, and requiring _key
94+ // keeps MONKEY and a field named exactly "key" readable.
95+ const CREDENTIAL_FIELD = new RegExp (
96+ `^(?:api[_ -]?key|access[_ -]?token|token|password|secret|credential|authorization|auth|${ MARKER_KEY_SUFFIX } )$` ,
97+ "i" ,
98+ ) ;
8499
85100/**
86101 * Returns a detached JSON-safe value without invoking input accessors or custom
0 commit comments