guardrail-compliance 1.0.0

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.
Files changed (149) hide show
  1. package/dist/audit/emitter.d.ts +97 -0
  2. package/dist/audit/emitter.d.ts.map +1 -0
  3. package/dist/audit/emitter.js +197 -0
  4. package/dist/audit/events.d.ts +304 -0
  5. package/dist/audit/events.d.ts.map +1 -0
  6. package/dist/audit/events.js +267 -0
  7. package/dist/audit/index.d.ts +11 -0
  8. package/dist/audit/index.d.ts.map +1 -0
  9. package/dist/audit/index.js +51 -0
  10. package/dist/audit/storage.d.ts +93 -0
  11. package/dist/audit/storage.d.ts.map +1 -0
  12. package/dist/audit/storage.js +337 -0
  13. package/dist/automation/__tests__/compliance-scheduler.test.d.ts +2 -0
  14. package/dist/automation/__tests__/compliance-scheduler.test.d.ts.map +1 -0
  15. package/dist/automation/__tests__/compliance-scheduler.test.js +140 -0
  16. package/dist/automation/audit-logger.d.ts +129 -0
  17. package/dist/automation/audit-logger.d.ts.map +1 -0
  18. package/dist/automation/audit-logger.js +473 -0
  19. package/dist/automation/compliance-scheduler-fixed.d.ts +1 -0
  20. package/dist/automation/compliance-scheduler-fixed.d.ts.map +1 -0
  21. package/dist/automation/compliance-scheduler-fixed.js +1 -0
  22. package/dist/automation/compliance-scheduler.d.ts +83 -0
  23. package/dist/automation/compliance-scheduler.d.ts.map +1 -0
  24. package/dist/automation/compliance-scheduler.js +414 -0
  25. package/dist/automation/dashboard.d.ts +194 -0
  26. package/dist/automation/dashboard.d.ts.map +1 -0
  27. package/dist/automation/dashboard.js +768 -0
  28. package/dist/automation/email-service.d.ts +69 -0
  29. package/dist/automation/email-service.d.ts.map +1 -0
  30. package/dist/automation/email-service.js +218 -0
  31. package/dist/automation/evidence-collector.d.ts +140 -0
  32. package/dist/automation/evidence-collector.d.ts.map +1 -0
  33. package/dist/automation/evidence-collector.js +682 -0
  34. package/dist/automation/index.d.ts +8 -0
  35. package/dist/automation/index.d.ts.map +1 -0
  36. package/dist/automation/index.js +24 -0
  37. package/dist/automation/pdf-exporter.d.ts +90 -0
  38. package/dist/automation/pdf-exporter.d.ts.map +1 -0
  39. package/dist/automation/pdf-exporter.js +381 -0
  40. package/dist/automation/reporting-engine.d.ts +116 -0
  41. package/dist/automation/reporting-engine.d.ts.map +1 -0
  42. package/dist/automation/reporting-engine.js +329 -0
  43. package/dist/container/index.d.ts +4 -0
  44. package/dist/container/index.d.ts.map +1 -0
  45. package/dist/container/index.js +19 -0
  46. package/dist/container/kubernetes.d.ts +94 -0
  47. package/dist/container/kubernetes.d.ts.map +1 -0
  48. package/dist/container/kubernetes.js +268 -0
  49. package/dist/container/rules.d.ts +27 -0
  50. package/dist/container/rules.d.ts.map +1 -0
  51. package/dist/container/rules.js +216 -0
  52. package/dist/container/scanner.d.ts +50 -0
  53. package/dist/container/scanner.d.ts.map +1 -0
  54. package/dist/container/scanner.js +143 -0
  55. package/dist/frameworks/engine.d.ts +108 -0
  56. package/dist/frameworks/engine.d.ts.map +1 -0
  57. package/dist/frameworks/engine.js +206 -0
  58. package/dist/frameworks/gdpr.d.ts +6 -0
  59. package/dist/frameworks/gdpr.d.ts.map +1 -0
  60. package/dist/frameworks/gdpr.js +198 -0
  61. package/dist/frameworks/hipaa.d.ts +6 -0
  62. package/dist/frameworks/hipaa.d.ts.map +1 -0
  63. package/dist/frameworks/hipaa.js +183 -0
  64. package/dist/frameworks/index.d.ts +8 -0
  65. package/dist/frameworks/index.d.ts.map +1 -0
  66. package/dist/frameworks/index.js +30 -0
  67. package/dist/frameworks/iso27001.d.ts +63 -0
  68. package/dist/frameworks/iso27001.d.ts.map +1 -0
  69. package/dist/frameworks/iso27001.js +331 -0
  70. package/dist/frameworks/nist.d.ts +62 -0
  71. package/dist/frameworks/nist.d.ts.map +1 -0
  72. package/dist/frameworks/nist.js +424 -0
  73. package/dist/frameworks/pci.d.ts +6 -0
  74. package/dist/frameworks/pci.d.ts.map +1 -0
  75. package/dist/frameworks/pci.js +201 -0
  76. package/dist/frameworks/soc2.d.ts +7 -0
  77. package/dist/frameworks/soc2.d.ts.map +1 -0
  78. package/dist/frameworks/soc2.js +248 -0
  79. package/dist/iac/drift-detector.d.ts +64 -0
  80. package/dist/iac/drift-detector.d.ts.map +1 -0
  81. package/dist/iac/drift-detector.js +134 -0
  82. package/dist/iac/index.d.ts +4 -0
  83. package/dist/iac/index.d.ts.map +1 -0
  84. package/dist/iac/index.js +19 -0
  85. package/dist/iac/rules.d.ts +17 -0
  86. package/dist/iac/rules.d.ts.map +1 -0
  87. package/dist/iac/rules.js +385 -0
  88. package/dist/iac/scanner.d.ts +104 -0
  89. package/dist/iac/scanner.d.ts.map +1 -0
  90. package/dist/iac/scanner.js +343 -0
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +28 -0
  94. package/dist/pii/data-flow.d.ts +58 -0
  95. package/dist/pii/data-flow.d.ts.map +1 -0
  96. package/dist/pii/data-flow.js +154 -0
  97. package/dist/pii/detector.d.ts +60 -0
  98. package/dist/pii/detector.d.ts.map +1 -0
  99. package/dist/pii/detector.js +267 -0
  100. package/dist/pii/index.d.ts +4 -0
  101. package/dist/pii/index.d.ts.map +1 -0
  102. package/dist/pii/index.js +19 -0
  103. package/dist/pii/patterns.d.ts +36 -0
  104. package/dist/pii/patterns.d.ts.map +1 -0
  105. package/dist/pii/patterns.js +108 -0
  106. package/dist/policy/index.d.ts +5 -0
  107. package/dist/policy/index.d.ts.map +1 -0
  108. package/dist/policy/index.js +20 -0
  109. package/dist/policy/opa-engine.d.ts +121 -0
  110. package/dist/policy/opa-engine.d.ts.map +1 -0
  111. package/dist/policy/opa-engine.js +423 -0
  112. package/package.json +31 -0
  113. package/src/audit/emitter.ts +383 -0
  114. package/src/audit/events.ts +351 -0
  115. package/src/audit/index.ts +35 -0
  116. package/src/audit/storage.ts +394 -0
  117. package/src/automation/__tests__/compliance-scheduler.test.ts +183 -0
  118. package/src/automation/audit-logger.ts +629 -0
  119. package/src/automation/compliance-scheduler-fixed.ts +0 -0
  120. package/src/automation/compliance-scheduler.ts +516 -0
  121. package/src/automation/dashboard.ts +947 -0
  122. package/src/automation/email-service.ts +230 -0
  123. package/src/automation/evidence-collector.ts +866 -0
  124. package/src/automation/index.ts +8 -0
  125. package/src/automation/pdf-exporter.ts +434 -0
  126. package/src/automation/reporting-engine.ts +462 -0
  127. package/src/container/index.ts +3 -0
  128. package/src/container/kubernetes.ts +379 -0
  129. package/src/container/rules.ts +244 -0
  130. package/src/container/scanner.ts +202 -0
  131. package/src/frameworks/engine.ts +298 -0
  132. package/src/frameworks/gdpr.ts +204 -0
  133. package/src/frameworks/hipaa.ts +209 -0
  134. package/src/frameworks/index.ts +23 -0
  135. package/src/frameworks/iso27001.ts +398 -0
  136. package/src/frameworks/nist.ts +518 -0
  137. package/src/frameworks/pci.ts +226 -0
  138. package/src/frameworks/soc2.ts +281 -0
  139. package/src/iac/drift-detector.ts +197 -0
  140. package/src/iac/index.ts +3 -0
  141. package/src/iac/rules.ts +420 -0
  142. package/src/iac/scanner.ts +445 -0
  143. package/src/index.ts +17 -0
  144. package/src/pii/data-flow.ts +216 -0
  145. package/src/pii/detector.ts +327 -0
  146. package/src/pii/index.ts +3 -0
  147. package/src/pii/patterns.ts +128 -0
  148. package/src/policy/index.ts +5 -0
  149. package/src/policy/opa-engine.ts +504 -0
