@doccloak/core 0.8.0 → 0.10.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/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type EntityType = 'PERSON' | 'EMAIL' | 'PHONE' | 'SSN' | 'CREDIT_CARD' | 'DATE' | 'CURRENCY' | 'IP_ADDRESS' | 'IBAN' | 'ADDRESS' | 'COMPANY' | 'OTHER';
1
+ export type EntityType = 'PERSON' | 'EMAIL' | 'PHONE' | 'SSN' | 'CREDIT_CARD' | 'DATE' | 'CURRENCY' | 'IP_ADDRESS' | 'IBAN' | 'ADDRESS' | 'COMPANY' | 'SECRET' | 'API_KEY' | 'OTHER';
2
2
  export interface DetectedEntity {
3
3
  type: EntityType;
4
4
  value: string;
package/dist/types.js CHANGED
@@ -10,6 +10,8 @@ export const ENTITY_COLORS = {
10
10
  IBAN: '#A16207',
11
11
  ADDRESS: '#DC2626',
12
12
  COMPANY: '#DB2777',
13
+ SECRET: '#E11D48',
14
+ API_KEY: '#059669',
13
15
  OTHER: '#6B7280',
14
16
  };
15
17
  export const ENTITY_LABELS = {
@@ -24,5 +26,7 @@ export const ENTITY_LABELS = {
24
26
  IBAN: 'IBAN',
25
27
  ADDRESS: 'Address',
26
28
  COMPANY: 'Company',
29
+ SECRET: 'Secret',
30
+ API_KEY: 'API Key',
27
31
  OTHER: 'Other',
28
32
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doccloak/core",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Environment-agnostic document anonymization engine for the DocCloak ecosystem.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Witold Lojek",
@@ -12,6 +12,10 @@
12
12
  "types": "./dist/index.d.ts",
13
13
  "default": "./dist/index.js"
14
14
  },
15
+ "./restore-tokens": {
16
+ "types": "./dist/restore-tokens.d.ts",
17
+ "default": "./dist/restore-tokens.js"
18
+ },
15
19
  "./dom": {
16
20
  "types": "./dist/dom/index.d.ts",
17
21
  "default": "./dist/dom/index.js"
@@ -57,6 +61,9 @@
57
61
  "postpack": "node scripts/package-exports.mjs src",
58
62
  "rules:gen": "node scripts/generate-rules-module.mjs",
59
63
  "rules:check": "node scripts/generate-rules-module.mjs --check",
64
+ "bench": "node --experimental-strip-types eval/run.mts",
65
+ "bench:multilang": "node --experimental-strip-types eval/multilang.mts",
66
+ "bench:data": "node eval/download.mjs",
60
67
  "test": "vitest run",
61
68
  "test:watch": "vitest",
62
69
  "typecheck": "tsc --noEmit"
@@ -69,7 +76,7 @@
69
76
  "dependencies": {
70
77
  "cfb": "1.2.2",
71
78
  "jszip": "3.10.1",
72
- "onnxruntime-web": "1.19.2",
79
+ "onnxruntime-web": "1.29.0",
73
80
  "tesseract.js": "7.0.0"
74
81
  }
75
82
  }
package/rules/gb.json CHANGED
@@ -189,6 +189,23 @@
189
189
  "Tesco Ltd",
190
190
  "Deloitte LLP"
191
191
  ]
192
+ },
193
+ {
194
+ "id": "regex:gb:driving_licence",
195
+ "entityType": "SSN",
196
+ "pattern": "\\b[A-Z9]{5}\\s?\\d{6}\\s?[A-Z9]{2}\\d[A-Z]{2}\\b",
197
+ "flags": "g",
198
+ "confidence": 0.8,
199
+ "domains": [
200
+ "identity"
201
+ ],
202
+ "description": "UK driving licence number (16 chars: surname block, encoded date of birth, initials, check chars)",
203
+ "examples": [
204
+ "MORGA657054SM9IJ",
205
+ "SMITH 751125 JM9AB"
206
+ ],
207
+ "falsePositiveNotes": "Best-effort: other 16-char uppercase codes can match the shape; the validator checks the embedded date-of-birth digit block",
208
+ "validate": "ukDrivingLicence"
192
209
  }
193
210
  ]
194
211
  }
package/rules/schema.json CHANGED
@@ -41,6 +41,8 @@
41
41
  "IBAN",
42
42
  "ADDRESS",
43
43
  "COMPANY",
44
+ "SECRET",
45
+ "API_KEY",
44
46
  "OTHER"
45
47
  ]
46
48
  },
@@ -274,6 +274,175 @@
274
274
  "75008 Paris"
