@apart-tech/intelligence-core 1.0.7 → 1.1.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/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/crypto.test.d.ts +2 -0
- package/dist/lib/__tests__/crypto.test.d.ts.map +1 -0
- package/dist/lib/__tests__/crypto.test.js +63 -0
- package/dist/lib/__tests__/crypto.test.js.map +1 -0
- package/dist/lib/crypto.d.ts +14 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +33 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/services/__tests__/pii-detector-service.test.d.ts +2 -0
- package/dist/services/__tests__/pii-detector-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/pii-detector-service.test.js +75 -0
- package/dist/services/__tests__/pii-detector-service.test.js.map +1 -0
- package/dist/services/__tests__/pii-encryption-service.test.d.ts +2 -0
- package/dist/services/__tests__/pii-encryption-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/pii-encryption-service.test.js +151 -0
- package/dist/services/__tests__/pii-encryption-service.test.js.map +1 -0
- package/dist/services/node-service.d.ts +10 -1
- package/dist/services/node-service.d.ts.map +1 -1
- package/dist/services/node-service.js +57 -22
- package/dist/services/node-service.js.map +1 -1
- package/dist/services/org-embedding-config-service.d.ts.map +1 -1
- package/dist/services/org-embedding-config-service.js +4 -21
- package/dist/services/org-embedding-config-service.js.map +1 -1
- package/dist/services/org-pii-config-service.d.ts +30 -0
- package/dist/services/org-pii-config-service.d.ts.map +1 -0
- package/dist/services/org-pii-config-service.js +97 -0
- package/dist/services/org-pii-config-service.js.map +1 -0
- package/dist/services/pii-detector-service.d.ts +24 -0
- package/dist/services/pii-detector-service.d.ts.map +1 -0
- package/dist/services/pii-detector-service.js +89 -0
- package/dist/services/pii-detector-service.js.map +1 -0
- package/dist/services/pii-encryption-service.d.ts +55 -0
- package/dist/services/pii-encryption-service.d.ts.map +1 -0
- package/dist/services/pii-encryption-service.js +216 -0
- package/dist/services/pii-encryption-service.js.map +1 -0
- package/package.json +2 -1
- package/prisma/schema.prisma +17 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { encryptAesGcm, decryptAesGcm } from "../lib/crypto.js";
|
|
2
|
+
const PII_TOKEN_REGEX = /\[PII:(\w+):([A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+)\]/g;
|
|
3
|
+
const MAX_METADATA_DEPTH = 5;
|
|
4
|
+
export class PiiEncryptionService {
|
|
5
|
+
detector;
|
|
6
|
+
constructor(detector) {
|
|
7
|
+
this.detector = detector;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Process a text string: detect PII and optionally encrypt matches.
|
|
11
|
+
*/
|
|
12
|
+
processText(text, options) {
|
|
13
|
+
const emptyReport = {
|
|
14
|
+
matchCount: 0,
|
|
15
|
+
encryptedCount: 0,
|
|
16
|
+
bypassedCount: 0,
|
|
17
|
+
types: [],
|
|
18
|
+
mode: options.mode,
|
|
19
|
+
bypassed: options.bypass ?? false,
|
|
20
|
+
};
|
|
21
|
+
if (options.mode === "disabled") {
|
|
22
|
+
return { text, report: emptyReport };
|
|
23
|
+
}
|
|
24
|
+
const detection = this.detector.detect(text);
|
|
25
|
+
if (!detection.hasPii) {
|
|
26
|
+
return { text, report: emptyReport };
|
|
27
|
+
}
|
|
28
|
+
const types = [...new Set(detection.matches.map((m) => m.type))];
|
|
29
|
+
const allowedTypes = new Set(options.allowedPiiTypes ?? []);
|
|
30
|
+
// Filter out matches whose type is explicitly allowed
|
|
31
|
+
const matchesToProcess = detection.matches.filter((m) => !allowedTypes.has(m.type));
|
|
32
|
+
const skippedCount = detection.matches.length - matchesToProcess.length;
|
|
33
|
+
if (options.mode === "detect-warn" || options.bypass || !options.orgKey) {
|
|
34
|
+
return {
|
|
35
|
+
text,
|
|
36
|
+
report: {
|
|
37
|
+
matchCount: detection.matches.length,
|
|
38
|
+
encryptedCount: 0,
|
|
39
|
+
bypassedCount: detection.matches.length,
|
|
40
|
+
types,
|
|
41
|
+
mode: options.mode,
|
|
42
|
+
bypassed: options.bypass ?? (options.mode === "detect-warn"),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Mode is "encrypt" — replace PII matches with encrypted tokens
|
|
47
|
+
// Process matches in reverse order to preserve string offsets
|
|
48
|
+
let result = text;
|
|
49
|
+
let encryptedCount = 0;
|
|
50
|
+
const reversedMatches = [...matchesToProcess].reverse();
|
|
51
|
+
for (const match of reversedMatches) {
|
|
52
|
+
const encrypted = encryptAesGcm(match.value, options.orgKey);
|
|
53
|
+
const token = `[PII:${match.type}:${encrypted}]`;
|
|
54
|
+
result = result.slice(0, match.start) + token + result.slice(match.end);
|
|
55
|
+
encryptedCount++;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
text: result,
|
|
59
|
+
report: {
|
|
60
|
+
matchCount: detection.matches.length,
|
|
61
|
+
encryptedCount,
|
|
62
|
+
bypassedCount: skippedCount,
|
|
63
|
+
types,
|
|
64
|
+
mode: options.mode,
|
|
65
|
+
bypassed: false,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Process node fields (title, content, metadata) for PII.
|
|
71
|
+
*/
|
|
72
|
+
processNodeFields(input, options) {
|
|
73
|
+
if (options.mode === "disabled") {
|
|
74
|
+
return {
|
|
75
|
+
...input,
|
|
76
|
+
report: {
|
|
77
|
+
matchCount: 0,
|
|
78
|
+
encryptedCount: 0,
|
|
79
|
+
bypassedCount: 0,
|
|
80
|
+
types: [],
|
|
81
|
+
mode: "disabled",
|
|
82
|
+
bypassed: false,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const titleResult = this.processText(input.title, options);
|
|
87
|
+
const contentResult = this.processText(input.content, options);
|
|
88
|
+
let processedMetadata = input.metadata;
|
|
89
|
+
let metadataMatchCount = 0;
|
|
90
|
+
let metadataEncryptedCount = 0;
|
|
91
|
+
const metadataTypes = [];
|
|
92
|
+
if (input.metadata && options.mode === "encrypt" && !options.bypass && options.orgKey) {
|
|
93
|
+
const { result, matchCount, encryptedCount, types } = this.processMetadata(input.metadata, options, 0);
|
|
94
|
+
processedMetadata = result;
|
|
95
|
+
metadataMatchCount = matchCount;
|
|
96
|
+
metadataEncryptedCount = encryptedCount;
|
|
97
|
+
metadataTypes.push(...types);
|
|
98
|
+
}
|
|
99
|
+
const allTypes = [
|
|
100
|
+
...new Set([
|
|
101
|
+
...titleResult.report.types,
|
|
102
|
+
...contentResult.report.types,
|
|
103
|
+
...metadataTypes,
|
|
104
|
+
]),
|
|
105
|
+
];
|
|
106
|
+
return {
|
|
107
|
+
title: titleResult.text,
|
|
108
|
+
content: contentResult.text,
|
|
109
|
+
metadata: processedMetadata,
|
|
110
|
+
report: {
|
|
111
|
+
matchCount: titleResult.report.matchCount +
|
|
112
|
+
contentResult.report.matchCount +
|
|
113
|
+
metadataMatchCount,
|
|
114
|
+
encryptedCount: titleResult.report.encryptedCount +
|
|
115
|
+
contentResult.report.encryptedCount +
|
|
116
|
+
metadataEncryptedCount,
|
|
117
|
+
bypassedCount: titleResult.report.bypassedCount +
|
|
118
|
+
contentResult.report.bypassedCount,
|
|
119
|
+
types: allTypes,
|
|
120
|
+
mode: options.mode,
|
|
121
|
+
bypassed: options.bypass ?? false,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Decrypt all PII tokens in a text string.
|
|
127
|
+
*/
|
|
128
|
+
decryptText(text, orgKey) {
|
|
129
|
+
return text.replace(PII_TOKEN_REGEX, (_fullMatch, _type, encrypted) => {
|
|
130
|
+
try {
|
|
131
|
+
return decryptAesGcm(encrypted, orgKey);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// If decryption fails (wrong key, corrupted), leave token as-is
|
|
135
|
+
return _fullMatch;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Decrypt PII tokens in node fields.
|
|
141
|
+
*/
|
|
142
|
+
decryptNodeFields(node, orgKey) {
|
|
143
|
+
return {
|
|
144
|
+
...node,
|
|
145
|
+
title: this.decryptText(node.title, orgKey),
|
|
146
|
+
content: this.decryptText(node.content, orgKey),
|
|
147
|
+
metadata: this.decryptMetadataValues(node.metadata, orgKey, 0),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
processMetadata(value, options, depth) {
|
|
151
|
+
if (depth > MAX_METADATA_DEPTH) {
|
|
152
|
+
return { result: value, matchCount: 0, encryptedCount: 0, types: [] };
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === "string") {
|
|
155
|
+
const processed = this.processText(value, options);
|
|
156
|
+
return {
|
|
157
|
+
result: processed.text,
|
|
158
|
+
matchCount: processed.report.matchCount,
|
|
159
|
+
encryptedCount: processed.report.encryptedCount,
|
|
160
|
+
types: processed.report.types,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (Array.isArray(value)) {
|
|
164
|
+
let totalMatches = 0;
|
|
165
|
+
let totalEncrypted = 0;
|
|
166
|
+
const allTypes = [];
|
|
167
|
+
const result = value.map((item) => {
|
|
168
|
+
const processed = this.processMetadata(item, options, depth + 1);
|
|
169
|
+
totalMatches += processed.matchCount;
|
|
170
|
+
totalEncrypted += processed.encryptedCount;
|
|
171
|
+
allTypes.push(...processed.types);
|
|
172
|
+
return processed.result;
|
|
173
|
+
});
|
|
174
|
+
return { result, matchCount: totalMatches, encryptedCount: totalEncrypted, types: allTypes };
|
|
175
|
+
}
|
|
176
|
+
if (value !== null && typeof value === "object") {
|
|
177
|
+
let totalMatches = 0;
|
|
178
|
+
let totalEncrypted = 0;
|
|
179
|
+
const allTypes = [];
|
|
180
|
+
const result = {};
|
|
181
|
+
for (const [key, val] of Object.entries(value)) {
|
|
182
|
+
// Skip internal PII report field
|
|
183
|
+
if (key === "_piiReport") {
|
|
184
|
+
result[key] = val;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const processed = this.processMetadata(val, options, depth + 1);
|
|
188
|
+
result[key] = processed.result;
|
|
189
|
+
totalMatches += processed.matchCount;
|
|
190
|
+
totalEncrypted += processed.encryptedCount;
|
|
191
|
+
allTypes.push(...processed.types);
|
|
192
|
+
}
|
|
193
|
+
return { result, matchCount: totalMatches, encryptedCount: totalEncrypted, types: allTypes };
|
|
194
|
+
}
|
|
195
|
+
return { result: value, matchCount: 0, encryptedCount: 0, types: [] };
|
|
196
|
+
}
|
|
197
|
+
decryptMetadataValues(value, orgKey, depth) {
|
|
198
|
+
if (depth > MAX_METADATA_DEPTH)
|
|
199
|
+
return value;
|
|
200
|
+
if (typeof value === "string") {
|
|
201
|
+
return this.decryptText(value, orgKey);
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
return value.map((item) => this.decryptMetadataValues(item, orgKey, depth + 1));
|
|
205
|
+
}
|
|
206
|
+
if (value !== null && typeof value === "object") {
|
|
207
|
+
const result = {};
|
|
208
|
+
for (const [key, val] of Object.entries(value)) {
|
|
209
|
+
result[key] = this.decryptMetadataValues(val, orgKey, depth + 1);
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
return value;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=pii-encryption-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii-encryption-service.js","sourceRoot":"","sources":["../../src/services/pii-encryption-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apart-tech/intelligence-core",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Core library: database, services, and providers for Apart Intelligence",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"@cdssnc/sanitize-pii": "^2.1.2",
|
|
22
23
|
"@prisma/client": "^6.6.0",
|
|
23
24
|
"@prisma/extension-accelerate": "^3.0.1",
|
|
24
25
|
"prisma": "^6.6.0",
|
package/prisma/schema.prisma
CHANGED
|
@@ -20,6 +20,7 @@ model Organization {
|
|
|
20
20
|
apiKeys ApiKey[]
|
|
21
21
|
workspaces Workspace[]
|
|
22
22
|
embeddingConfig OrgEmbeddingConfig?
|
|
23
|
+
piiConfig OrgPiiConfig?
|
|
23
24
|
|
|
24
25
|
@@map("organizations")
|
|
25
26
|
}
|
|
@@ -39,6 +40,21 @@ model OrgEmbeddingConfig {
|
|
|
39
40
|
@@map("org_embedding_config")
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
model OrgPiiConfig {
|
|
44
|
+
id String @id @default(uuid()) @db.Uuid
|
|
45
|
+
organizationId String @unique @map("organization_id") @db.Uuid
|
|
46
|
+
mode String @default("encrypt") @db.VarChar(20)
|
|
47
|
+
piiKeyEncrypted String @map("pii_key_encrypted") @db.Text
|
|
48
|
+
allowedPiiTypes Json @default("[]") @map("allowed_pii_types")
|
|
49
|
+
allowBypass Boolean @default(false) @map("allow_bypass")
|
|
50
|
+
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz
|
|
51
|
+
updatedBy String @default("api") @map("updated_by") @db.VarChar(255)
|
|
52
|
+
|
|
53
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
54
|
+
|
|
55
|
+
@@map("org_pii_config")
|
|
56
|
+
}
|
|
57
|
+
|
|
42
58
|
model Domain {
|
|
43
59
|
id String @id @default(uuid()) @db.Uuid
|
|
44
60
|
name String @db.VarChar(200)
|
|
@@ -75,6 +91,7 @@ model Node {
|
|
|
75
91
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
|
76
92
|
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz
|
|
77
93
|
version Int @default(1)
|
|
94
|
+
hasPii Boolean @default(false) @map("has_pii")
|
|
78
95
|
domainId String? @map("domain_id") @db.Uuid
|
|
79
96
|
organizationId String @map("organization_id") @db.Uuid
|
|
80
97
|
|