@@ -0,0 +1,327 @@
1
+ import { prisma } from '@guardrail/database';
2
+ import { readFileSync, readdirSync, statSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { PII_PATTERNS, PII_FIELD_PATTERNS, PII_TEST_VALUES, NON_PII_CONTEXT_INDICATORS } from './patterns';
5
+ import { dataFlowTracker, PIIFinding, DataFlow } from './data-flow';
6
+
7
+ export interface PIIDetectionResult {
8
+ projectId: string;
9
+ summary: {
10
+ totalFindings: number;
11
+ byCategory: Record<string, number>;
12
+ riskLevel: 'high' | 'medium' | 'low';
13
+ };
14
+ findings: PIIFinding[];
15
+ dataFlows: DataFlow[];
16
+ recommendations: string[];
17
+ }
18
+
19
+ export class PIIDetector {
20
+ /**
21
+ * Detect PII in entire project
22
+ */
23
+ async detectPII(projectPath: string, projectId: string): Promise<PIIDetectionResult> {
24
+ const allFindings: PIIFinding[] = [];
25
+
26
+ // Find all source files
27
+ const sourceFiles = this.findSourceFiles(projectPath);
28
+
29
+ // Scan each file
30
+ for (const filePath of sourceFiles) {
31
+ try {
32
+ const content = readFileSync(filePath, 'utf-8');
33
+ const findings = this.scanContent(content, filePath);
34
+ allFindings.push(...findings);
35
+
36
+ // Also scan for PII field names
37
+ const fieldFindings = this.scanFieldNames(content, filePath);
38
+ allFindings.push(...fieldFindings);
39
+ } catch (error) {
40
+ console.error(`Error scanning file ${filePath}:`, error);
41
+ }
42
+ }
43
+
44
+ // Track data flows
45
+ const dataFlows = await this.trackPIIDataFlows(projectPath, allFindings);
46
+
47
+ // Generate recommendations
48
+ const recommendations = this.generateRecommendations(allFindings, dataFlows);
49
+
50
+ // Calculate summary
51
+ const byCategory: Record<string, number> = {};
52
+ for (const finding of allFindings) {
53
+ byCategory[finding.category] = (byCategory[finding.category] || 0) + 1;
54
+ }
55
+
56
+ const highSeverityCount = allFindings.filter(f => f.severity === 'high').length;
57
+ const riskLevel: 'high' | 'medium' | 'low' =
58
+ highSeverityCount > 5 ? 'high' :
59
+ highSeverityCount > 0 ? 'medium' : 'low';
60
+
61
+ const result: PIIDetectionResult = {
62
+ projectId,
63
+ summary: {
64
+ totalFindings: allFindings.length,
65
+ byCategory,
66
+ riskLevel
67
+ },
68
+ findings: allFindings,
69
+ dataFlows,
70
+ recommendations
71
+ };
72
+
73
+ // Save to database
74
+ try {
75
+ await prisma.pIIDetection.create({
76
+ data: {
77
+ projectId
78
+ } as any
79
+ });
80
+ } catch (error) {
81
+ // Table may not exist - continue
82
+ }
83
+
84
+ return result;
85
+ }
86
+
87
+ /**
88
+ * Scan file content for PII patterns
89
+ */
90
+ private scanContent(content: string, filePath: string): PIIFinding[] {
91
+ const findings: PIIFinding[] = [];
92
+ const lines = content.split('\n');
93
+
94
+ for (const pattern of PII_PATTERNS) {
95
+ let match;
96
+ while ((match = pattern.pattern.exec(content)) !== null) {
97
+ const value = match[0];
98
+
99
+ // Skip test values
100
+ if (this.isTestValue(value)) {
101
+ continue;
102
+ }
103
+
104
+ // Get line and column
105
+ const position = this.getLineAndColumn(content, match.index);
106
+
107
+ // Get context
108
+ const context = this.getContext(lines, position.line);
109
+
110
+ // Skip if in non-PII context
111
+ if (this.isNonPIIContext(context)) {
112
+ continue;
113
+ }
114
+
115
+ findings.push({
116
+ category: pattern.category,
117
+ value: this.maskValue(value, pattern.category),
118
+ location: {
119
+ file: filePath,
120
+ line: position.line + 1,
121
+ column: position.column
122
+ },
123
+ context,
124
+ severity: pattern.severity
125
+ });
126
+ }
127
+
128
+ // Reset lastIndex for global regex
129
+ pattern.pattern.lastIndex = 0;
130
+ }
131
+
132
+ return findings;
133
+ }
134
+
135
+ /**
136
+ * Scan AST for PII field names
137
+ */
138
+ private scanFieldNames(content: string, filePath: string): PIIFinding[] {
139
+ const findings: PIIFinding[] = [];
140
+ const lines = content.split('\n');
141
+
142
+ // Simple pattern matching for field names
143
+ // In production, would use proper AST parsing
144
+
145
+ for (let i = 0; i < lines.length; i++) {
146
+ const line = lines[i];
147
+ if (!line) continue;
148
+
149
+ for (const fieldPattern of PII_FIELD_PATTERNS) {
150
+ const matches = line.matchAll(fieldPattern.pattern);
151
+
152
+ for (const match of matches) {
153
+ const fieldName = match[0];
154
+ const context = this.getContext(lines, i);
155
+
156
+ // Skip if in comments or strings
157
+ if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
158
+ continue;
159
+ }
160
+
161
+ findings.push({
162
+ category: fieldPattern.category,
163
+ value: fieldName,
164
+ location: {
165
+ file: filePath,
166
+ line: i + 1,
167
+ column: match.index || 0
168
+ },
169
+ context,
170
+ severity: fieldPattern.severity
171
+ });
172
+ }
173
+ }
174
+ }
175
+
176
+ return findings;
177
+ }
178
+
179
+ /**
180
+ * Track data flows for PII
181
+ */
182
+ private async trackPIIDataFlows(_projectPath: string, findings: PIIFinding[]): Promise<DataFlow[]> {
183
+ // Use data flow tracker to analyze flows
184
+ return dataFlowTracker.analyzeDataFlows(findings);
185
+ }
186
+
187
+ /**
188
+ * Generate recommendations based on findings
189
+ */
190
+ private generateRecommendations(findings: PIIFinding[], dataFlows: DataFlow[]): string[] {
191
+ const recommendations: string[] = [];
192
+
193
+ // Count findings by category
194
+ const bySeverity = {
195
+ high: findings.filter(f => f.severity === 'high').length,
196
+ medium: findings.filter(f => f.severity === 'medium').length,
197
+ low: findings.filter(f => f.severity === 'low').length
198
+ };
199
+
200
+ if (bySeverity.high > 0) {
201
+ recommendations.push(`🔴 Found ${bySeverity.high} high-severity PII findings - immediate action required`);
202
+ recommendations.push('Implement encryption for sensitive data fields');
203
+ recommendations.push('Review and minimize PII storage');
204
+ }
205
+
206
+ // Check for unencrypted storage
207
+ const unencryptedStorage = dataFlows.some(flow =>
208
+ flow.storage.some(s => !s.encrypted)
209
+ );
210
+
211
+ if (unencryptedStorage) {
212
+ recommendations.push('⚠️ PII detected in unencrypted storage - enable encryption at rest');
213
+ }
214
+
215
+ // Check for external transfers
216
+ const hasExternalTransfers = dataFlows.some(flow => flow.externalTransfers.length > 0);
217
+
218
+ if (hasExternalTransfers) {
219
+ recommendations.push('📡 PII transferred to external systems - ensure proper data processing agreements');
220
+ }
221
+
222
+ // General recommendations
223
+ if (findings.length > 0) {
224
+ recommendations.push('Implement data retention policies');
225
+ recommendations.push('Add user consent mechanisms for PII collection');
226
+ recommendations.push('Consider pseudonymization or anonymization techniques');
227
+ recommendations.push('Implement access controls for PII data');
228
+ recommendations.push('Add audit logging for PII access');
229
+ }
230
+
231
+ return recommendations;
232
+ }
233
+
234
+ /**
235
+ * Find source files in project
236
+ */
237
+ private findSourceFiles(dir: string): string[] {
238
+ const files: string[] = [];
239
+ const extensions = ['.ts', '.js', '.tsx', '.jsx', '.py', '.java', '.go', '.rb', '.php'];
240
+
241
+ try {
242
+ const entries = readdirSync(dir);
243
+
244
+ for (const entry of entries) {
245
+ const fullPath = join(dir, entry);
246
+ const stat = statSync(fullPath);
247
+
248
+ if (stat.isDirectory() && !entry.startsWith('.') && entry !== 'node_modules' && entry !== 'dist') {
249
+ files.push(...this.findSourceFiles(fullPath));
250
+ } else if (stat.isFile()) {
251
+ if (extensions.some(ext => entry.endsWith(ext))) {
252
+ files.push(fullPath);
253
+ }
254
+ }
255
+ }
256
+ } catch (error) {
257
+ // Ignore permission errors
258
+ }
259
+
260
+ return files;
261
+ }
262
+
263
+ /**
264
+ * Check if value is a test value
265
+ */
266
+ private isTestValue(value: string): boolean {
267
+ return PII_TEST_VALUES.some(test => value.includes(test));
268
+ }
269
+
270
+ /**
271
+ * Check if context indicates non-PII usage
272
+ */
273
+ private isNonPIIContext(context: string): boolean {
274
+ const lowerContext = context.toLowerCase();
275
+ return NON_PII_CONTEXT_INDICATORS.some(indicator =>
276
+ lowerContext.includes(indicator)
277
+ );
278
+ }
279
+
280
+ /**
281
+ * Get line and column from position
282
+ */
283
+ private getLineAndColumn(content: string, position: number): { line: number; column: number } {
284
+ const lines = content.substring(0, position).split('\n');
285
+ const lastLine = lines[lines.length - 1] || '';
286
+ return {
287
+ line: lines.length - 1,
288
+ column: lastLine.length
289
+ };
290
+ }
291
+
292
+ /**
293
+ * Get context around a line
294
+ */
295
+ private getContext(lines: string[], lineIndex: number, contextSize: number = 2): string {
296
+ const start = Math.max(0, lineIndex - contextSize);
297
+ const end = Math.min(lines.length, lineIndex + contextSize + 1);
298
+ return lines.slice(start, end).join('\n');
299
+ }
300
+
301
+ /**
302
+ * Mask sensitive value
303
+ */
304
+ private maskValue(value: string, category: string): string {
305
+ if (category === 'email') {
306
+ const parts = value.split('@');
307
+ const local = parts[0];
308
+ const domain = parts[1];
309
+ if (local && domain) {
310
+ return `${local.charAt(0)}***@${domain}`;
311
+ }
312
+ return '***@***.com';
313
+ }
314
+
315
+ if (category === 'phone') {
316
+ return `***-***-${value.slice(-4)}`;
317
+ }
318
+
319
+ if (category === 'ssn' || category === 'credit-card') {
320
+ return `***-**-${value.slice(-4)}`;
321
+ }
322
+
323
+ return `${value.slice(0, 3)}***`;
324
+ }
325
+ }
326
+
327
+ export const piiDetector = new PIIDetector();
@@ -0,0 +1,3 @@
1
+ export * from './detector';
2
+ export * from './patterns';
3
+ export * from './data-flow';
@@ -0,0 +1,128 @@
1
+ export interface PIIPattern {
2
+ category: 'email' | 'phone' | 'ssn' | 'credit-card' | 'ip-address' | 'name-field' | 'address' | 'dob' | 'health' | 'financial';
3
+ description: string;
4
+ pattern: RegExp;
5
+ severity: 'high' | 'medium' | 'low';
6
+ examples: string[];
7
+ }
8
+
9
+ /**
10
+ * PII Detection Patterns
11
+ */
12
+ export const PII_PATTERNS: PIIPattern[] = [
13
+ // Email Addresses
14
+ {
15
+ category: 'email',
16
+ description: 'Email address',
17
+ pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
18
+ severity: 'medium',
19
+ examples: ['user@example.com', 'john.doe@company.co.uk']
20
+ },
21
+
22
+ // Phone Numbers
23
+ {
24
+ category: 'phone',
25
+ description: 'US Phone number',
26
+ pattern: /\b(\+1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}\b/g,
27
+ severity: 'medium',
28
+ examples: ['+1-555-123-4567', '(555) 123-4567', '555-123-4567']
29
+ },
30
+
31
+ // Social Security Numbers
32
+ {
33
+ category: 'ssn',
34
+ description: 'US Social Security Number',
35
+ pattern: /\b\d{3}-\d{2}-\d{4}\b/g,
36
+ severity: 'high',
37
+ examples: ['123-45-6789']
38
+ },
39
+
40
+ // Credit Card Numbers (Luhn algorithm pattern)
41
+ {
42
+ category: 'credit-card',
43
+ description: 'Credit card number',
44
+ pattern: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
45
+ severity: 'high',
46
+ examples: ['4532-1234-5678-9010', '5425 2334 3010 9903']
47
+ },
48
+
49
+ // IP Addresses
50
+ {
51
+ category: 'ip-address',
52
+ description: 'IPv4 address',
53
+ pattern: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
54
+ severity: 'low',
55
+ examples: ['192.168.1.1', '10.0.0.1']
56
+ }
57
+ ];
58
+
59
+ /**
60
+ * Field name patterns that suggest PII
61
+ */
62
+ export const PII_FIELD_PATTERNS = [
63
+ // Name fields
64
+ { pattern: /\b(first_?name|last_?name|full_?name|given_?name|family_?name)\b/i, category: 'name-field', severity: 'medium' as const },
65
+ { pattern: /\b(name)\b/i, category: 'name-field', severity: 'low' as const },
66
+
67
+ // Email fields
68
+ { pattern: /\b(email|e_?mail|email_?address)\b/i, category: 'email', severity: 'medium' as const },
69
+
70
+ // Phone fields
71
+ { pattern: /\b(phone|telephone|mobile|cell_?phone)\b/i, category: 'phone', severity: 'medium' as const },
72
+
73
+ // Address fields
74
+ { pattern: /\b(address|street|city|state|zip|postal_?code|country)\b/i, category: 'address', severity: 'medium' as const },
75
+ { pattern: /\b(billing_?address|shipping_?address|home_?address)\b/i, category: 'address', severity: 'high' as const },
76
+
77
+ // Date of Birth
78
+ { pattern: /\b(dob|date_?of_?birth|birth_?date|birthday)\b/i, category: 'dob', severity: 'high' as const },
79
+
80
+ // Social Security
81
+ { pattern: /\b(ssn|social_?security|national_?id)\b/i, category: 'ssn', severity: 'high' as const },
82
+
83
+ // Financial
84
+ { pattern: /\b(credit_?card|card_?number|cvv|cvc|account_?number|routing_?number|iban)\b/i, category: 'financial', severity: 'high' as const },
85
+ { pattern: /\b(salary|income|tax_?id|ein)\b/i, category: 'financial', severity: 'high' as const },
86
+
87
+ // Health
88
+ { pattern: /\b(medical_?record|patient_?id|diagnosis|prescription|health_?insurance)\b/i, category: 'health', severity: 'high' as const },
89
+ { pattern: /\b(blood_?type|allergies|medication)\b/i, category: 'health', severity: 'high' as const },
90
+
91
+ // Authentication
92
+ { pattern: /\b(password|passwd|pwd|secret|token|api_?key)\b/i, category: 'financial', severity: 'high' as const }
93
+ ];
94
+
95
+ /**
96
+ * Test values that should be excluded
97
+ */
98
+ export const PII_TEST_VALUES = [
99
+ 'test@example.com',
100
+ 'user@example.com',
101
+ 'admin@example.com',
102
+ 'noreply@example.com',
103
+ '555-0100', // Reserved for testing
104
+ '555-0199',
105
+ '000-00-0000', // Invalid SSN
106
+ '123-45-6789', // Well-known fake SSN
107
+ '127.0.0.1',
108
+ 'localhost',
109
+ '0.0.0.0',
110
+ 'example.com',
111
+ 'test.com'
112
+ ];
113
+
114
+ /**
115
+ * Context indicators that suggest non-PII usage
116
+ */
117
+ export const NON_PII_CONTEXT_INDICATORS = [
118
+ 'example',
119
+ 'test',
120
+ 'demo',
121
+ 'sample',
122
+ 'placeholder',
123
+ 'fake',
124
+ 'mock',
125
+ 'dummy',
126
+ 'template',
127
+ 'default'
128
+ ];
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Policy as Code Module
3
+ */
4
+
5
+ export * from './opa-engine';