275
275
  ],
276
276
  "falsePositiveNotes": "May match non-address number+word sequences"
277
+ },
278
+ {
279
+ "id": "regex:universal:aws_access_key",
280
+ "entityType": "API_KEY",
281
+ "pattern": "\\b(?:AKIA|ASIA|ABIA|ACCA|AGPA|AIDA|AIPA|ANPA|ANVA|AROA)[0-9A-Z]{16}\\b",
282
+ "flags": "g",
283
+ "confidence": 0.95,
284
+ "domains": [
285
+ "technical"
286
+ ],
287
+ "description": "AWS access key ID (AKIA/ASIA + 16 uppercase alphanumeric)",
288
+ "examples": [
289
+ "AKIAIOSFODNN7EXAMPLE",
290
+ "ASIAJEXAMPLEKEY12345"
291
+ ]
292
+ },
293
+ {
294
+ "id": "regex:universal:github_token",
295
+ "entityType": "API_KEY",
296
+ "pattern": "\\b(?:gh[pousr]_[A-Za-z0-9]{36,255}|github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59})\\b",
297
+ "flags": "g",
298
+ "confidence": 0.95,
299
+ "domains": [
300
+ "technical"
301
+ ],
302
+ "description": "GitHub token (classic ghp_/gho_/ghu_/ghs_/ghr_ or fine-grained github_pat_)",
303
+ "examples": [
304
+ "ghp_16C7e42F292c6912E7710c838347Ae178B4a",
305
+ "github_pat_11ABCDEFG0123456789abc_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456"
306
+ ]
307
+ },
308
+ {
309
+ "id": "regex:universal:slack_token",
310
+ "entityType": "API_KEY",
311
+ "pattern": "\\bxox[abprs]-[A-Za-z0-9-]{10,64}\\b",
312
+ "flags": "g",
313
+ "confidence": 0.95,
314
+ "domains": [
315
+ "technical"
316
+ ],
317
+ "description": "Slack token (xoxb- bot, xoxp- user, xoxa-/xoxr-/xoxs- variants)",
318
+ "examples": [
319
+ "xoxb-NotARealBotToken-DocCloakTestFixture",
320
+ "xoxp-FakeUserToken-DocCloakTestFixture00"
321
+ ]
322
+ },
323
+ {
324
+ "id": "regex:universal:openai_api_key",
325
+ "entityType": "API_KEY",
326
+ "pattern": "\\bsk-(?:(?:proj|svcacct|admin)-[A-Za-z0-9_-]{40,}|[A-Za-z0-9]{40,})\\b",
327
+ "flags": "g",
328
+ "confidence": 0.92,
329
+ "domains": [
330
+ "technical"
331
+ ],
332
+ "description": "OpenAI API key (legacy sk- + 40+ alphanumeric, or sk-proj-/sk-svcacct-/sk-admin- project keys)",
333
+ "examples": [
334
+ "sk-proj-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGh",
335
+ "sk-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhIjKl"
336
+ ],
337
+ "falsePositiveNotes": "Anthropic sk-ant- keys never reach the alphanumeric-only branch (hyphen after ant stops it); the dedicated anthropic rule wins overlap resolution via its longer prefix"
338
+ },
339
+ {
340
+ "id": "regex:universal:anthropic_api_key",
341
+ "entityType": "API_KEY",
342
+ "pattern": "\\bsk-ant-[A-Za-z0-9_-]{24,}\\b",
343
+ "flags": "g",
344
+ "confidence": 0.95,
345
+ "domains": [
346
+ "technical"
347
+ ],
348
+ "description": "Anthropic API key (sk-ant- prefix)",
349
+ "examples": [
350
+ "sk-ant-api03-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789-AbCdEfGh"
351
+ ]
352
+ },
353
+ {
354
+ "id": "regex:universal:google_api_key",
355
+ "entityType": "API_KEY",
356
+ "pattern": "\\bAIza[0-9A-Za-z_-]{35}\\b",
357
+ "flags": "g",
358
+ "confidence": 0.95,
359
+ "domains": [
360
+ "technical"
361
+ ],
362
+ "description": "Google API key (AIza + 35 characters)",
363
+ "examples": [
364
+ "AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY"
365
+ ]
366
+ },
367
+ {
368
+ "id": "regex:universal:private_key_block",
369
+ "entityType": "SECRET",
370
+ "pattern": "-----BEGIN (?:[A-Z]+ )*PRIVATE KEY(?: BLOCK)?-----[\\s\\S]*?-----END (?:[A-Z]+ )*PRIVATE KEY(?: BLOCK)?-----",
371
+ "flags": "g",
372
+ "confidence": 0.99,
373
+ "domains": [
374
+ "technical"
375
+ ],
376
+ "description": "PEM private key block (RSA/EC/DSA/OPENSSH/ENCRYPTED/PGP), including SSH private keys",
377
+ "examples": [
378
+ "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA0Z3VS5JJcds3xfn\n-----END RSA PRIVATE KEY-----",
379
+ "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmU\n-----END OPENSSH PRIVATE KEY-----"
380
+ ]
381
+ },
382
+ {
383
+ "id": "regex:universal:jwt",
384
+ "entityType": "SECRET",
385
+ "pattern": "\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b",
386
+ "flags": "g",
387
+ "confidence": 0.95,
388
+ "domains": [
389
+ "technical"
390
+ ],
391
+ "description": "JSON Web Token (three base64url segments, header starts with eyJ = base64 of '{\")",
392
+ "examples": [
393
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
394
+ ]
395
+ },
396
+ {
397
+ "id": "regex:universal:connection_string_creds",
398
+ "entityType": "SECRET",
399
+ "pattern": "\\b[a-zA-Z][a-zA-Z0-9+.-]{1,30}:\\/\\/[^\\s:@\\/]{1,64}:[^\\s@]{1,128}@[^\\s\"']{1,256}",
400
+ "flags": "g",
401
+ "confidence": 0.9,
402
+ "domains": [
403
+ "technical"
404
+ ],
405
+ "description": "Connection string with inline credentials (scheme://user:password@host)",
406
+ "examples": [
407
+ "postgres://admin:S3cr3tPass@db.example.com:5432/mydb",
408
+ "mongodb+srv://appuser:hunter2pass@cluster0.abc.mongodb.net/prod"
409
+ ],
410
+ "falsePositiveNotes": "Plain URLs without a user:password pair never match (the colon between user and password is required before the @)"
411
+ },
412
+ {
413
+ "id": "regex:universal:secret_assignment",
414
+ "entityType": "SECRET",
415
+ "pattern": "\\b[a-zA-Z0-9_-]{0,32}?(?:api[_-]?key|apikey|secret|token|passwd|password|credential|auth|access[_-]?key|client[_-]?secret|private[_-]?key|signing[_-]?key)[a-zA-Z0-9_-]{0,32}[\"']?\\s*[:=]>?\\s*[\"']?[A-Za-z0-9+\\/_=-]{16,}",
416
+ "flags": "gi",
417
+ "confidence": 0.75,
418
+ "domains": [
419
+ "technical"
420
+ ],
421
+ "description": "Secret-ish keyword assignment (api_key = ..., password: ..., aws_secret_access_key: ...) with a 16+ char value; the value is Shannon-entropy gated by the secretAssignment validator",
422
+ "examples": [
423
+ "api_key = \"9fQz3kX7Lm2Pw8Rt5Vy1Jh6Nd4Bg0Cs\"",
424
+ "aws_secret_access_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
425
+ "session_token=a3f8c2d914b7e605d2c8a1f4b9e7d305"
426
+ ],
427
+ "falsePositiveNotes": "The keyword and separator are part of the match (lookbehind is banned for new rules), so the config key name is redacted along with the value. Low-entropy placeholder values (your_api_key_here, changeme) are rejected by the validator.",
428
+ "validate": "secretAssignment"
429
+ },
430
+ {
431
+ "id": "regex:universal:high_entropy_token",
432
+ "entityType": "SECRET",
433
+ "pattern": "\\b[A-Za-z0-9][A-Za-z0-9+\\/]{39,}={0,2}",
434
+ "flags": "g",
435
+ "confidence": 0.6,
436
+ "domains": [
437
+ "technical"
438
+ ],
439
+ "description": "Bare high-entropy base64/alphanumeric token (40+ chars); the highEntropyToken validator requires mixed character classes and Shannon entropy >= 4.5 bits/char",
440
+ "examples": [
441
+ "Zq7PmX2vR9kLtY4wNb8QcJ3fHd6GsA1uEi5oT0xVrKp",
442
+ "kM3nP8qR2sT7uV1wX5yZ9aB4cD6eF0gH1jK2lM3nP4qR5sT6"
443
+ ],
444
+ "falsePositiveNotes": "Low confidence by design. Git SHAs and UUID fragments are single-case hex (rejected by the class-mix check); base64 data blobs exceed the 256 char cap; identifiers and prose fall below the entropy threshold.",
445
+ "validate": "highEntropyToken"
277
446
  }
278
447
  ]
279
448
  }