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.
- package/dist/audit/emitter.d.ts +97 -0
- package/dist/audit/emitter.d.ts.map +1 -0
- package/dist/audit/emitter.js +197 -0
- package/dist/audit/events.d.ts +304 -0
- package/dist/audit/events.d.ts.map +1 -0
- package/dist/audit/events.js +267 -0
- package/dist/audit/index.d.ts +11 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +51 -0
- package/dist/audit/storage.d.ts +93 -0
- package/dist/audit/storage.d.ts.map +1 -0
- package/dist/audit/storage.js +337 -0
- package/dist/automation/__tests__/compliance-scheduler.test.d.ts +2 -0
- package/dist/automation/__tests__/compliance-scheduler.test.d.ts.map +1 -0
- package/dist/automation/__tests__/compliance-scheduler.test.js +140 -0
- package/dist/automation/audit-logger.d.ts +129 -0
- package/dist/automation/audit-logger.d.ts.map +1 -0
- package/dist/automation/audit-logger.js +473 -0
- package/dist/automation/compliance-scheduler-fixed.d.ts +1 -0
- package/dist/automation/compliance-scheduler-fixed.d.ts.map +1 -0
- package/dist/automation/compliance-scheduler-fixed.js +1 -0
- package/dist/automation/compliance-scheduler.d.ts +83 -0
- package/dist/automation/compliance-scheduler.d.ts.map +1 -0
- package/dist/automation/compliance-scheduler.js +414 -0
- package/dist/automation/dashboard.d.ts +194 -0
- package/dist/automation/dashboard.d.ts.map +1 -0
- package/dist/automation/dashboard.js +768 -0
- package/dist/automation/email-service.d.ts +69 -0
- package/dist/automation/email-service.d.ts.map +1 -0
- package/dist/automation/email-service.js +218 -0
- package/dist/automation/evidence-collector.d.ts +140 -0
- package/dist/automation/evidence-collector.d.ts.map +1 -0
- package/dist/automation/evidence-collector.js +682 -0
- package/dist/automation/index.d.ts +8 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +24 -0
- package/dist/automation/pdf-exporter.d.ts +90 -0
- package/dist/automation/pdf-exporter.d.ts.map +1 -0
- package/dist/automation/pdf-exporter.js +381 -0
- package/dist/automation/reporting-engine.d.ts +116 -0
- package/dist/automation/reporting-engine.d.ts.map +1 -0
- package/dist/automation/reporting-engine.js +329 -0
- package/dist/container/index.d.ts +4 -0
- package/dist/container/index.d.ts.map +1 -0
- package/dist/container/index.js +19 -0
- package/dist/container/kubernetes.d.ts +94 -0
- package/dist/container/kubernetes.d.ts.map +1 -0
- package/dist/container/kubernetes.js +268 -0
- package/dist/container/rules.d.ts +27 -0
- package/dist/container/rules.d.ts.map +1 -0
- package/dist/container/rules.js +216 -0
- package/dist/container/scanner.d.ts +50 -0
- package/dist/container/scanner.d.ts.map +1 -0
- package/dist/container/scanner.js +143 -0
- package/dist/frameworks/engine.d.ts +108 -0
- package/dist/frameworks/engine.d.ts.map +1 -0
- package/dist/frameworks/engine.js +206 -0
- package/dist/frameworks/gdpr.d.ts +6 -0
- package/dist/frameworks/gdpr.d.ts.map +1 -0
- package/dist/frameworks/gdpr.js +198 -0
- package/dist/frameworks/hipaa.d.ts +6 -0
- package/dist/frameworks/hipaa.d.ts.map +1 -0
- package/dist/frameworks/hipaa.js +183 -0
- package/dist/frameworks/index.d.ts +8 -0
- package/dist/frameworks/index.d.ts.map +1 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/iso27001.d.ts +63 -0
- package/dist/frameworks/iso27001.d.ts.map +1 -0
- package/dist/frameworks/iso27001.js +331 -0
- package/dist/frameworks/nist.d.ts +62 -0
- package/dist/frameworks/nist.d.ts.map +1 -0
- package/dist/frameworks/nist.js +424 -0
- package/dist/frameworks/pci.d.ts +6 -0
- package/dist/frameworks/pci.d.ts.map +1 -0
- package/dist/frameworks/pci.js +201 -0
- package/dist/frameworks/soc2.d.ts +7 -0
- package/dist/frameworks/soc2.d.ts.map +1 -0
- package/dist/frameworks/soc2.js +248 -0
- package/dist/iac/drift-detector.d.ts +64 -0
- package/dist/iac/drift-detector.d.ts.map +1 -0
- package/dist/iac/drift-detector.js +134 -0
- package/dist/iac/index.d.ts +4 -0
- package/dist/iac/index.d.ts.map +1 -0
- package/dist/iac/index.js +19 -0
- package/dist/iac/rules.d.ts +17 -0
- package/dist/iac/rules.d.ts.map +1 -0
- package/dist/iac/rules.js +385 -0
- package/dist/iac/scanner.d.ts +104 -0
- package/dist/iac/scanner.d.ts.map +1 -0
- package/dist/iac/scanner.js +343 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/pii/data-flow.d.ts +58 -0
- package/dist/pii/data-flow.d.ts.map +1 -0
- package/dist/pii/data-flow.js +154 -0
- package/dist/pii/detector.d.ts +60 -0
- package/dist/pii/detector.d.ts.map +1 -0
- package/dist/pii/detector.js +267 -0
- package/dist/pii/index.d.ts +4 -0
- package/dist/pii/index.d.ts.map +1 -0
- package/dist/pii/index.js +19 -0
- package/dist/pii/patterns.d.ts +36 -0
- package/dist/pii/patterns.d.ts.map +1 -0
- package/dist/pii/patterns.js +108 -0
- package/dist/policy/index.d.ts +5 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +20 -0
- package/dist/policy/opa-engine.d.ts +121 -0
- package/dist/policy/opa-engine.d.ts.map +1 -0
- package/dist/policy/opa-engine.js +423 -0
- package/package.json +31 -0
- package/src/audit/emitter.ts +383 -0
- package/src/audit/events.ts +351 -0
- package/src/audit/index.ts +35 -0
- package/src/audit/storage.ts +394 -0
- package/src/automation/__tests__/compliance-scheduler.test.ts +183 -0
- package/src/automation/audit-logger.ts +629 -0
- package/src/automation/compliance-scheduler-fixed.ts +0 -0
- package/src/automation/compliance-scheduler.ts +516 -0
- package/src/automation/dashboard.ts +947 -0
- package/src/automation/email-service.ts +230 -0
- package/src/automation/evidence-collector.ts +866 -0
- package/src/automation/index.ts +8 -0
- package/src/automation/pdf-exporter.ts +434 -0
- package/src/automation/reporting-engine.ts +462 -0
- package/src/container/index.ts +3 -0
- package/src/container/kubernetes.ts +379 -0
- package/src/container/rules.ts +244 -0
- package/src/container/scanner.ts +202 -0
- package/src/frameworks/engine.ts +298 -0
- package/src/frameworks/gdpr.ts +204 -0
- package/src/frameworks/hipaa.ts +209 -0
- package/src/frameworks/index.ts +23 -0
- package/src/frameworks/iso27001.ts +398 -0
- package/src/frameworks/nist.ts +518 -0
- package/src/frameworks/pci.ts +226 -0
- package/src/frameworks/soc2.ts +281 -0
- package/src/iac/drift-detector.ts +197 -0
- package/src/iac/index.ts +3 -0
- package/src/iac/rules.ts +420 -0
- package/src/iac/scanner.ts +445 -0
- package/src/index.ts +17 -0
- package/src/pii/data-flow.ts +216 -0
- package/src/pii/detector.ts +327 -0
- package/src/pii/index.ts +3 -0
- package/src/pii/patterns.ts +128 -0
- package/src/policy/index.ts +5 -0
- package/src/policy/opa-engine.ts +504 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.piiDetector = exports.PIIDetector = void 0;
|
|
4
|
+
const database_1 = require("@guardrail/database");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const patterns_1 = require("./patterns");
|
|
8
|
+
const data_flow_1 = require("./data-flow");
|
|
9
|
+
class PIIDetector {
|
|
10
|
+
/**
|
|
11
|
+
* Detect PII in entire project
|
|
12
|
+
*/
|
|
13
|
+
async detectPII(projectPath, projectId) {
|
|
14
|
+
const allFindings = [];
|
|
15
|
+
// Find all source files
|
|
16
|
+
const sourceFiles = this.findSourceFiles(projectPath);
|
|
17
|
+
// Scan each file
|
|
18
|
+
for (const filePath of sourceFiles) {
|
|
19
|
+
try {
|
|
20
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
21
|
+
const findings = this.scanContent(content, filePath);
|
|
22
|
+
allFindings.push(...findings);
|
|
23
|
+
// Also scan for PII field names
|
|
24
|
+
const fieldFindings = this.scanFieldNames(content, filePath);
|
|
25
|
+
allFindings.push(...fieldFindings);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error(`Error scanning file ${filePath}:`, error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Track data flows
|
|
32
|
+
const dataFlows = await this.trackPIIDataFlows(projectPath, allFindings);
|
|
33
|
+
// Generate recommendations
|
|
34
|
+
const recommendations = this.generateRecommendations(allFindings, dataFlows);
|
|
35
|
+
// Calculate summary
|
|
36
|
+
const byCategory = {};
|
|
37
|
+
for (const finding of allFindings) {
|
|
38
|
+
byCategory[finding.category] = (byCategory[finding.category] || 0) + 1;
|
|
39
|
+
}
|
|
40
|
+
const highSeverityCount = allFindings.filter(f => f.severity === 'high').length;
|
|
41
|
+
const riskLevel = highSeverityCount > 5 ? 'high' :
|
|
42
|
+
highSeverityCount > 0 ? 'medium' : 'low';
|
|
43
|
+
const result = {
|
|
44
|
+
projectId,
|
|
45
|
+
summary: {
|
|
46
|
+
totalFindings: allFindings.length,
|
|
47
|
+
byCategory,
|
|
48
|
+
riskLevel
|
|
49
|
+
},
|
|
50
|
+
findings: allFindings,
|
|
51
|
+
dataFlows,
|
|
52
|
+
recommendations
|
|
53
|
+
};
|
|
54
|
+
// Save to database
|
|
55
|
+
try {
|
|
56
|
+
await database_1.prisma.pIIDetection.create({
|
|
57
|
+
data: {
|
|
58
|
+
projectId
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
// Table may not exist - continue
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Scan file content for PII patterns
|
|
69
|
+
*/
|
|
70
|
+
scanContent(content, filePath) {
|
|
71
|
+
const findings = [];
|
|
72
|
+
const lines = content.split('\n');
|
|
73
|
+
for (const pattern of patterns_1.PII_PATTERNS) {
|
|
74
|
+
let match;
|
|
75
|
+
while ((match = pattern.pattern.exec(content)) !== null) {
|
|
76
|
+
const value = match[0];
|
|
77
|
+
// Skip test values
|
|
78
|
+
if (this.isTestValue(value)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Get line and column
|
|
82
|
+
const position = this.getLineAndColumn(content, match.index);
|
|
83
|
+
// Get context
|
|
84
|
+
const context = this.getContext(lines, position.line);
|
|
85
|
+
// Skip if in non-PII context
|
|
86
|
+
if (this.isNonPIIContext(context)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
findings.push({
|
|
90
|
+
category: pattern.category,
|
|
91
|
+
value: this.maskValue(value, pattern.category),
|
|
92
|
+
location: {
|
|
93
|
+
file: filePath,
|
|
94
|
+
line: position.line + 1,
|
|
95
|
+
column: position.column
|
|
96
|
+
},
|
|
97
|
+
context,
|
|
98
|
+
severity: pattern.severity
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Reset lastIndex for global regex
|
|
102
|
+
pattern.pattern.lastIndex = 0;
|
|
103
|
+
}
|
|
104
|
+
return findings;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Scan AST for PII field names
|
|
108
|
+
*/
|
|
109
|
+
scanFieldNames(content, filePath) {
|
|
110
|
+
const findings = [];
|
|
111
|
+
const lines = content.split('\n');
|
|
112
|
+
// Simple pattern matching for field names
|
|
113
|
+
// In production, would use proper AST parsing
|
|
114
|
+
for (let i = 0; i < lines.length; i++) {
|
|
115
|
+
const line = lines[i];
|
|
116
|
+
if (!line)
|
|
117
|
+
continue;
|
|
118
|
+
for (const fieldPattern of patterns_1.PII_FIELD_PATTERNS) {
|
|
119
|
+
const matches = line.matchAll(fieldPattern.pattern);
|
|
120
|
+
for (const match of matches) {
|
|
121
|
+
const fieldName = match[0];
|
|
122
|
+
const context = this.getContext(lines, i);
|
|
123
|
+
// Skip if in comments or strings
|
|
124
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
findings.push({
|
|
128
|
+
category: fieldPattern.category,
|
|
129
|
+
value: fieldName,
|
|
130
|
+
location: {
|
|
131
|
+
file: filePath,
|
|
132
|
+
line: i + 1,
|
|
133
|
+
column: match.index || 0
|
|
134
|
+
},
|
|
135
|
+
context,
|
|
136
|
+
severity: fieldPattern.severity
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return findings;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Track data flows for PII
|
|
145
|
+
*/
|
|
146
|
+
async trackPIIDataFlows(_projectPath, findings) {
|
|
147
|
+
// Use data flow tracker to analyze flows
|
|
148
|
+
return data_flow_1.dataFlowTracker.analyzeDataFlows(findings);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Generate recommendations based on findings
|
|
152
|
+
*/
|
|
153
|
+
generateRecommendations(findings, dataFlows) {
|
|
154
|
+
const recommendations = [];
|
|
155
|
+
// Count findings by category
|
|
156
|
+
const bySeverity = {
|
|
157
|
+
high: findings.filter(f => f.severity === 'high').length,
|
|
158
|
+
medium: findings.filter(f => f.severity === 'medium').length,
|
|
159
|
+
low: findings.filter(f => f.severity === 'low').length
|
|
160
|
+
};
|
|
161
|
+
if (bySeverity.high > 0) {
|
|
162
|
+
recommendations.push(`🔴 Found ${bySeverity.high} high-severity PII findings - immediate action required`);
|
|
163
|
+
recommendations.push('Implement encryption for sensitive data fields');
|
|
164
|
+
recommendations.push('Review and minimize PII storage');
|
|
165
|
+
}
|
|
166
|
+
// Check for unencrypted storage
|
|
167
|
+
const unencryptedStorage = dataFlows.some(flow => flow.storage.some(s => !s.encrypted));
|
|
168
|
+
if (unencryptedStorage) {
|
|
169
|
+
recommendations.push('⚠️ PII detected in unencrypted storage - enable encryption at rest');
|
|
170
|
+
}
|
|
171
|
+
// Check for external transfers
|
|
172
|
+
const hasExternalTransfers = dataFlows.some(flow => flow.externalTransfers.length > 0);
|
|
173
|
+
if (hasExternalTransfers) {
|
|
174
|
+
recommendations.push('📡 PII transferred to external systems - ensure proper data processing agreements');
|
|
175
|
+
}
|
|
176
|
+
// General recommendations
|
|
177
|
+
if (findings.length > 0) {
|
|
178
|
+
recommendations.push('Implement data retention policies');
|
|
179
|
+
recommendations.push('Add user consent mechanisms for PII collection');
|
|
180
|
+
recommendations.push('Consider pseudonymization or anonymization techniques');
|
|
181
|
+
recommendations.push('Implement access controls for PII data');
|
|
182
|
+
recommendations.push('Add audit logging for PII access');
|
|
183
|
+
}
|
|
184
|
+
return recommendations;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Find source files in project
|
|
188
|
+
*/
|
|
189
|
+
findSourceFiles(dir) {
|
|
190
|
+
const files = [];
|
|
191
|
+
const extensions = ['.ts', '.js', '.tsx', '.jsx', '.py', '.java', '.go', '.rb', '.php'];
|
|
192
|
+
try {
|
|
193
|
+
const entries = (0, fs_1.readdirSync)(dir);
|
|
194
|
+
for (const entry of entries) {
|
|
195
|
+
const fullPath = (0, path_1.join)(dir, entry);
|
|
196
|
+
const stat = (0, fs_1.statSync)(fullPath);
|
|
197
|
+
if (stat.isDirectory() && !entry.startsWith('.') && entry !== 'node_modules' && entry !== 'dist') {
|
|
198
|
+
files.push(...this.findSourceFiles(fullPath));
|
|
199
|
+
}
|
|
200
|
+
else if (stat.isFile()) {
|
|
201
|
+
if (extensions.some(ext => entry.endsWith(ext))) {
|
|
202
|
+
files.push(fullPath);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
// Ignore permission errors
|
|
209
|
+
}
|
|
210
|
+
return files;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if value is a test value
|
|
214
|
+
*/
|
|
215
|
+
isTestValue(value) {
|
|
216
|
+
return patterns_1.PII_TEST_VALUES.some(test => value.includes(test));
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Check if context indicates non-PII usage
|
|
220
|
+
*/
|
|
221
|
+
isNonPIIContext(context) {
|
|
222
|
+
const lowerContext = context.toLowerCase();
|
|
223
|
+
return patterns_1.NON_PII_CONTEXT_INDICATORS.some(indicator => lowerContext.includes(indicator));
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get line and column from position
|
|
227
|
+
*/
|
|
228
|
+
getLineAndColumn(content, position) {
|
|
229
|
+
const lines = content.substring(0, position).split('\n');
|
|
230
|
+
const lastLine = lines[lines.length - 1] || '';
|
|
231
|
+
return {
|
|
232
|
+
line: lines.length - 1,
|
|
233
|
+
column: lastLine.length
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get context around a line
|
|
238
|
+
*/
|
|
239
|
+
getContext(lines, lineIndex, contextSize = 2) {
|
|
240
|
+
const start = Math.max(0, lineIndex - contextSize);
|
|
241
|
+
const end = Math.min(lines.length, lineIndex + contextSize + 1);
|
|
242
|
+
return lines.slice(start, end).join('\n');
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Mask sensitive value
|
|
246
|
+
*/
|
|
247
|
+
maskValue(value, category) {
|
|
248
|
+
if (category === 'email') {
|
|
249
|
+
const parts = value.split('@');
|
|
250
|
+
const local = parts[0];
|
|
251
|
+
const domain = parts[1];
|
|
252
|
+
if (local && domain) {
|
|
253
|
+
return `${local.charAt(0)}***@${domain}`;
|
|
254
|
+
}
|
|
255
|
+
return '***@***.com';
|
|
256
|
+
}
|
|
257
|
+
if (category === 'phone') {
|
|
258
|
+
return `***-***-${value.slice(-4)}`;
|
|
259
|
+
}
|
|
260
|
+
if (category === 'ssn' || category === 'credit-card') {
|
|
261
|
+
return `***-**-${value.slice(-4)}`;
|
|
262
|
+
}
|
|
263
|
+
return `${value.slice(0, 3)}***`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
exports.PIIDetector = PIIDetector;
|
|
267
|
+
exports.piiDetector = new PIIDetector();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pii/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./detector"), exports);
|
|
18
|
+
__exportStar(require("./patterns"), exports);
|
|
19
|
+
__exportStar(require("./data-flow"), exports);
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
* PII Detection Patterns
|
|
10
|
+
*/
|
|
11
|
+
export declare const PII_PATTERNS: PIIPattern[];
|
|
12
|
+
/**
|
|
13
|
+
* Field name patterns that suggest PII
|
|
14
|
+
*/
|
|
15
|
+
export declare const PII_FIELD_PATTERNS: ({
|
|
16
|
+
pattern: RegExp;
|
|
17
|
+
category: string;
|
|
18
|
+
severity: "medium";
|
|
19
|
+
} | {
|
|
20
|
+
pattern: RegExp;
|
|
21
|
+
category: string;
|
|
22
|
+
severity: "low";
|
|
23
|
+
} | {
|
|
24
|
+
pattern: RegExp;
|
|
25
|
+
category: string;
|
|
26
|
+
severity: "high";
|
|
27
|
+
})[];
|
|
28
|
+
/**
|
|
29
|
+
* Test values that should be excluded
|
|
30
|
+
*/
|
|
31
|
+
export declare const PII_TEST_VALUES: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Context indicators that suggest non-PII usage
|
|
34
|
+
*/
|
|
35
|
+
export declare const NON_PII_CONTEXT_INDICATORS: string[];
|
|
36
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/pii/patterns.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC/H,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,UAAU,EA6CpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;IA+B9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,UAc3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,UAWtC,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NON_PII_CONTEXT_INDICATORS = exports.PII_TEST_VALUES = exports.PII_FIELD_PATTERNS = exports.PII_PATTERNS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* PII Detection Patterns
|
|
6
|
+
*/
|
|
7
|
+
exports.PII_PATTERNS = [
|
|
8
|
+
// Email Addresses
|
|
9
|
+
{
|
|
10
|
+
category: 'email',
|
|
11
|
+
description: 'Email address',
|
|
12
|
+
pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
13
|
+
severity: 'medium',
|
|
14
|
+
examples: ['user@example.com', 'john.doe@company.co.uk']
|
|
15
|
+
},
|
|
16
|
+
// Phone Numbers
|
|
17
|
+
{
|
|
18
|
+
category: 'phone',
|
|
19
|
+
description: 'US Phone number',
|
|
20
|
+
pattern: /\b(\+1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}\b/g,
|
|
21
|
+
severity: 'medium',
|
|
22
|
+
examples: ['+1-555-123-4567', '(555) 123-4567', '555-123-4567']
|
|
23
|
+
},
|
|
24
|
+
// Social Security Numbers
|
|
25
|
+
{
|
|
26
|
+
category: 'ssn',
|
|
27
|
+
description: 'US Social Security Number',
|
|
28
|
+
pattern: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
29
|
+
severity: 'high',
|
|
30
|
+
examples: ['123-45-6789']
|
|
31
|
+
},
|
|
32
|
+
// Credit Card Numbers (Luhn algorithm pattern)
|
|
33
|
+
{
|
|
34
|
+
category: 'credit-card',
|
|
35
|
+
description: 'Credit card number',
|
|
36
|
+
pattern: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
|
|
37
|
+
severity: 'high',
|
|
38
|
+
examples: ['4532-1234-5678-9010', '5425 2334 3010 9903']
|
|
39
|
+
},
|
|
40
|
+
// IP Addresses
|
|
41
|
+
{
|
|
42
|
+
category: 'ip-address',
|
|
43
|
+
description: 'IPv4 address',
|
|
44
|
+
pattern: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
|
|
45
|
+
severity: 'low',
|
|
46
|
+
examples: ['192.168.1.1', '10.0.0.1']
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Field name patterns that suggest PII
|
|
51
|
+
*/
|
|
52
|
+
exports.PII_FIELD_PATTERNS = [
|
|
53
|
+
// Name fields
|
|
54
|
+
{ pattern: /\b(first_?name|last_?name|full_?name|given_?name|family_?name)\b/i, category: 'name-field', severity: 'medium' },
|
|
55
|
+
{ pattern: /\b(name)\b/i, category: 'name-field', severity: 'low' },
|
|
56
|
+
// Email fields
|
|
57
|
+
{ pattern: /\b(email|e_?mail|email_?address)\b/i, category: 'email', severity: 'medium' },
|
|
58
|
+
// Phone fields
|
|
59
|
+
{ pattern: /\b(phone|telephone|mobile|cell_?phone)\b/i, category: 'phone', severity: 'medium' },
|
|
60
|
+
// Address fields
|
|
61
|
+
{ pattern: /\b(address|street|city|state|zip|postal_?code|country)\b/i, category: 'address', severity: 'medium' },
|
|
62
|
+
{ pattern: /\b(billing_?address|shipping_?address|home_?address)\b/i, category: 'address', severity: 'high' },
|
|
63
|
+
// Date of Birth
|
|
64
|
+
{ pattern: /\b(dob|date_?of_?birth|birth_?date|birthday)\b/i, category: 'dob', severity: 'high' },
|
|
65
|
+
// Social Security
|
|
66
|
+
{ pattern: /\b(ssn|social_?security|national_?id)\b/i, category: 'ssn', severity: 'high' },
|
|
67
|
+
// Financial
|
|
68
|
+
{ pattern: /\b(credit_?card|card_?number|cvv|cvc|account_?number|routing_?number|iban)\b/i, category: 'financial', severity: 'high' },
|
|
69
|
+
{ pattern: /\b(salary|income|tax_?id|ein)\b/i, category: 'financial', severity: 'high' },
|
|
70
|
+
// Health
|
|
71
|
+
{ pattern: /\b(medical_?record|patient_?id|diagnosis|prescription|health_?insurance)\b/i, category: 'health', severity: 'high' },
|
|
72
|
+
{ pattern: /\b(blood_?type|allergies|medication)\b/i, category: 'health', severity: 'high' },
|
|
73
|
+
// Authentication
|
|
74
|
+
{ pattern: /\b(password|passwd|pwd|secret|token|api_?key)\b/i, category: 'financial', severity: 'high' }
|
|
75
|
+
];
|
|
76
|
+
/**
|
|
77
|
+
* Test values that should be excluded
|
|
78
|
+
*/
|
|
79
|
+
exports.PII_TEST_VALUES = [
|
|
80
|
+
'test@example.com',
|
|
81
|
+
'user@example.com',
|
|
82
|
+
'admin@example.com',
|
|
83
|
+
'noreply@example.com',
|
|
84
|
+
'555-0100', // Reserved for testing
|
|
85
|
+
'555-0199',
|
|
86
|
+
'000-00-0000', // Invalid SSN
|
|
87
|
+
'123-45-6789', // Well-known fake SSN
|
|
88
|
+
'127.0.0.1',
|
|
89
|
+
'localhost',
|
|
90
|
+
'0.0.0.0',
|
|
91
|
+
'example.com',
|
|
92
|
+
'test.com'
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* Context indicators that suggest non-PII usage
|
|
96
|
+
*/
|
|
97
|
+
exports.NON_PII_CONTEXT_INDICATORS = [
|
|
98
|
+
'example',
|
|
99
|
+
'test',
|
|
100
|
+
'demo',
|
|
101
|
+
'sample',
|
|
102
|
+
'placeholder',
|
|
103
|
+
'fake',
|
|
104
|
+
'mock',
|
|
105
|
+
'dummy',
|
|
106
|
+
'template',
|
|
107
|
+
'default'
|
|
108
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Policy as Code Module
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./opa-engine"), exports);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy as Code Engine (OPA/Rego Integration)
|
|
3
|
+
*
|
|
4
|
+
* Enables custom security policies using Open Policy Agent and Rego language
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Custom policy definitions
|
|
7
|
+
* - Policy evaluation against code/config
|
|
8
|
+
* - Policy bundles and versioning
|
|
9
|
+
* - Decision logging and auditing
|
|
10
|
+
*/
|
|
11
|
+
export interface Policy {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
version: string;
|
|
16
|
+
rego: string;
|
|
17
|
+
category: 'security' | 'compliance' | 'quality' | 'access' | 'custom';
|
|
18
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
tags: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface PolicyInput {
|
|
23
|
+
type: 'code' | 'config' | 'dependency' | 'request' | 'action';
|
|
24
|
+
data: Record<string, unknown>;
|
|
25
|
+
context?: {
|
|
26
|
+
user?: string;
|
|
27
|
+
project?: string;
|
|
28
|
+
environment?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface PolicyDecision {
|
|
32
|
+
policyId: string;
|
|
33
|
+
allowed: boolean;
|
|
34
|
+
violations: PolicyViolation[];
|
|
35
|
+
warnings: string[];
|
|
36
|
+
metadata: Record<string, unknown>;
|
|
37
|
+
evaluatedAt: string;
|
|
38
|
+
durationMs: number;
|
|
39
|
+
}
|
|
40
|
+
export interface PolicyViolation {
|
|
41
|
+
rule: string;
|
|
42
|
+
message: string;
|
|
43
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
44
|
+
remediation?: string;
|
|
45
|
+
location?: {
|
|
46
|
+
file?: string;
|
|
47
|
+
line?: number;
|
|
48
|
+
column?: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export interface PolicyBundle {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
version: string;
|
|
55
|
+
policies: Policy[];
|
|
56
|
+
createdAt: string;
|
|
57
|
+
updatedAt: string;
|
|
58
|
+
}
|
|
59
|
+
export declare const BUILTIN_POLICIES: Policy[];
|
|
60
|
+
/**
|
|
61
|
+
* Policy Engine for evaluating Rego policies
|
|
62
|
+
*/
|
|
63
|
+
export declare class PolicyEngine {
|
|
64
|
+
private policies;
|
|
65
|
+
private decisionLog;
|
|
66
|
+
constructor();
|
|
67
|
+
/**
|
|
68
|
+
* Register a custom policy
|
|
69
|
+
*/
|
|
70
|
+
registerPolicy(policy: Policy): void;
|
|
71
|
+
/**
|
|
72
|
+
* Remove a policy
|
|
73
|
+
*/
|
|
74
|
+
removePolicy(policyId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Get all registered policies
|
|
77
|
+
*/
|
|
78
|
+
getPolicies(): Policy[];
|
|
79
|
+
/**
|
|
80
|
+
* Get a specific policy
|
|
81
|
+
*/
|
|
82
|
+
getPolicy(policyId: string): Policy | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Evaluate input against all enabled policies
|
|
85
|
+
*/
|
|
86
|
+
evaluate(input: PolicyInput): Promise<PolicyDecision[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Evaluate input against a specific policy
|
|
89
|
+
*/
|
|
90
|
+
evaluatePolicy(policy: Policy, input: PolicyInput): Promise<PolicyDecision>;
|
|
91
|
+
/**
|
|
92
|
+
* Simplified Rego evaluation (placeholder for OPA integration)
|
|
93
|
+
* In production, this would use @open-policy-agent/opa-wasm or call OPA server
|
|
94
|
+
*/
|
|
95
|
+
private evaluateRego;
|
|
96
|
+
/**
|
|
97
|
+
* Get decision log
|
|
98
|
+
*/
|
|
99
|
+
getDecisionLog(): PolicyDecision[];
|
|
100
|
+
/**
|
|
101
|
+
* Clear decision log
|
|
102
|
+
*/
|
|
103
|
+
clearDecisionLog(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Export policies as a bundle
|
|
106
|
+
*/
|
|
107
|
+
exportBundle(name: string): PolicyBundle;
|
|
108
|
+
/**
|
|
109
|
+
* Import policies from a bundle
|
|
110
|
+
*/
|
|
111
|
+
importBundle(bundle: PolicyBundle): void;
|
|
112
|
+
/**
|
|
113
|
+
* Validate Rego syntax (placeholder)
|
|
114
|
+
*/
|
|
115
|
+
validateRego(rego: string): {
|
|
116
|
+
valid: boolean;
|
|
117
|
+
errors: string[];
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export declare const policyEngine: PolicyEngine;
|
|
121
|
+
//# sourceMappingURL=opa-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opa-engine.d.ts","sourceRoot":"","sources":["../../src/policy/opa-engine.ts"],"names":[],"mappings":"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"}
|