agent-inspect 6.31.3 → 6.31.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/SECURITY.md +2 -0
- package/docs/GETTING-STARTED.md +2 -0
- package/docs/SAFE-TRACE-SHARING.md +1 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-SJ6FRNOE.mjs → chunk-LKEPABND.mjs} +86 -80
- package/packages/cli/dist/chunk-LKEPABND.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +399 -91
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +307 -14
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-YNEJOPRA.mjs → src-4WYF5RFI.mjs} +3 -3
- package/packages/cli/dist/{src-YNEJOPRA.mjs.map → src-4WYF5RFI.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +97 -30
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +13 -13
- package/packages/core/dist/checks.cjs +51 -49
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +5 -5
- package/packages/core/dist/{chunk-PBNBQRXV.mjs → chunk-2KJR6X4V.mjs} +9 -9
- package/packages/core/dist/chunk-2KJR6X4V.mjs.map +1 -0
- package/packages/core/dist/{chunk-26YJSETN.mjs → chunk-7DHSWDKB.mjs} +19 -6
- package/packages/core/dist/chunk-7DHSWDKB.mjs.map +1 -0
- package/packages/core/dist/{chunk-BGF5JDJN.mjs → chunk-INE5IWLN.mjs} +3 -3
- package/packages/core/dist/{chunk-BGF5JDJN.mjs.map → chunk-INE5IWLN.mjs.map} +1 -1
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs → chunk-MTMTXTJL.mjs} +5 -5
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs.map → chunk-MTMTXTJL.mjs.map} +1 -1
- package/packages/core/dist/{chunk-KWBO36PH.mjs → chunk-NY4ILMXK.mjs} +4 -4
- package/packages/core/dist/{chunk-KWBO36PH.mjs.map → chunk-NY4ILMXK.mjs.map} +1 -1
- package/packages/core/dist/{chunk-WN5PT4GV.mjs → chunk-OSGNGRHF.mjs} +3 -3
- package/packages/core/dist/{chunk-WN5PT4GV.mjs.map → chunk-OSGNGRHF.mjs.map} +1 -1
- package/packages/core/dist/{chunk-CBPWLHNQ.mjs → chunk-PKDBFBJ7.mjs} +5 -76
- package/packages/core/dist/chunk-PKDBFBJ7.mjs.map +1 -0
- package/packages/core/dist/{chunk-VU6O5QAH.mjs → chunk-VLVCLAPB.mjs} +83 -5
- package/packages/core/dist/chunk-VLVCLAPB.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +217 -6
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +118 -9
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.cjs +97 -8
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.mjs +6 -6
- package/packages/core/dist/logs.cjs +80 -2
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.d.cts +2 -0
- package/packages/core/dist/logs.d.ts +2 -0
- package/packages/core/dist/logs.mjs +2 -2
- package/packages/core/dist/readers.cjs +2 -0
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +2 -2
- package/packages/core/dist/writers.cjs +96 -8
- package/packages/core/dist/writers.cjs.map +1 -1
- package/packages/core/dist/writers.mjs +7 -8
- package/packages/core/dist/writers.mjs.map +1 -1
- package/packages/cli/dist/chunk-SJ6FRNOE.mjs.map +0 -1
- package/packages/core/dist/chunk-26YJSETN.mjs.map +0 -1
- package/packages/core/dist/chunk-CBPWLHNQ.mjs.map +0 -1
- package/packages/core/dist/chunk-PBNBQRXV.mjs.map +0 -1
- package/packages/core/dist/chunk-VU6O5QAH.mjs.map +0 -1
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
|
|
3
|
+
// packages/core/src/logs/redactor.ts
|
|
4
|
+
|
|
5
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
6
|
+
function keyHasExplicitSeparator(value) {
|
|
7
|
+
return /[_\-.]/.test(value);
|
|
8
|
+
}
|
|
9
|
+
function normalizeSensitiveKey(value) {
|
|
10
|
+
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
11
|
+
}
|
|
12
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
|
|
13
|
+
[
|
|
14
|
+
"tokens",
|
|
15
|
+
"max_tokens",
|
|
16
|
+
"min_tokens",
|
|
17
|
+
"ls_max_tokens",
|
|
18
|
+
"token_count",
|
|
19
|
+
"token_limit",
|
|
20
|
+
"token_budget",
|
|
21
|
+
"input_tokens",
|
|
22
|
+
"output_tokens",
|
|
23
|
+
"total_tokens",
|
|
24
|
+
"cached_tokens",
|
|
25
|
+
"prompt_tokens",
|
|
26
|
+
"completion_tokens"
|
|
27
|
+
].map(normalizeSensitiveKey)
|
|
28
|
+
);
|
|
29
|
+
var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
|
|
30
|
+
"authorization",
|
|
31
|
+
"cookie",
|
|
32
|
+
"token",
|
|
33
|
+
"access_token",
|
|
34
|
+
"accesstoken",
|
|
35
|
+
"auth_token",
|
|
36
|
+
"authtoken",
|
|
37
|
+
"refresh_token",
|
|
38
|
+
"refreshtoken",
|
|
39
|
+
"id_token",
|
|
40
|
+
"idtoken",
|
|
41
|
+
"bearer_token",
|
|
42
|
+
"bearertoken",
|
|
43
|
+
"api_token",
|
|
44
|
+
"apitoken",
|
|
45
|
+
"apikey",
|
|
46
|
+
"api_key",
|
|
47
|
+
"password",
|
|
48
|
+
"secret",
|
|
49
|
+
"email"
|
|
50
|
+
];
|
|
51
|
+
function isTokenCredentialKey(normalized) {
|
|
52
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
53
|
+
if (normalized === "token") return true;
|
|
54
|
+
if (normalized.endsWith("tokens")) return false;
|
|
55
|
+
return normalized.endsWith("token");
|
|
56
|
+
}
|
|
57
|
+
function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
|
|
58
|
+
if (!key) return false;
|
|
59
|
+
const normalized = normalizeSensitiveKey(key);
|
|
60
|
+
if (!normalized) return false;
|
|
61
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
62
|
+
const allowPrefixCompound = keyHasExplicitSeparator(key);
|
|
63
|
+
for (const sensitive of sensitiveKeys) {
|
|
64
|
+
const s = normalizeSensitiveKey(sensitive);
|
|
65
|
+
if (!s) continue;
|
|
66
|
+
if (s === "token") {
|
|
67
|
+
if (isTokenCredentialKey(normalized)) return true;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (normalized === s) return true;
|
|
71
|
+
if (normalized.endsWith(`_${s}`)) return true;
|
|
72
|
+
if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
3
77
|
// packages/core/src/logs/redactor.ts
|
|
4
78
|
var DEFAULT_REDACT_KEYS = [
|
|
5
79
|
"authorization",
|
|
@@ -24,7 +98,7 @@ function compileRules(rules, extraKeys) {
|
|
|
24
98
|
const out = /* @__PURE__ */ new Map();
|
|
25
99
|
const set = (r) => {
|
|
26
100
|
const k = toKey(r.key);
|
|
27
|
-
out.set(k, { ...r, key: k });
|
|
101
|
+
out.set(k, { ...r, key: k, raw: r.raw ?? r.key });
|
|
28
102
|
};
|
|
29
103
|
for (const k of DEFAULT_REDACT_KEYS) {
|
|
30
104
|
set({ key: k, strategy: "full" });
|
|
@@ -53,9 +127,13 @@ var Redactor = class {
|
|
|
53
127
|
constructor(options) {
|
|
54
128
|
this.#rules = compileRules(options?.rules, options?.extraKeys);
|
|
55
129
|
}
|
|
130
|
+
/** Field names this redactor treats as sensitive, for value-level helpers. */
|
|
131
|
+
get sensitiveKeys() {
|
|
132
|
+
return this.#rules.map((rule) => rule.raw ?? rule.key);
|
|
133
|
+
}
|
|
56
134
|
redactValue(key, value) {
|
|
57
135
|
const k = toKey(key);
|
|
58
|
-
const rule = this.#rules.find((r) => r.key === k);
|
|
136
|
+
const rule = this.#rules.find((r) => r.key === k) ?? this.#rules.find((r) => isCredentialSensitiveKey(key, [r.raw ?? r.key]));
|
|
59
137
|
if (!rule) {
|
|
60
138
|
return this.#redactNested(value);
|
|
61
139
|
}
|
|
@@ -94,6 +172,6 @@ var Redactor = class {
|
|
|
94
172
|
}
|
|
95
173
|
};
|
|
96
174
|
|
|
97
|
-
export { DEFAULT_REDACT_KEYS, Redactor };
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
99
|
-
//# sourceMappingURL=chunk-
|
|
175
|
+
export { DEFAULT_CREDENTIAL_SENSITIVE_KEYS, DEFAULT_REDACT_KEYS, Redactor, isCredentialSensitiveKey };
|
|
176
|
+
//# sourceMappingURL=chunk-VLVCLAPB.mjs.map
|
|
177
|
+
//# sourceMappingURL=chunk-VLVCLAPB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/safety/sensitive-key.ts","../src/logs/redactor.ts"],"names":[],"mappings":"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","file":"chunk-VLVCLAPB.mjs","sourcesContent":["/**\n * Contextual sensitive-key classification for safety checks and redaction.\n *\n * Avoids treating model token-configuration fields (ls_max_tokens, max_tokens,\n * token_count, …) as credentials solely because they contain the substring\n * \"token\". Value-based secret detectors remain separate.\n *\n * @experimental Shared classifier used by checks (6.14.2+); parity across\n * surfaces lands in the same patch train.\n */\n\n/** True when the original key already uses an explicit separator. */\nfunction keyHasExplicitSeparator(value: string): boolean {\n return /[_\\-.]/.test(value);\n}\n\n/**\n * Canonicalize field names so camelCase / kebab / dot / snake forms share a\n * snake_case shape the compound matcher can recognize (`userPassword` →\n * `user_password`).\n */\nexport function normalizeSensitiveKey(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n}\n\n/** Model / usage configuration keys that are not credentials by key alone. */\nexport const NON_CREDENTIAL_TOKEN_CONFIG_KEYS: ReadonlySet<string> = new Set(\n [\n \"tokens\",\n \"max_tokens\",\n \"min_tokens\",\n \"ls_max_tokens\",\n \"token_count\",\n \"token_limit\",\n \"token_budget\",\n \"input_tokens\",\n \"output_tokens\",\n \"total_tokens\",\n \"cached_tokens\",\n \"prompt_tokens\",\n \"completion_tokens\",\n ].map(normalizeSensitiveKey),\n);\n\nexport const DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"access_token\",\n \"accesstoken\",\n \"auth_token\",\n \"authtoken\",\n \"refresh_token\",\n \"refreshtoken\",\n \"id_token\",\n \"idtoken\",\n \"bearer_token\",\n \"bearertoken\",\n \"api_token\",\n \"apitoken\",\n \"apikey\",\n \"api_key\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nfunction isTokenCredentialKey(normalized: string): boolean {\n if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;\n if (normalized === \"token\") return true;\n // access_token / refreshToken → *token, but not *tokens (max_tokens → max_tokens)\n if (normalized.endsWith(\"tokens\")) return false;\n return normalized.endsWith(\"token\");\n}\n\n/**\n * True when the field name looks credential-sensitive under the shared policy.\n *\n * Suffix compounds (`user_password`, `userPassword`) always match. Prefix\n * compounds (`email_note`) match only when the original key already contained\n * an explicit separator, so camelCase topic fields like `emailNote` stay for\n * value detectors instead of key redaction.\n */\nexport function isCredentialSensitiveKey(\n key: string | undefined,\n sensitiveKeys: readonly string[] = DEFAULT_CREDENTIAL_SENSITIVE_KEYS,\n): boolean {\n if (!key) return false;\n const normalized = normalizeSensitiveKey(key);\n if (!normalized) return false;\n if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;\n\n const allowPrefixCompound = keyHasExplicitSeparator(key);\n\n for (const sensitive of sensitiveKeys) {\n const s = normalizeSensitiveKey(sensitive);\n if (!s) continue;\n if (s === \"token\") {\n if (isTokenCredentialKey(normalized)) return true;\n continue;\n }\n if (normalized === s) return true;\n // Compound keys with explicit separators, plus camelCase owner+secret suffixes.\n if (normalized.endsWith(`_${s}`)) return true;\n if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;\n }\n return false;\n}\n","import crypto from \"node:crypto\";\n\nimport { isCredentialSensitiveKey } from \"../safety/sensitive-key.js\";\n\nimport type { RedactionRule } from \"../types/log-config.js\";\n\nexport const DEFAULT_REDACT_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"apiKey\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nexport interface RedactorOptions {\n rules?: RedactionRule[];\n /** Additional exact keys (case-insensitive) to redact in addition to defaults. */\n extraKeys?: readonly string[];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction toKey(s: string): string {\n return s.toLowerCase();\n}\n\nfunction stableHash(value: string): string {\n const h = crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n return h.slice(0, 8);\n}\n\ntype CompiledRule = (\n | { key: string; strategy: \"full\" }\n | { key: string; strategy: \"prefix\"; keep: number }\n | { key: string; strategy: \"hash\" }\n) & { raw?: string };\n\nfunction compileRules(\n rules?: RedactionRule[],\n extraKeys?: readonly string[],\n): CompiledRule[] {\n const out = new Map<string, CompiledRule>();\n\n const set = (r: CompiledRule) => {\n const k = toKey(r.key);\n out.set(k, { ...r, key: k, raw: r.raw ?? r.key } as CompiledRule);\n };\n\n for (const k of DEFAULT_REDACT_KEYS) {\n set({ key: k, strategy: \"full\" });\n }\n\n for (const k of extraKeys ?? []) {\n if (typeof k === \"string\" && k.length > 0) {\n set({ key: k, strategy: \"full\" });\n }\n }\n\n for (const r of rules ?? []) {\n if (typeof r === \"string\") {\n set({ key: r, strategy: \"full\" });\n continue;\n }\n const key = r.key;\n if (r.strategy === \"full\") set({ key, strategy: \"full\" });\n if (r.strategy === \"hash\") set({ key, strategy: \"hash\" });\n if (r.strategy === \"prefix\") {\n set({ key, strategy: \"prefix\", keep: typeof r.keep === \"number\" ? r.keep : 8 });\n }\n }\n\n return [...out.values()];\n}\n\nexport class Redactor {\n readonly #rules: CompiledRule[];\n\n constructor(options?: RedactorOptions) {\n this.#rules = compileRules(options?.rules, options?.extraKeys);\n }\n\n /** Field names this redactor treats as sensitive, for value-level helpers. */\n get sensitiveKeys(): readonly string[] {\n return this.#rules.map((rule) => rule.raw ?? rule.key);\n }\n\n redactValue(key: string, value: unknown): unknown {\n const k = toKey(key);\n const rule =\n this.#rules.find((r) => r.key === k) ??\n this.#rules.find((r) => isCredentialSensitiveKey(key, [r.raw ?? r.key]));\n if (!rule) {\n return this.#redactNested(value);\n }\n\n if (rule.strategy === \"full\") return \"[REDACTED]\";\n const asString =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\"\n ? String(value)\n : undefined;\n\n if (rule.strategy === \"prefix\") {\n if (asString === undefined) return \"[REDACTED]\";\n const keep = Math.max(0, Math.floor(rule.keep));\n return asString.length <= keep ? `${asString}…` : `${asString.slice(0, keep)}…`;\n }\n\n if (rule.strategy === \"hash\") {\n if (asString === undefined) return \"[HASH:unknown]\";\n return `[HASH:${stableHash(asString)}]`;\n }\n\n return this.#redactNested(value);\n }\n\n redactRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(record)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n\n #redactNested(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => this.#redactNested(v));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n return value;\n }\n}\n\n"]}
|
|
@@ -13,6 +13,80 @@ var os__default = /*#__PURE__*/_interopDefault(os);
|
|
|
13
13
|
|
|
14
14
|
// packages/core/src/exporters/types.ts
|
|
15
15
|
var EXPORT_PAYLOAD_VERSION = "0.1.2";
|
|
16
|
+
|
|
17
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
18
|
+
function keyHasExplicitSeparator(value) {
|
|
19
|
+
return /[_\-.]/.test(value);
|
|
20
|
+
}
|
|
21
|
+
function normalizeSensitiveKey(value) {
|
|
22
|
+
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
23
|
+
}
|
|
24
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
|
|
25
|
+
[
|
|
26
|
+
"tokens",
|
|
27
|
+
"max_tokens",
|
|
28
|
+
"min_tokens",
|
|
29
|
+
"ls_max_tokens",
|
|
30
|
+
"token_count",
|
|
31
|
+
"token_limit",
|
|
32
|
+
"token_budget",
|
|
33
|
+
"input_tokens",
|
|
34
|
+
"output_tokens",
|
|
35
|
+
"total_tokens",
|
|
36
|
+
"cached_tokens",
|
|
37
|
+
"prompt_tokens",
|
|
38
|
+
"completion_tokens"
|
|
39
|
+
].map(normalizeSensitiveKey)
|
|
40
|
+
);
|
|
41
|
+
var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
|
|
42
|
+
"authorization",
|
|
43
|
+
"cookie",
|
|
44
|
+
"token",
|
|
45
|
+
"access_token",
|
|
46
|
+
"accesstoken",
|
|
47
|
+
"auth_token",
|
|
48
|
+
"authtoken",
|
|
49
|
+
"refresh_token",
|
|
50
|
+
"refreshtoken",
|
|
51
|
+
"id_token",
|
|
52
|
+
"idtoken",
|
|
53
|
+
"bearer_token",
|
|
54
|
+
"bearertoken",
|
|
55
|
+
"api_token",
|
|
56
|
+
"apitoken",
|
|
57
|
+
"apikey",
|
|
58
|
+
"api_key",
|
|
59
|
+
"password",
|
|
60
|
+
"secret",
|
|
61
|
+
"email"
|
|
62
|
+
];
|
|
63
|
+
function isTokenCredentialKey(normalized) {
|
|
64
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
65
|
+
if (normalized === "token") return true;
|
|
66
|
+
if (normalized.endsWith("tokens")) return false;
|
|
67
|
+
return normalized.endsWith("token");
|
|
68
|
+
}
|
|
69
|
+
function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
|
|
70
|
+
if (!key) return false;
|
|
71
|
+
const normalized = normalizeSensitiveKey(key);
|
|
72
|
+
if (!normalized) return false;
|
|
73
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
74
|
+
const allowPrefixCompound = keyHasExplicitSeparator(key);
|
|
75
|
+
for (const sensitive of sensitiveKeys) {
|
|
76
|
+
const s = normalizeSensitiveKey(sensitive);
|
|
77
|
+
if (!s) continue;
|
|
78
|
+
if (s === "token") {
|
|
79
|
+
if (isTokenCredentialKey(normalized)) return true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (normalized === s) return true;
|
|
83
|
+
if (normalized.endsWith(`_${s}`)) return true;
|
|
84
|
+
if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// packages/core/src/logs/redactor.ts
|
|
16
90
|
var DEFAULT_REDACT_KEYS = [
|
|
17
91
|
"authorization",
|
|
18
92
|
"cookie",
|
|
@@ -36,7 +110,7 @@ function compileRules(rules, extraKeys) {
|
|
|
36
110
|
const out = /* @__PURE__ */ new Map();
|
|
37
111
|
const set = (r) => {
|
|
38
112
|
const k = toKey(r.key);
|
|
39
|
-
out.set(k, { ...r, key: k });
|
|
113
|
+
out.set(k, { ...r, key: k, raw: r.raw ?? r.key });
|
|
40
114
|
};
|
|
41
115
|
for (const k of DEFAULT_REDACT_KEYS) {
|
|
42
116
|
set({ key: k, strategy: "full" });
|
|
@@ -65,9 +139,13 @@ var Redactor = class {
|
|
|
65
139
|
constructor(options) {
|
|
66
140
|
this.#rules = compileRules(options?.rules, options?.extraKeys);
|
|
67
141
|
}
|
|
142
|
+
/** Field names this redactor treats as sensitive, for value-level helpers. */
|
|
143
|
+
get sensitiveKeys() {
|
|
144
|
+
return this.#rules.map((rule) => rule.raw ?? rule.key);
|
|
145
|
+
}
|
|
68
146
|
redactValue(key, value) {
|
|
69
147
|
const k = toKey(key);
|
|
70
|
-
const rule = this.#rules.find((r) => r.key === k);
|
|
148
|
+
const rule = this.#rules.find((r) => r.key === k) ?? this.#rules.find((r) => isCredentialSensitiveKey(key, [r.raw ?? r.key]));
|
|
71
149
|
if (!rule) {
|
|
72
150
|
return this.#redactNested(value);
|
|
73
151
|
}
|
|
@@ -106,6 +184,123 @@ var Redactor = class {
|
|
|
106
184
|
}
|
|
107
185
|
};
|
|
108
186
|
|
|
187
|
+
// packages/core/src/safety/credential-value-patterns.ts
|
|
188
|
+
var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})/i;
|
|
189
|
+
var HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
|
|
190
|
+
/^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
|
|
191
|
+
/\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
|
|
192
|
+
/\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
|
|
193
|
+
/\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
|
|
194
|
+
/\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
|
|
195
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
|
|
196
|
+
/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
|
|
197
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
|
|
198
|
+
KEY_VALUE_SECRET_PATTERN
|
|
199
|
+
];
|
|
200
|
+
function stringContainsHighConfidenceCredential(value) {
|
|
201
|
+
for (const pattern of HIGH_CONFIDENCE_CREDENTIAL_PATTERNS) {
|
|
202
|
+
pattern.lastIndex = 0;
|
|
203
|
+
if (pattern.test(value)) {
|
|
204
|
+
pattern.lastIndex = 0;
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// packages/core/src/safety/url-redaction.ts
|
|
212
|
+
var HTTP_URL = /^https?:\/\/[^\s]+$/i;
|
|
213
|
+
var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
214
|
+
var HEX_SEGMENT = /^[0-9a-f]{12,}$/i;
|
|
215
|
+
var NUMERIC_SEGMENT = /^\d{5,}$/;
|
|
216
|
+
var OPAQUE_SEGMENT = /^[A-Za-z0-9_-]{20,}$/;
|
|
217
|
+
function looksLikeHttpUrl(value) {
|
|
218
|
+
return HTTP_URL.test(value.trim());
|
|
219
|
+
}
|
|
220
|
+
function parseHttpUrl(value) {
|
|
221
|
+
try {
|
|
222
|
+
const url = new URL(value.trim());
|
|
223
|
+
return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
|
|
224
|
+
} catch {
|
|
225
|
+
return void 0;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function isIdentifierSegment(segment) {
|
|
229
|
+
if (UUID_SEGMENT.test(segment)) return true;
|
|
230
|
+
if (HEX_SEGMENT.test(segment)) return true;
|
|
231
|
+
if (NUMERIC_SEGMENT.test(segment)) return true;
|
|
232
|
+
return OPAQUE_SEGMENT.test(segment) && /\d/.test(segment) && /[A-Za-z]/.test(segment);
|
|
233
|
+
}
|
|
234
|
+
function decodeParam(value) {
|
|
235
|
+
try {
|
|
236
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
237
|
+
} catch {
|
|
238
|
+
return value;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function redactParams(raw, options, replacement) {
|
|
242
|
+
let redacted = false;
|
|
243
|
+
const parts = raw.split("&").map((part) => {
|
|
244
|
+
if (part.length === 0) return part;
|
|
245
|
+
const separator = part.indexOf("=");
|
|
246
|
+
if (separator < 0) return part;
|
|
247
|
+
const rawKey = part.slice(0, separator);
|
|
248
|
+
const rawValue = part.slice(separator + 1);
|
|
249
|
+
const key = decodeParam(rawKey);
|
|
250
|
+
const value = decodeParam(rawValue);
|
|
251
|
+
if (isCredentialSensitiveKey(key, options.sensitiveKeys) || options.isSensitiveValue(value)) {
|
|
252
|
+
redacted = true;
|
|
253
|
+
return `${rawKey}=${replacement}`;
|
|
254
|
+
}
|
|
255
|
+
return part;
|
|
256
|
+
});
|
|
257
|
+
return { value: parts.join("&"), redacted };
|
|
258
|
+
}
|
|
259
|
+
function redactUrlString(value, options) {
|
|
260
|
+
const unchanged = {
|
|
261
|
+
value,
|
|
262
|
+
credentialRedacted: false,
|
|
263
|
+
identifiersMasked: false
|
|
264
|
+
};
|
|
265
|
+
if (!looksLikeHttpUrl(value)) return unchanged;
|
|
266
|
+
const url = parseHttpUrl(value);
|
|
267
|
+
if (!url) return unchanged;
|
|
268
|
+
const replacement = options.replacement ?? "[REDACTED]";
|
|
269
|
+
const idPlaceholder = options.idPlaceholder ?? "[id]";
|
|
270
|
+
let credentialRedacted = url.username.length > 0 || url.password.length > 0;
|
|
271
|
+
let identifiersMasked = false;
|
|
272
|
+
let pathname = url.pathname;
|
|
273
|
+
if (options.maskPathIds === true) {
|
|
274
|
+
pathname = url.pathname.split("/").map((segment) => {
|
|
275
|
+
if (segment.length === 0 || !isIdentifierSegment(decodeParam(segment))) {
|
|
276
|
+
return segment;
|
|
277
|
+
}
|
|
278
|
+
identifiersMasked = true;
|
|
279
|
+
return idPlaceholder;
|
|
280
|
+
}).join("/");
|
|
281
|
+
}
|
|
282
|
+
let search = "";
|
|
283
|
+
if (url.search.length > 1) {
|
|
284
|
+
const params = redactParams(url.search.slice(1), options, replacement);
|
|
285
|
+
if (params.redacted) credentialRedacted = true;
|
|
286
|
+
search = `?${params.value}`;
|
|
287
|
+
} else if (url.search.length === 1) {
|
|
288
|
+
search = "?";
|
|
289
|
+
}
|
|
290
|
+
let hash = url.hash;
|
|
291
|
+
if (url.hash.includes("=")) {
|
|
292
|
+
const params = redactParams(url.hash.slice(1), options, replacement);
|
|
293
|
+
if (params.redacted) credentialRedacted = true;
|
|
294
|
+
hash = `#${params.value}`;
|
|
295
|
+
}
|
|
296
|
+
if (!credentialRedacted && !identifiersMasked) return unchanged;
|
|
297
|
+
return {
|
|
298
|
+
value: `${url.protocol}//${url.host}${pathname}${search}${hash}`,
|
|
299
|
+
credentialRedacted,
|
|
300
|
+
identifiersMasked
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
109
304
|
// packages/core/src/redaction-profiles.ts
|
|
110
305
|
var SHARE_PROFILE_EXTRA_KEYS = [
|
|
111
306
|
"userEmail",
|
|
@@ -208,21 +403,34 @@ function deepClone(value) {
|
|
|
208
403
|
}
|
|
209
404
|
return out;
|
|
210
405
|
}
|
|
211
|
-
function boundAttributeValues(record, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
406
|
+
function boundAttributeValues(record, sensitiveKeys, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
212
407
|
if (depth > 32) {
|
|
213
408
|
return { truncated: true, reason: "maxDepth" };
|
|
214
409
|
}
|
|
215
410
|
const out = {};
|
|
216
411
|
for (const [key, value] of Object.entries(record)) {
|
|
217
|
-
out[key] = boundValue(
|
|
412
|
+
out[key] = boundValue(
|
|
413
|
+
value,
|
|
414
|
+
key,
|
|
415
|
+
sensitiveKeys,
|
|
416
|
+
maxMetadataValueLength,
|
|
417
|
+
maxPreviewLength,
|
|
418
|
+
seen,
|
|
419
|
+
depth
|
|
420
|
+
);
|
|
218
421
|
}
|
|
219
422
|
return out;
|
|
220
423
|
}
|
|
221
|
-
function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
424
|
+
function boundValue(value, key, sensitiveKeys, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
222
425
|
if (value === null || typeof value !== "object") {
|
|
223
426
|
if (typeof value === "string") {
|
|
427
|
+
const rewritten = redactUrlString(value, {
|
|
428
|
+
sensitiveKeys,
|
|
429
|
+
isSensitiveValue: stringContainsHighConfidenceCredential,
|
|
430
|
+
maskPathIds: true
|
|
431
|
+
}).value;
|
|
224
432
|
return truncateStringForProfile(
|
|
225
|
-
|
|
433
|
+
stringContainsHighConfidenceCredential(rewritten) ? "[REDACTED]" : rewritten,
|
|
226
434
|
key,
|
|
227
435
|
maxMetadataValueLength,
|
|
228
436
|
maxPreviewLength
|
|
@@ -237,6 +445,7 @@ function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen,
|
|
|
237
445
|
(item, index) => boundValue(
|
|
238
446
|
item,
|
|
239
447
|
String(index),
|
|
448
|
+
sensitiveKeys,
|
|
240
449
|
maxMetadataValueLength,
|
|
241
450
|
maxPreviewLength,
|
|
242
451
|
seen,
|
|
@@ -246,6 +455,7 @@ function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen,
|
|
|
246
455
|
}
|
|
247
456
|
return boundAttributeValues(
|
|
248
457
|
value,
|
|
458
|
+
sensitiveKeys,
|
|
249
459
|
maxMetadataValueLength,
|
|
250
460
|
maxPreviewLength,
|
|
251
461
|
seen,
|
|
@@ -260,6 +470,7 @@ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPrevi
|
|
|
260
470
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
261
471
|
const bounded = boundAttributeValues(
|
|
262
472
|
redacted,
|
|
473
|
+
[...DEFAULT_REDACT_KEYS, ...redactor.sensitiveKeys],
|
|
263
474
|
maxMetadataValueLength,
|
|
264
475
|
maxPreviewLength,
|
|
265
476
|
seen,
|