@superblocksteam/telemetry 2.0.83-next.1
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/LICENSE.txt +87 -0
- package/README.md +155 -0
- package/dist/browser/index.d.ts +8 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +19 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/init.d.ts +75 -0
- package/dist/browser/init.d.ts.map +1 -0
- package/dist/browser/init.js +169 -0
- package/dist/browser/init.js.map +1 -0
- package/dist/browser/resilient-exporter.d.ts +43 -0
- package/dist/browser/resilient-exporter.d.ts.map +1 -0
- package/dist/browser/resilient-exporter.js +88 -0
- package/dist/browser/resilient-exporter.js.map +1 -0
- package/dist/common/contracts/tier2-traces.d.ts +75 -0
- package/dist/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist/common/contracts/tier2-traces.js +186 -0
- package/dist/common/contracts/tier2-traces.js.map +1 -0
- package/dist/common/deployment-type.d.ts +18 -0
- package/dist/common/deployment-type.d.ts.map +1 -0
- package/dist/common/deployment-type.js +30 -0
- package/dist/common/deployment-type.js.map +1 -0
- package/dist/common/guardrails.d.ts +116 -0
- package/dist/common/guardrails.d.ts.map +1 -0
- package/dist/common/guardrails.js +189 -0
- package/dist/common/guardrails.js.map +1 -0
- package/dist/common/index.d.ts +16 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +32 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/log-sanitizer.d.ts +78 -0
- package/dist/common/log-sanitizer.d.ts.map +1 -0
- package/dist/common/log-sanitizer.js +340 -0
- package/dist/common/log-sanitizer.js.map +1 -0
- package/dist/common/policy-evaluator.d.ts +103 -0
- package/dist/common/policy-evaluator.d.ts.map +1 -0
- package/dist/common/policy-evaluator.js +200 -0
- package/dist/common/policy-evaluator.js.map +1 -0
- package/dist/common/resource.d.ts +62 -0
- package/dist/common/resource.d.ts.map +1 -0
- package/dist/common/resource.js +106 -0
- package/dist/common/resource.js.map +1 -0
- package/dist/common/tier-hints.d.ts +182 -0
- package/dist/common/tier-hints.d.ts.map +1 -0
- package/dist/common/tier-hints.js +209 -0
- package/dist/common/tier-hints.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/forbidden-attributes.d.ts +149 -0
- package/dist/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist/lint/forbidden-attributes.js +214 -0
- package/dist/lint/forbidden-attributes.js.map +1 -0
- package/dist/lint/index.d.ts +9 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +16 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/llmobs/index.d.ts +22 -0
- package/dist/llmobs/index.d.ts.map +1 -0
- package/dist/llmobs/index.js +29 -0
- package/dist/llmobs/index.js.map +1 -0
- package/dist/llmobs/tier1-exporter.d.ts +146 -0
- package/dist/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist/llmobs/tier1-exporter.js +196 -0
- package/dist/llmobs/tier1-exporter.js.map +1 -0
- package/dist/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist/llmobs/tier2-summarizer.js +650 -0
- package/dist/llmobs/tier2-summarizer.js.map +1 -0
- package/dist/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist/node/exporters/resilient-exporter.js +129 -0
- package/dist/node/exporters/resilient-exporter.js.map +1 -0
- package/dist/node/index.d.ts +11 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +24 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/init.d.ts +75 -0
- package/dist/node/init.d.ts.map +1 -0
- package/dist/node/init.js +245 -0
- package/dist/node/init.js.map +1 -0
- package/dist/node/log-processor.d.ts +83 -0
- package/dist/node/log-processor.d.ts.map +1 -0
- package/dist/node/log-processor.js +266 -0
- package/dist/node/log-processor.js.map +1 -0
- package/dist/node/metrics-client.d.ts +66 -0
- package/dist/node/metrics-client.d.ts.map +1 -0
- package/dist/node/metrics-client.js +193 -0
- package/dist/node/metrics-client.js.map +1 -0
- package/dist/node/traced-socket.d.ts +76 -0
- package/dist/node/traced-socket.d.ts.map +1 -0
- package/dist/node/traced-socket.js +261 -0
- package/dist/node/traced-socket.js.map +1 -0
- package/dist/testing/in-memory-exporter.d.ts +179 -0
- package/dist/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist/testing/in-memory-exporter.js +254 -0
- package/dist/testing/in-memory-exporter.js.map +1 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +19 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/test-init.d.ts +80 -0
- package/dist/testing/test-init.d.ts.map +1 -0
- package/dist/testing/test-init.js +144 -0
- package/dist/testing/test-init.js.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/policy.d.ts +92 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +125 -0
- package/dist/types/policy.js.map +1 -0
- package/dist-esm/browser/index.d.ts +8 -0
- package/dist-esm/browser/index.d.ts.map +1 -0
- package/dist-esm/browser/index.js +9 -0
- package/dist-esm/browser/index.js.map +1 -0
- package/dist-esm/browser/init.d.ts +75 -0
- package/dist-esm/browser/init.d.ts.map +1 -0
- package/dist-esm/browser/init.js +162 -0
- package/dist-esm/browser/init.js.map +1 -0
- package/dist-esm/browser/resilient-exporter.d.ts +43 -0
- package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/browser/resilient-exporter.js +84 -0
- package/dist-esm/browser/resilient-exporter.js.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts +75 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.js +178 -0
- package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
- package/dist-esm/common/deployment-type.d.ts +18 -0
- package/dist-esm/common/deployment-type.d.ts.map +1 -0
- package/dist-esm/common/deployment-type.js +27 -0
- package/dist-esm/common/deployment-type.js.map +1 -0
- package/dist-esm/common/guardrails.d.ts +116 -0
- package/dist-esm/common/guardrails.d.ts.map +1 -0
- package/dist-esm/common/guardrails.js +179 -0
- package/dist-esm/common/guardrails.js.map +1 -0
- package/dist-esm/common/index.d.ts +16 -0
- package/dist-esm/common/index.d.ts.map +1 -0
- package/dist-esm/common/index.js +16 -0
- package/dist-esm/common/index.js.map +1 -0
- package/dist-esm/common/log-sanitizer.d.ts +78 -0
- package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
- package/dist-esm/common/log-sanitizer.js +331 -0
- package/dist-esm/common/log-sanitizer.js.map +1 -0
- package/dist-esm/common/policy-evaluator.d.ts +103 -0
- package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
- package/dist-esm/common/policy-evaluator.js +196 -0
- package/dist-esm/common/policy-evaluator.js.map +1 -0
- package/dist-esm/common/resource.d.ts +62 -0
- package/dist-esm/common/resource.d.ts.map +1 -0
- package/dist-esm/common/resource.js +100 -0
- package/dist-esm/common/resource.js.map +1 -0
- package/dist-esm/common/tier-hints.d.ts +182 -0
- package/dist-esm/common/tier-hints.d.ts.map +1 -0
- package/dist-esm/common/tier-hints.js +199 -0
- package/dist-esm/common/tier-hints.js.map +1 -0
- package/dist-esm/index.d.ts +43 -0
- package/dist-esm/index.d.ts.map +1 -0
- package/dist-esm/index.js +53 -0
- package/dist-esm/index.js.map +1 -0
- package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
- package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist-esm/lint/forbidden-attributes.js +209 -0
- package/dist-esm/lint/forbidden-attributes.js.map +1 -0
- package/dist-esm/lint/index.d.ts +9 -0
- package/dist-esm/lint/index.d.ts.map +1 -0
- package/dist-esm/lint/index.js +9 -0
- package/dist-esm/lint/index.js.map +1 -0
- package/dist-esm/llmobs/index.d.ts +22 -0
- package/dist-esm/llmobs/index.d.ts.map +1 -0
- package/dist-esm/llmobs/index.js +22 -0
- package/dist-esm/llmobs/index.js.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.js +190 -0
- package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.js +646 -0
- package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.js +125 -0
- package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
- package/dist-esm/node/index.d.ts +11 -0
- package/dist-esm/node/index.d.ts.map +1 -0
- package/dist-esm/node/index.js +11 -0
- package/dist-esm/node/index.js.map +1 -0
- package/dist-esm/node/init.d.ts +75 -0
- package/dist-esm/node/init.d.ts.map +1 -0
- package/dist-esm/node/init.js +239 -0
- package/dist-esm/node/init.js.map +1 -0
- package/dist-esm/node/log-processor.d.ts +83 -0
- package/dist-esm/node/log-processor.d.ts.map +1 -0
- package/dist-esm/node/log-processor.js +261 -0
- package/dist-esm/node/log-processor.js.map +1 -0
- package/dist-esm/node/metrics-client.d.ts +66 -0
- package/dist-esm/node/metrics-client.d.ts.map +1 -0
- package/dist-esm/node/metrics-client.js +189 -0
- package/dist-esm/node/metrics-client.js.map +1 -0
- package/dist-esm/node/traced-socket.d.ts +76 -0
- package/dist-esm/node/traced-socket.d.ts.map +1 -0
- package/dist-esm/node/traced-socket.js +257 -0
- package/dist-esm/node/traced-socket.js.map +1 -0
- package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
- package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist-esm/testing/in-memory-exporter.js +248 -0
- package/dist-esm/testing/in-memory-exporter.js.map +1 -0
- package/dist-esm/testing/index.d.ts +8 -0
- package/dist-esm/testing/index.d.ts.map +1 -0
- package/dist-esm/testing/index.js +8 -0
- package/dist-esm/testing/index.js.map +1 -0
- package/dist-esm/testing/test-init.d.ts +80 -0
- package/dist-esm/testing/test-init.d.ts.map +1 -0
- package/dist-esm/testing/test-init.js +137 -0
- package/dist-esm/testing/test-init.js.map +1 -0
- package/dist-esm/types/index.d.ts +40 -0
- package/dist-esm/types/index.d.ts.map +1 -0
- package/dist-esm/types/index.js +7 -0
- package/dist-esm/types/index.js.map +1 -0
- package/dist-esm/types/policy.d.ts +92 -0
- package/dist-esm/types/policy.d.ts.map +1 -0
- package/dist-esm/types/policy.js +122 -0
- package/dist-esm/types/policy.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Sanitizer for Application-Level Secret Protection
|
|
3
|
+
*
|
|
4
|
+
* Sanitizes secrets from log messages while preserving debugging information.
|
|
5
|
+
* This operates at the APPLICATION layer and only removes secrets that should
|
|
6
|
+
* NEVER appear in any log, anywhere.
|
|
7
|
+
*
|
|
8
|
+
* ARCHITECTURE:
|
|
9
|
+
* - Application layer (this file): Secrets-only sanitization (unconditional)
|
|
10
|
+
* - Pipeline layer (OTel Collector): Tier-based filtering for export
|
|
11
|
+
*
|
|
12
|
+
* Stack traces, emails, file paths are preserved for debugging. The pipeline
|
|
13
|
+
* layer handles redacting these for Tier 2 export in cloud-prem deployments.
|
|
14
|
+
*
|
|
15
|
+
* @see https://github.com/superblocksteam/engineering/blob/main/projects/o11y-refactor/epics/epic-c4-logging-strategy.md
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Fields that contain secrets and should be stripped from log objects.
|
|
19
|
+
* Only includes actual secret field names - NOT debugging info.
|
|
20
|
+
*
|
|
21
|
+
* Pipeline-layer concerns (AI content, stack traces, PII) are NOT included here.
|
|
22
|
+
* Those are handled by the OTel Collector for tier-based export filtering.
|
|
23
|
+
*/
|
|
24
|
+
export declare const SECRET_FIELDS: Set<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a field name contains secrets using word boundary matching.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isSecretField(fieldName: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated Use SECRET_FIELDS instead. This export is kept for backward
|
|
31
|
+
* compatibility but now only contains secret fields, not Tier 1 content fields.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TIER1_FORBIDDEN_LOG_FIELDS: Set<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Sanitizes secrets from a log message string.
|
|
36
|
+
* Preserves debugging info (emails, file paths, etc.) for troubleshooting.
|
|
37
|
+
*
|
|
38
|
+
* @param message - The log message to sanitize
|
|
39
|
+
* @returns Message with secrets redacted
|
|
40
|
+
*/
|
|
41
|
+
export declare function sanitizeLogMessage(message: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Sanitizes secrets within a stack trace while preserving the full trace.
|
|
44
|
+
* Stack traces are essential for debugging - only redact secrets within them.
|
|
45
|
+
*
|
|
46
|
+
* @param stack - The stack trace string
|
|
47
|
+
* @returns Stack trace with secrets redacted but structure preserved
|
|
48
|
+
*/
|
|
49
|
+
export declare function redactStackTrace(stack: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Recursively sanitizes secrets from an object.
|
|
52
|
+
* Strips secret fields entirely, sanitizes secrets in string values.
|
|
53
|
+
* Preserves debugging info (stack traces, file paths, emails).
|
|
54
|
+
*
|
|
55
|
+
* @param obj - The object to sanitize
|
|
56
|
+
* @param depth - Current recursion depth (default: 0)
|
|
57
|
+
* @returns Object with secrets removed
|
|
58
|
+
*/
|
|
59
|
+
export declare function sanitizeLogObject<T>(obj: T, depth?: number): T;
|
|
60
|
+
/**
|
|
61
|
+
* Sanitizes secrets from an error object.
|
|
62
|
+
* Preserves full stack traces for debugging.
|
|
63
|
+
*
|
|
64
|
+
* @param error - The error to sanitize
|
|
65
|
+
* @returns Error object with secrets redacted
|
|
66
|
+
*/
|
|
67
|
+
export declare function sanitizeLogError(error: unknown): unknown;
|
|
68
|
+
/**
|
|
69
|
+
* Safe JSON stringify with secret sanitization.
|
|
70
|
+
* Handles circular references and non-serializable types.
|
|
71
|
+
* Preserves debugging info (stack traces, file paths, emails).
|
|
72
|
+
*
|
|
73
|
+
* @param obj - Object to stringify
|
|
74
|
+
* @param space - Indentation (optional)
|
|
75
|
+
* @returns JSON string with secrets redacted
|
|
76
|
+
*/
|
|
77
|
+
export declare function safeJsonStringify(obj: unknown, space?: string | number): string;
|
|
78
|
+
//# sourceMappingURL=log-sanitizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-sanitizer.d.ts","sourceRoot":"","sources":["../../src/common/log-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAmFH;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAqBxB,CAAC;AA+BH;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAMxD;AAMD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,aAAgB,CAAC;AAMxD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,SAAI,GAAG,CAAC,CAyCzD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAsCxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CA6DR"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Sanitizer for Application-Level Secret Protection
|
|
3
|
+
*
|
|
4
|
+
* Sanitizes secrets from log messages while preserving debugging information.
|
|
5
|
+
* This operates at the APPLICATION layer and only removes secrets that should
|
|
6
|
+
* NEVER appear in any log, anywhere.
|
|
7
|
+
*
|
|
8
|
+
* ARCHITECTURE:
|
|
9
|
+
* - Application layer (this file): Secrets-only sanitization (unconditional)
|
|
10
|
+
* - Pipeline layer (OTel Collector): Tier-based filtering for export
|
|
11
|
+
*
|
|
12
|
+
* Stack traces, emails, file paths are preserved for debugging. The pipeline
|
|
13
|
+
* layer handles redacting these for Tier 2 export in cloud-prem deployments.
|
|
14
|
+
*
|
|
15
|
+
* @see https://github.com/superblocksteam/engineering/blob/main/projects/o11y-refactor/epics/epic-c4-logging-strategy.md
|
|
16
|
+
*/
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Secret Patterns - These should NEVER appear in any log
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Patterns that indicate tokens, keys, and secrets in log messages.
|
|
22
|
+
* These use capture groups to preserve prefixes while redacting values.
|
|
23
|
+
*/
|
|
24
|
+
const SECRET_PATTERNS = [
|
|
25
|
+
// Tokens and keys with prefixes
|
|
26
|
+
{
|
|
27
|
+
pattern: /(\bbearer\s+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
28
|
+
replacement: "$1[REDACTED]",
|
|
29
|
+
},
|
|
30
|
+
{ pattern: /(\bbasic\s+)\S+/gi, replacement: "$1[REDACTED]" },
|
|
31
|
+
{ pattern: /(\bjwt\s+)[a-zA-Z0-9\-._~+/]+=*/gi, replacement: "$1[REDACTED]" },
|
|
32
|
+
{
|
|
33
|
+
pattern: /(\btoken[:\s=]+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
34
|
+
replacement: "$1[REDACTED]",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: /(\bapi[_\s]?key[:\s=]+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
38
|
+
replacement: "$1[REDACTED]",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
pattern: /(\baccess[_\s]?token[:\s=]+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
42
|
+
replacement: "$1[REDACTED]",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pattern: /(\brefresh[_\s]?token[:\s=]+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
46
|
+
replacement: "$1[REDACTED]",
|
|
47
|
+
},
|
|
48
|
+
// JWT pattern (base64.base64.base64) - standalone tokens
|
|
49
|
+
{
|
|
50
|
+
pattern: /\b[A-Za-z0-9-_]{20,}\.[A-Za-z0-9-_]{20,}\.[A-Za-z0-9-_]{20,}\b/g,
|
|
51
|
+
replacement: "[JWT_REDACTED]",
|
|
52
|
+
},
|
|
53
|
+
// OpenAI API keys
|
|
54
|
+
{ pattern: /\bsk-[A-Za-z0-9]{48}\b/g, replacement: "[OPENAI_KEY_REDACTED]" },
|
|
55
|
+
// Anthropic API keys
|
|
56
|
+
{
|
|
57
|
+
pattern: /\bsk-ant-[A-Za-z0-9-]{32,}\b/g,
|
|
58
|
+
replacement: "[ANTHROPIC_KEY_REDACTED]",
|
|
59
|
+
},
|
|
60
|
+
// AWS access key IDs
|
|
61
|
+
{ pattern: /\bAKIA[A-Z0-9]{16}\b/g, replacement: "[AWS_KEY_REDACTED]" },
|
|
62
|
+
// GitHub tokens
|
|
63
|
+
{
|
|
64
|
+
pattern: /\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/g,
|
|
65
|
+
replacement: "[GITHUB_TOKEN_REDACTED]",
|
|
66
|
+
},
|
|
67
|
+
// Generic API key patterns
|
|
68
|
+
{
|
|
69
|
+
pattern: /\b(sk|pk)-[a-zA-Z0-9]{32,}\b/g,
|
|
70
|
+
replacement: "[API_KEY_REDACTED]",
|
|
71
|
+
},
|
|
72
|
+
// Connection strings with credentials
|
|
73
|
+
{
|
|
74
|
+
pattern: /\b(postgres|mysql|mongodb|redis):\/\/[^\s]+:[^\s]+@[^\s]+/gi,
|
|
75
|
+
replacement: "[CONNECTION_STRING_REDACTED]",
|
|
76
|
+
},
|
|
77
|
+
// PEM blocks
|
|
78
|
+
{
|
|
79
|
+
pattern: /-----BEGIN\s+(RSA\s+)?(PRIVATE|PUBLIC)\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?(PRIVATE|PUBLIC)\s+KEY-----/g,
|
|
80
|
+
replacement: "[PEM_KEY_REDACTED]",
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// Secret Fields - Field names that contain secrets
|
|
85
|
+
// ============================================================================
|
|
86
|
+
/**
|
|
87
|
+
* Fields that contain secrets and should be stripped from log objects.
|
|
88
|
+
* Only includes actual secret field names - NOT debugging info.
|
|
89
|
+
*
|
|
90
|
+
* Pipeline-layer concerns (AI content, stack traces, PII) are NOT included here.
|
|
91
|
+
* Those are handled by the OTel Collector for tier-based export filtering.
|
|
92
|
+
*/
|
|
93
|
+
export const SECRET_FIELDS = new Set([
|
|
94
|
+
// Auth/secrets
|
|
95
|
+
"password",
|
|
96
|
+
"passwd",
|
|
97
|
+
"secret",
|
|
98
|
+
"private_key",
|
|
99
|
+
"privatekey",
|
|
100
|
+
"credentials",
|
|
101
|
+
"token",
|
|
102
|
+
"accesstoken",
|
|
103
|
+
"access_token",
|
|
104
|
+
"refreshtoken",
|
|
105
|
+
"refresh_token",
|
|
106
|
+
"jwt",
|
|
107
|
+
"bearer",
|
|
108
|
+
"apikey",
|
|
109
|
+
"api_key",
|
|
110
|
+
"auth_token",
|
|
111
|
+
"authorization",
|
|
112
|
+
"cookie",
|
|
113
|
+
"x-api-key",
|
|
114
|
+
]);
|
|
115
|
+
/**
|
|
116
|
+
* Patterns for compound field names that contain secrets.
|
|
117
|
+
* Uses word boundary matching to avoid false positives.
|
|
118
|
+
*/
|
|
119
|
+
const SECRET_FIELD_PATTERNS = [
|
|
120
|
+
// Password patterns
|
|
121
|
+
/(?:^|[._-])password(?:[._-]|$)/i,
|
|
122
|
+
/(?:^|[._-])passwd(?:[._-]|$)/i,
|
|
123
|
+
// Secret patterns
|
|
124
|
+
/(?:^|[._-])secret(?:[._-]|$)/i,
|
|
125
|
+
/(?:^|[._-])private[._-]?key(?:[._-]|$)/i,
|
|
126
|
+
// Token patterns
|
|
127
|
+
/(?:^|[._-])token(?:[._-]|$)/i,
|
|
128
|
+
/(?:^|[._-])jwt(?:[._-]|$)/i,
|
|
129
|
+
/(?:^|[._-])bearer(?:[._-]|$)/i,
|
|
130
|
+
// Credential patterns
|
|
131
|
+
/(?:^|[._-])credentials?(?:[._-]|$)/i,
|
|
132
|
+
// API key patterns
|
|
133
|
+
/api[._-]?key/i,
|
|
134
|
+
/x[._-]api[._-]key/i,
|
|
135
|
+
// Auth token patterns
|
|
136
|
+
/auth[._-]token/i,
|
|
137
|
+
];
|
|
138
|
+
/**
|
|
139
|
+
* Check if a field name contains secrets using word boundary matching.
|
|
140
|
+
*/
|
|
141
|
+
export function isSecretField(fieldName) {
|
|
142
|
+
const lowerKey = fieldName.toLowerCase();
|
|
143
|
+
if (SECRET_FIELDS.has(lowerKey)) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return SECRET_FIELD_PATTERNS.some((pattern) => pattern.test(lowerKey));
|
|
147
|
+
}
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Legacy exports for backward compatibility
|
|
150
|
+
// ============================================================================
|
|
151
|
+
/**
|
|
152
|
+
* @deprecated Use SECRET_FIELDS instead. This export is kept for backward
|
|
153
|
+
* compatibility but now only contains secret fields, not Tier 1 content fields.
|
|
154
|
+
*/
|
|
155
|
+
export const TIER1_FORBIDDEN_LOG_FIELDS = SECRET_FIELDS;
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// Public API
|
|
158
|
+
// ============================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Sanitizes secrets from a log message string.
|
|
161
|
+
* Preserves debugging info (emails, file paths, etc.) for troubleshooting.
|
|
162
|
+
*
|
|
163
|
+
* @param message - The log message to sanitize
|
|
164
|
+
* @returns Message with secrets redacted
|
|
165
|
+
*/
|
|
166
|
+
export function sanitizeLogMessage(message) {
|
|
167
|
+
if (!message || typeof message !== "string") {
|
|
168
|
+
return message;
|
|
169
|
+
}
|
|
170
|
+
let sanitized = message;
|
|
171
|
+
// Only apply secret patterns - preserve debugging info
|
|
172
|
+
for (const { pattern, replacement } of SECRET_PATTERNS) {
|
|
173
|
+
pattern.lastIndex = 0; // Reset regex state for global patterns
|
|
174
|
+
sanitized = sanitized.replace(pattern, replacement);
|
|
175
|
+
}
|
|
176
|
+
return sanitized;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Sanitizes secrets within a stack trace while preserving the full trace.
|
|
180
|
+
* Stack traces are essential for debugging - only redact secrets within them.
|
|
181
|
+
*
|
|
182
|
+
* @param stack - The stack trace string
|
|
183
|
+
* @returns Stack trace with secrets redacted but structure preserved
|
|
184
|
+
*/
|
|
185
|
+
export function redactStackTrace(stack) {
|
|
186
|
+
if (!stack || typeof stack !== "string") {
|
|
187
|
+
return stack;
|
|
188
|
+
}
|
|
189
|
+
// Preserve full stack trace, only sanitize secrets within
|
|
190
|
+
return sanitizeLogMessage(stack);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Recursively sanitizes secrets from an object.
|
|
194
|
+
* Strips secret fields entirely, sanitizes secrets in string values.
|
|
195
|
+
* Preserves debugging info (stack traces, file paths, emails).
|
|
196
|
+
*
|
|
197
|
+
* @param obj - The object to sanitize
|
|
198
|
+
* @param depth - Current recursion depth (default: 0)
|
|
199
|
+
* @returns Object with secrets removed
|
|
200
|
+
*/
|
|
201
|
+
export function sanitizeLogObject(obj, depth = 0) {
|
|
202
|
+
// Prevent infinite recursion
|
|
203
|
+
if (depth > 10) {
|
|
204
|
+
return "[MAX_DEPTH_REACHED]";
|
|
205
|
+
}
|
|
206
|
+
if (obj === null || obj === undefined) {
|
|
207
|
+
return obj;
|
|
208
|
+
}
|
|
209
|
+
if (typeof obj === "string") {
|
|
210
|
+
return sanitizeLogMessage(obj);
|
|
211
|
+
}
|
|
212
|
+
if (typeof obj === "number" || typeof obj === "boolean") {
|
|
213
|
+
return obj;
|
|
214
|
+
}
|
|
215
|
+
if (typeof obj !== "object") {
|
|
216
|
+
return obj;
|
|
217
|
+
}
|
|
218
|
+
if (Array.isArray(obj)) {
|
|
219
|
+
return obj.map((item) => sanitizeLogObject(item, depth + 1));
|
|
220
|
+
}
|
|
221
|
+
const sanitized = {};
|
|
222
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
223
|
+
// Skip secret fields entirely
|
|
224
|
+
if (isSecretField(key)) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
// Recursively sanitize all other fields
|
|
228
|
+
sanitized[key] = sanitizeLogObject(value, depth + 1);
|
|
229
|
+
}
|
|
230
|
+
return sanitized;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Sanitizes secrets from an error object.
|
|
234
|
+
* Preserves full stack traces for debugging.
|
|
235
|
+
*
|
|
236
|
+
* @param error - The error to sanitize
|
|
237
|
+
* @returns Error object with secrets redacted
|
|
238
|
+
*/
|
|
239
|
+
export function sanitizeLogError(error) {
|
|
240
|
+
if (!error) {
|
|
241
|
+
return error;
|
|
242
|
+
}
|
|
243
|
+
// Check if already sanitized
|
|
244
|
+
const errorWithSanitized = error;
|
|
245
|
+
if (errorWithSanitized._sanitized) {
|
|
246
|
+
return error;
|
|
247
|
+
}
|
|
248
|
+
if (error instanceof Error) {
|
|
249
|
+
const sanitized = {
|
|
250
|
+
name: error.name,
|
|
251
|
+
message: sanitizeLogMessage(error.message),
|
|
252
|
+
// Preserve full stack trace, only sanitize secrets within
|
|
253
|
+
stack: sanitizeLogMessage(error.stack || ""),
|
|
254
|
+
_sanitized: true,
|
|
255
|
+
};
|
|
256
|
+
// Copy and sanitize enumerable properties
|
|
257
|
+
for (const [key, value] of Object.entries(error)) {
|
|
258
|
+
if (key !== "name" && key !== "message" && key !== "stack") {
|
|
259
|
+
// Skip secret fields
|
|
260
|
+
if (isSecretField(key)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
sanitized[key] = sanitizeLogObject(value);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return sanitized;
|
|
267
|
+
}
|
|
268
|
+
// For non-Error objects, sanitize the entire object
|
|
269
|
+
const sanitized = sanitizeLogObject(error);
|
|
270
|
+
sanitized._sanitized = true;
|
|
271
|
+
return sanitized;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Safe JSON stringify with secret sanitization.
|
|
275
|
+
* Handles circular references and non-serializable types.
|
|
276
|
+
* Preserves debugging info (stack traces, file paths, emails).
|
|
277
|
+
*
|
|
278
|
+
* @param obj - Object to stringify
|
|
279
|
+
* @param space - Indentation (optional)
|
|
280
|
+
* @returns JSON string with secrets redacted
|
|
281
|
+
*/
|
|
282
|
+
export function safeJsonStringify(obj, space) {
|
|
283
|
+
if (obj === null || obj === undefined) {
|
|
284
|
+
return "{}";
|
|
285
|
+
}
|
|
286
|
+
if (typeof obj === "string") {
|
|
287
|
+
return sanitizeLogMessage(obj);
|
|
288
|
+
}
|
|
289
|
+
const seen = new WeakSet();
|
|
290
|
+
return JSON.stringify(obj, (key, value) => {
|
|
291
|
+
// Skip secret fields
|
|
292
|
+
if (key && isSecretField(key)) {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
// Handle null/undefined
|
|
296
|
+
if (value === null || value === undefined) {
|
|
297
|
+
return value;
|
|
298
|
+
}
|
|
299
|
+
// Handle circular references
|
|
300
|
+
if (typeof value === "object") {
|
|
301
|
+
if (seen.has(value)) {
|
|
302
|
+
return "[Circular Reference]";
|
|
303
|
+
}
|
|
304
|
+
seen.add(value);
|
|
305
|
+
// Handle Error objects - preserve full stack trace
|
|
306
|
+
if (value instanceof Error) {
|
|
307
|
+
return {
|
|
308
|
+
name: value.name,
|
|
309
|
+
message: sanitizeLogMessage(value.message),
|
|
310
|
+
stack: sanitizeLogMessage(value.stack || ""),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Sanitize string values
|
|
315
|
+
if (typeof value === "string") {
|
|
316
|
+
return sanitizeLogMessage(value);
|
|
317
|
+
}
|
|
318
|
+
// Handle non-serializable types
|
|
319
|
+
if (typeof value === "function") {
|
|
320
|
+
return `[Function: ${value.name || "anonymous"}]`;
|
|
321
|
+
}
|
|
322
|
+
if (typeof value === "symbol") {
|
|
323
|
+
return `[Symbol: ${value.toString()}]`;
|
|
324
|
+
}
|
|
325
|
+
if (typeof value === "bigint") {
|
|
326
|
+
return `[BigInt: ${value.toString()}]`;
|
|
327
|
+
}
|
|
328
|
+
return value;
|
|
329
|
+
}, space);
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=log-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-sanitizer.js","sourceRoot":"","sources":["../../src/common/log-sanitizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Evaluator
|
|
3
|
+
*
|
|
4
|
+
* Evaluates telemetry routing decisions based on policy configuration.
|
|
5
|
+
*/
|
|
6
|
+
import { TelemetryPolicy, TelemetryTier } from "../types/policy.js";
|
|
7
|
+
/**
|
|
8
|
+
* Result of a policy evaluation.
|
|
9
|
+
*/
|
|
10
|
+
export interface PolicyDecision {
|
|
11
|
+
/** Should this data be retained locally? */
|
|
12
|
+
retainLocal: boolean;
|
|
13
|
+
/** Should this data be exported? */
|
|
14
|
+
export: boolean;
|
|
15
|
+
/** Sampling decision */
|
|
16
|
+
sampled: boolean;
|
|
17
|
+
/** If blocked, the reason */
|
|
18
|
+
blockReason?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Evaluator for telemetry policy decisions.
|
|
22
|
+
*
|
|
23
|
+
* IMPORTANT: This evaluator determines ROUTING eligibility, not trace sampling.
|
|
24
|
+
*
|
|
25
|
+
* For TRACES: Sampling must be handled by the OTel SDK Sampler (parent-based,
|
|
26
|
+
* trace-ID ratio) to ensure trace consistency.
|
|
27
|
+
*
|
|
28
|
+
* For METRICS/LOGS: sampleRate applies with deterministic trace-ID-based logic.
|
|
29
|
+
*/
|
|
30
|
+
export declare class TelemetryPolicyEvaluator {
|
|
31
|
+
private readonly policy;
|
|
32
|
+
constructor(policy: TelemetryPolicy);
|
|
33
|
+
/**
|
|
34
|
+
* Get the current policy.
|
|
35
|
+
*/
|
|
36
|
+
getPolicy(): TelemetryPolicy;
|
|
37
|
+
/**
|
|
38
|
+
* Evaluate whether a telemetry signal should be processed/exported.
|
|
39
|
+
*
|
|
40
|
+
* @param tier - The tier this signal belongs to
|
|
41
|
+
* @param orgId - Optional org ID for org-specific overrides
|
|
42
|
+
* @param traceId - Optional trace ID for deterministic sampling
|
|
43
|
+
* @returns PolicyDecision
|
|
44
|
+
*/
|
|
45
|
+
evaluate(tier: TelemetryTier, orgId?: string, traceId?: string): PolicyDecision;
|
|
46
|
+
/**
|
|
47
|
+
* Check if export infrastructure should be created for a tier.
|
|
48
|
+
*
|
|
49
|
+
* This checks ONLY whether export is enabled in policy configuration.
|
|
50
|
+
* It does NOT apply sampling - use this for SDK initialization decisions.
|
|
51
|
+
*
|
|
52
|
+
* @param tier - The tier to check
|
|
53
|
+
* @param orgId - Optional org ID for org-specific overrides
|
|
54
|
+
* @returns true if export infrastructure should be created
|
|
55
|
+
*/
|
|
56
|
+
isExportEnabled(tier: TelemetryTier, orgId?: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Check if an export attempt is allowed (includes sampling).
|
|
59
|
+
*
|
|
60
|
+
* This applies sampling logic and should be used for per-span/per-signal
|
|
61
|
+
* decisions at runtime, NOT for infrastructure initialization.
|
|
62
|
+
*
|
|
63
|
+
* @param tier - The tier to check
|
|
64
|
+
* @param orgId - Optional org ID for org-specific overrides
|
|
65
|
+
* @param traceId - Optional trace ID for deterministic sampling
|
|
66
|
+
* @returns true if export is allowed for this specific signal
|
|
67
|
+
*/
|
|
68
|
+
canExport(tier: TelemetryTier, orgId?: string, traceId?: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Assert export is allowed, throwing or logging based on enforcement mode.
|
|
71
|
+
*
|
|
72
|
+
* @param tier - The tier to check
|
|
73
|
+
* @param orgId - Optional org ID for org-specific overrides
|
|
74
|
+
* @throws Error if in ENFORCE mode and export is blocked
|
|
75
|
+
*/
|
|
76
|
+
assertCanExport(tier: TelemetryTier, orgId?: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Check if Tier 3 content export is enabled.
|
|
79
|
+
*
|
|
80
|
+
* @returns true if Tier 3 prompts/responses can be exported
|
|
81
|
+
*/
|
|
82
|
+
canExportTier3Content(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Get the effective policy for an org (applying overrides if present).
|
|
85
|
+
*
|
|
86
|
+
* Performs deep merge for nested objects (tiers, tier3Content) to ensure
|
|
87
|
+
* partial overrides don't clobber unspecified configurations.
|
|
88
|
+
*
|
|
89
|
+
* @param orgId - Optional org ID
|
|
90
|
+
* @returns Effective policy
|
|
91
|
+
*/
|
|
92
|
+
private getEffectivePolicy;
|
|
93
|
+
/**
|
|
94
|
+
* Deterministic sampling based on trace ID (W3C TraceContext recommendation).
|
|
95
|
+
* Uses last 8 hex chars for uniform distribution in [0, 1).
|
|
96
|
+
*
|
|
97
|
+
* @param traceId - The trace ID (must be at least 8 hex characters)
|
|
98
|
+
* @param sampleRate - Sample rate (0.0 - 1.0)
|
|
99
|
+
* @returns true if sampled
|
|
100
|
+
*/
|
|
101
|
+
private traceIdBasedSample;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=policy-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-evaluator.d.ts","sourceRoot":"","sources":["../../src/common/policy-evaluator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,aAAa,EAEd,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,WAAW,EAAE,OAAO,CAAC;IACrB,oCAAoC;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,wBAAwB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,qBAAa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAEpD;;OAEG;IACH,SAAS,IAAI,eAAe;IAI5B;;;;;;;OAOG;IACH,QAAQ,CACN,IAAI,EAAE,aAAa,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf,cAAc;IAoCjB;;;;;;;;;OASG;IACH,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAM7D;;;;;;;;;;OAUG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAKzE;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAW1D;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAOhC;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IA2C1B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;CAwB3B"}
|