mask-privacy 3.5.1 → 4.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/index.d.mts CHANGED
@@ -69,6 +69,8 @@ interface Span {
69
69
  confidence: number;
70
70
  method: string;
71
71
  language?: string;
72
+ ruleId?: string;
73
+ complianceScope?: ReadonlySet<string>;
72
74
  maskedValue?: string;
73
75
  }
74
76
 
@@ -371,6 +373,8 @@ interface PatternDescriptor {
371
373
  validatorTag: string | null;
372
374
  isHighEntropy: boolean;
373
375
  supportedLocales: string[];
376
+ ruleId: string;
377
+ complianceScope: ReadonlySet<string>;
374
378
  }
375
379
  /**
376
380
  * Immutable catalogue of sensitive-data regex signatures.
package/dist/index.d.ts CHANGED
@@ -69,6 +69,8 @@ interface Span {
69
69
  confidence: number;
70
70
  method: string;
71
71
  language?: string;
72
+ ruleId?: string;
73
+ complianceScope?: ReadonlySet<string>;
72
74
  maskedValue?: string;
73
75
  }
74
76
 
@@ -371,6 +373,8 @@ interface PatternDescriptor {
371
373
  validatorTag: string | null;
372
374
  isHighEntropy: boolean;
373
375
  supportedLocales: string[];
376
+ ruleId: string;
377
+ complianceScope: ReadonlySet<string>;
374
378
  }
375
379
  /**
376
380
  * Immutable catalogue of sensitive-data regex signatures.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  var process2 = require('process');
4
4
  var path = require('path');
5
5
  var os = require('os');
6
- var cryptoNode = require('crypto');
6
+ var crypto2 = require('crypto');
7
7
  var buffer = require('buffer');
8
8
  var stream = require('stream');
9
9
  var https = require('https');
@@ -38,7 +38,7 @@ function _interopNamespace(e) {
38
38
  var process2__namespace = /*#__PURE__*/_interopNamespace(process2);
39
39
  var path__namespace = /*#__PURE__*/_interopNamespace(path);
40
40
  var os__namespace = /*#__PURE__*/_interopNamespace(os);
41
- var cryptoNode__namespace = /*#__PURE__*/_interopNamespace(cryptoNode);
41
+ var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
42
42
  var http2__default = /*#__PURE__*/_interopDefault(http2);
43
43
  var fs__default = /*#__PURE__*/_interopDefault(fs$1);
44
44
 
@@ -114,6 +114,16 @@ var init_config = __esm({
114
114
  get MASK_LOG_LEVEL() {
115
115
  return (process2__namespace.env.MASK_LOG_LEVEL || "info").toLowerCase();
116
116
  },
117
+ // --- COMPLIANCE & PRIVACY (Bijective) ---
118
+ get MASK_TENANT_ID() {
119
+ return process2__namespace.env.MASK_TENANT_ID || "global-default-tenant";
120
+ },
121
+ get MASK_SALT_ROTATION() {
122
+ return (process2__namespace.env.MASK_SALT_ROTATION || "NONE").toUpperCase();
123
+ },
124
+ get MASK_BIJECTIVE_MODE() {
125
+ return getEnvBool("MASK_BIJECTIVE_MODE", true);
126
+ },
117
127
  // --- SECURITY & CRYPTOGRAPHY ---
118
128
  get MASK_ENCRYPTION_KEY() {
119
129
  return process2__namespace.env.MASK_ENCRYPTION_KEY || null;
@@ -252,6 +262,216 @@ var init_exceptions = __esm({
252
262
  }
253
263
  });
254
264
 
265
+ // src/core/synthesisLibrary.ts
266
+ var FIRST_NAMES, CONNECTORS, SURNAME_ROOTS, SURNAME_SUFFIXES, SYLLABLES;
267
+ var init_synthesisLibrary = __esm({
268
+ "src/core/synthesisLibrary.ts"() {
269
+ FIRST_NAMES = [
270
+ "James",
271
+ "Mary",
272
+ "Robert",
273
+ "Patricia",
274
+ "John",
275
+ "Jennifer",
276
+ "Michael",
277
+ "Linda",
278
+ "David",
279
+ "Elizabeth",
280
+ "William",
281
+ "Barbara",
282
+ "Richard",
283
+ "Susan",
284
+ "Joseph",
285
+ "Jessica"
286
+ ];
287
+ while (FIRST_NAMES.length < 2048) {
288
+ FIRST_NAMES.push(`NameEx_${FIRST_NAMES.length}`);
289
+ }
290
+ CONNECTORS = [
291
+ "of",
292
+ "from",
293
+ "van",
294
+ "del",
295
+ "di",
296
+ "von",
297
+ "le",
298
+ "la",
299
+ "de",
300
+ "el",
301
+ "the",
302
+ "near",
303
+ "at",
304
+ "by",
305
+ "under",
306
+ "over",
307
+ "across",
308
+ "beyond",
309
+ "within",
310
+ "without",
311
+ "and",
312
+ "with",
313
+ "aka",
314
+ "alias",
315
+ "formally",
316
+ "lately",
317
+ "born",
318
+ "styled",
319
+ "known",
320
+ "called",
321
+ "st",
322
+ "al",
323
+ "bin",
324
+ "ibn",
325
+ "abu",
326
+ "ben",
327
+ "bar",
328
+ "fitz",
329
+ "mac",
330
+ "mc",
331
+ "o",
332
+ "da",
333
+ "dos",
334
+ "das",
335
+ "do",
336
+ "du",
337
+ "della",
338
+ "degli",
339
+ "dei",
340
+ "delle",
341
+ "sur",
342
+ "ter",
343
+ "ten",
344
+ "zu",
345
+ "zum",
346
+ "zur",
347
+ "auf",
348
+ "an",
349
+ "der",
350
+ "die",
351
+ "das",
352
+ "pro",
353
+ "anti",
354
+ "ex",
355
+ "quasi"
356
+ ];
357
+ SURNAME_ROOTS = [
358
+ "Silver",
359
+ "Gold",
360
+ "Iron",
361
+ "Stone",
362
+ "Rock",
363
+ "Wood",
364
+ "Leaf",
365
+ "Rain",
366
+ "Snow",
367
+ "Wind",
368
+ "Storm",
369
+ "Cloud",
370
+ "Sun",
371
+ "Moon",
372
+ "Star",
373
+ "Sky",
374
+ "Sea",
375
+ "Lake",
376
+ "River",
377
+ "Brook",
378
+ "Hill",
379
+ "Mount",
380
+ "Vale",
381
+ "Glen",
382
+ "Dale",
383
+ "Field",
384
+ "Meadow",
385
+ "Forest",
386
+ "Grove",
387
+ "Wild"
388
+ ];
389
+ while (SURNAME_ROOTS.length < 4096) {
390
+ SURNAME_ROOTS.push(`RootEx_${SURNAME_ROOTS.length}`);
391
+ }
392
+ SURNAME_SUFFIXES = [
393
+ "son",
394
+ "man",
395
+ "field",
396
+ "wood",
397
+ "berg",
398
+ "stein",
399
+ "ov",
400
+ "ova",
401
+ "ski",
402
+ "ska",
403
+ "ez",
404
+ "ez",
405
+ "ia",
406
+ "ic",
407
+ "os",
408
+ "as",
409
+ "is",
410
+ "us",
411
+ "er",
412
+ "en",
413
+ "ard",
414
+ "ier",
415
+ "eau",
416
+ "oux",
417
+ "ly",
418
+ "ley",
419
+ "ton",
420
+ "don",
421
+ "ham",
422
+ "ford",
423
+ "wick",
424
+ "shire",
425
+ "land",
426
+ "way",
427
+ "side",
428
+ "gate",
429
+ "bridge",
430
+ "well",
431
+ "pool",
432
+ "cliff",
433
+ "bank",
434
+ "shore",
435
+ "hart",
436
+ "foot",
437
+ "head",
438
+ "more",
439
+ "less",
440
+ "ness",
441
+ "ship",
442
+ "ward"
443
+ ];
444
+ while (SURNAME_SUFFIXES.length < 512) {
445
+ SURNAME_SUFFIXES.push(`SuffixEx_${SURNAME_SUFFIXES.length}`);
446
+ }
447
+ SYLLABLES = [
448
+ "San",
449
+ "Ver",
450
+ "Dina",
451
+ "Lon",
452
+ "Don",
453
+ "Chi",
454
+ "Ca",
455
+ "Go",
456
+ "New",
457
+ "York",
458
+ "Los",
459
+ "An",
460
+ "Ge",
461
+ "Les",
462
+ "Pa",
463
+ "Ris",
464
+ "Ber",
465
+ "Lin",
466
+ "Mad",
467
+ "Rid"
468
+ ];
469
+ while (SYLLABLES.length < 1e3) {
470
+ SYLLABLES.push(`Syl_${SYLLABLES.length}`);
471
+ }
472
+ }
473
+ });
474
+
255
475
  // src/core/fpe_utils.ts
256
476
  function looksLikeToken(value) {
257
477
  if (typeof value !== "string") return false;
@@ -286,13 +506,20 @@ function looksLikeToken(value) {
286
506
  if (v7.startsWith("[TKN-") && v7.endsWith("]")) {
287
507
  return true;
288
508
  }
509
+ if (v7.includes("-") && v7.length >= 6) {
510
+ const parts = v7.split("-");
511
+ const tag = parts[parts.length - 1];
512
+ if (tag.length === 4 && /^\d+$/.test(tag)) {
513
+ return true;
514
+ }
515
+ }
289
516
  return false;
290
517
  }
291
518
  var TOKEN_PATTERN;
292
519
  var init_fpe_utils = __esm({
293
520
  "src/core/fpe_utils.ts"() {
294
521
  TOKEN_PATTERN = new RegExp(
295
- "tkn-[a-f0-9]{8,64}@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}|\\+[1-9]\\d{0,3}-555-\\d{7}|000-00-\\d{4}|4000-0000-0000-\\d{4}|000000\\d{3}|000\\d{5}[A-Z]|[A-Z]{2}00[A-F0-9]{4,16}|<(?:PER|LOC|ORG):[^>]+>|\\[TKN-[a-f0-9]{8,64}\\]",
522
+ "tkn-[a-f0-9]{8,64}@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}|\\+[1-9]\\d{0,3}-555-\\d{7}|000-00-\\d{4}|4000-0000-0000-\\d{4}|000000\\d{3}|000\\d{5}[A-Z]|[A-Z]{2}00[A-F0-9]{4,16}|<(?:PER|LOC|ORG):[^>]+>|\\b[A-Z][a-zA-Z, ]+-[0-9]{3,4}\\b|\\\\[TKN-[a-f0-9]{8,64}\\\\]",
296
523
  // Opaque
297
524
  "g"
298
525
  );
@@ -307,7 +534,7 @@ async function _getMasterKey() {
307
534
  }
308
535
  if (!raw) {
309
536
  if (config.MASK_DEV_MODE) {
310
- raw = cryptoNode__namespace.randomBytes(32).toString("hex");
537
+ raw = crypto2__namespace.randomBytes(32).toString("hex");
311
538
  process.env.MASK_MASTER_KEY = raw;
312
539
  } else {
313
540
  throw new exports.MaskSecurityError(
@@ -324,27 +551,64 @@ function resetMasterKey() {
324
551
  }
325
552
  async function _hmacHex(plaintext, n6 = 8) {
326
553
  const masterKey = await _getMasterKey();
327
- const digest = cryptoNode__namespace.createHmac("sha256", masterKey).update(plaintext, "utf-8").digest("hex");
554
+ const digest = crypto2__namespace.createHmac("sha256", masterKey).update(plaintext, "utf-8").digest("hex");
328
555
  return digest.slice(0, n6);
329
556
  }
330
- async function _hmacDigits(plaintext, n6, offset = 0) {
557
+ async function _hmacInt(plaintext) {
331
558
  const masterKey = await _getMasterKey();
332
- const digest = cryptoNode__namespace.createHmac("sha256", masterKey).update(plaintext, "utf-8").digest("hex");
333
- const result = [];
334
- for (let i6 = offset; i6 < digest.length; i6++) {
335
- const ch = digest[i6];
336
- result.push((parseInt(ch, 16) % 10).toString());
337
- if (result.length === n6) break;
559
+ const raw = crypto2__namespace.createHmac("sha256", masterKey).update(plaintext, "utf-8").digest();
560
+ let result = 0n;
561
+ for (let i6 = 0; i6 < 16; i6++) {
562
+ result = result << 8n | BigInt(raw[i6]);
338
563
  }
339
- while (result.length < n6) {
340
- result.push("0");
564
+ return result;
565
+ }
566
+ async function _hmacDigits(plaintext, n6, offset = 0) {
567
+ const salted = offset ? `${plaintext}::${offset}` : plaintext;
568
+ const seed = await _hmacInt(salted);
569
+ const modulus = 10n ** BigInt(n6);
570
+ return (seed % modulus).toString().padStart(n6, "0");
571
+ }
572
+ async function _getBijectiveTweak() {
573
+ const masterKey = await _getMasterKey();
574
+ let base = config.MASK_TENANT_ID;
575
+ if (config.MASK_SALT_ROTATION !== "NONE") {
576
+ const now = /* @__PURE__ */ new Date();
577
+ if (config.MASK_SALT_ROTATION === "MONTHLY") {
578
+ base += `-${now.getUTCFullYear()}-${now.getUTCMonth() + 1}`;
579
+ } else if (config.MASK_SALT_ROTATION === "YEARLY") {
580
+ base += `-${now.getUTCFullYear()}`;
581
+ }
341
582
  }
342
- return result.join("");
583
+ return crypto2__namespace.createHmac("sha256", masterKey).update(base, "utf-8").digest();
343
584
  }
344
- async function _pickFromArray(plaintext, array) {
345
- const digits = await _hmacDigits(plaintext, 8);
346
- const num = parseInt(digits, 10);
347
- return array[num % array.length];
585
+ function _renderBijectivePerson(bits) {
586
+ const firstIdx = Number(bits & 0x7FFn);
587
+ const connIdx = Number(bits >> 11n & 0x3Fn);
588
+ const rootIdx = Number(bits >> 17n & 0xFFFn);
589
+ const suffixIdx = Number(bits >> 29n & 0x1FFn);
590
+ const tag = Number(bits >> 38n & 0x3FFFn);
591
+ const formatIdx = Number(bits >> 52n & 0xFn);
592
+ const first = FIRST_NAMES[firstIdx % FIRST_NAMES.length];
593
+ const conn = CONNECTORS[connIdx % CONNECTORS.length];
594
+ const root = SURNAME_ROOTS[rootIdx % SURNAME_ROOTS.length];
595
+ const suffix = SURNAME_SUFFIXES[suffixIdx % SURNAME_SUFFIXES.length];
596
+ const surname = `${root}${suffix}`;
597
+ const numeric = tag % 1e4;
598
+ const paddedNumeric = numeric.toString().padStart(4, "0");
599
+ if (formatIdx === 0) return `${first} ${conn} ${surname}-${paddedNumeric}`;
600
+ if (formatIdx === 1) return `${surname}, ${first}-${paddedNumeric}`;
601
+ if (formatIdx === 2) return `${first[0]}. ${surname}-${paddedNumeric}`;
602
+ if (formatIdx === 3) return `${first} ${surname}-${paddedNumeric}`;
603
+ return `${first} ${surname}-${paddedNumeric}`;
604
+ }
605
+ function _renderBijectiveLocation(bits) {
606
+ const s1 = Number(bits & 0x3FFn);
607
+ const s22 = Number(bits >> 10n & 0x3FFn);
608
+ const s32 = Number(bits >> 20n & 0x3FFn);
609
+ const tag = Number(bits >> 30n & 0xFFFn);
610
+ const city = `${SYLLABLES[s1 % 1e3]}${SYLLABLES[s22 % 1e3].toLowerCase()}${SYLLABLES[s32 % 1e3].toLowerCase()}`;
611
+ return `${city}-${tag.toString().padStart(3, "0")}`;
348
612
  }
349
613
  function _computeLuhnDigit(partialNum) {
350
614
  const digits = partialNum.split("").map(Number);
@@ -407,26 +671,41 @@ async function generateFPEToken(rawText, entityType = "UNKNOWN") {
407
671
  return digits + _computeEsIdCheck(parseInt(digits, 10));
408
672
  }
409
673
  if (type === "PERSON" || type === "PERSON_NAME") {
410
- const f6 = await _pickFromArray(text, _FIRST_NAMES);
411
- const l6 = await _pickFromArray(text + "last", _LAST_NAMES);
412
- return `<PER:${f6}_${l6}>`;
674
+ if (config.MASK_BIJECTIVE_MODE) {
675
+ const canonical = text.toLowerCase().trim();
676
+ const hash = crypto2__namespace.createHash("sha256").update(canonical, "utf-8").digest();
677
+ const inputInt = hash.readBigUInt64BE(0);
678
+ const masterKey = await _getMasterKey();
679
+ const engine = new FF1(masterKey.slice(0, 16), await _getBijectiveTweak());
680
+ const cipher = engine.encrypt(inputInt);
681
+ return _renderBijectivePerson(cipher);
682
+ }
683
+ return `[TKN-PERSON-${await _hmacHex(text)}]`;
413
684
  }
414
685
  if (type === "LOCATION" || type === "PHYS_ADDRESS") {
415
- const c6 = await _pickFromArray(text, _CITIES);
416
- return `<LOC:${c6}>`;
686
+ if (config.MASK_BIJECTIVE_MODE) {
687
+ const canonical = text.toLowerCase().trim();
688
+ const hash = crypto2__namespace.createHash("sha256").update(canonical, "utf-8").digest();
689
+ const inputInt = hash.readBigUInt64BE(0);
690
+ const masterKey = await _getMasterKey();
691
+ const engine = new FF1(masterKey.slice(0, 16), await _getBijectiveTweak());
692
+ const cipher = engine.encrypt(inputInt);
693
+ return _renderBijectiveLocation(cipher);
694
+ }
695
+ return `[TKN-LOC-${await _hmacHex(text)}]`;
417
696
  }
418
697
  if (type === "ORGANIZATION") {
419
- const c6 = await _pickFromArray(text, _LAST_NAMES);
420
- return `<ORG:${c6}_Inc>`;
698
+ return `[TKN-ORG-${await _hmacHex(text)}]`;
421
699
  }
422
700
  return `[TKN-${await _hmacHex(text)}]`;
423
701
  }
424
- var _masterKey, _EMAIL_RE, _PHONE_RE, _SSN_RE, _CC_RE, _ROUTING_RE, _ES_ID_RE, _IBAN_RE, _FIRST_NAMES, _LAST_NAMES, _CITIES;
702
+ var _masterKey, _EMAIL_RE, _PHONE_RE, _SSN_RE, _CC_RE, _ROUTING_RE, _ES_ID_RE, _IBAN_RE, FF1;
425
703
  var init_fpe = __esm({
426
704
  "src/core/fpe.ts"() {
427
705
  init_config();
428
706
  init_key_provider();
429
707
  init_exceptions();
708
+ init_synthesisLibrary();
430
709
  init_fpe_utils();
431
710
  _masterKey = null;
432
711
  _EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
@@ -436,9 +715,49 @@ var init_fpe = __esm({
436
715
  _ROUTING_RE = /^\d{9}$/;
437
716
  _ES_ID_RE = /^(?:\d{8}[A-Z]|[XYZ]\d{7}[A-Z])$/;
438
717
  _IBAN_RE = /^[A-Z]{2}\d{2}[A-Z0-9]{4,30}$/;
439
- _FIRST_NAMES = ["Taylor", "Jordan", "Casey", "Morgan", "Riley", "Avery", "Rowan", "Quinn", "Charlie", "Peyton", "Blake", "Dakota", "Reese", "Skyler", "Finley", "Eden", "Harley", "Rory", "Emerson", "Remi"];
440
- _LAST_NAMES = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin"];
441
- _CITIES = ["London", "Paris", "Berlin", "Tokyo", "Rome", "Madrid", "Vienna", "Sydney", "Toronto", "Chicago", "Seattle", "Austin", "Boston", "Denver", "Dallas", "Miami", "Seoul", "Dubai", "Mumbai", "Cairo"];
718
+ FF1 = class {
719
+ /** NIST SP 800-38G FF1 implementation (simplified for 64-bit domains). */
720
+ constructor(key, tweak) {
721
+ this.key = key;
722
+ this.tweak = tweak;
723
+ }
724
+ encrypt(n6) {
725
+ let A3 = n6 >> 32n;
726
+ let B3 = n6 & 0xFFFFFFFFn;
727
+ const radix = 2n ** 32n;
728
+ for (let i6 = 0; i6 < 10; i6++) {
729
+ const tweakInfoBuffer = Buffer.alloc(8);
730
+ tweakInfoBuffer.writeUInt32BE(i6, 0);
731
+ tweakInfoBuffer.writeUInt32BE(Number(B3), 4);
732
+ const tweakInfoCombined = Buffer.concat([this.tweak, tweakInfoBuffer]);
733
+ const h6 = crypto2__namespace.createHmac("sha256", this.key).update(tweakInfoCombined).digest();
734
+ const roundVal = BigInt(h6.readUInt32BE(0));
735
+ const Anext = B3;
736
+ const Bnext = (A3 + roundVal) % radix;
737
+ A3 = Anext;
738
+ B3 = Bnext;
739
+ }
740
+ return A3 << 32n | B3;
741
+ }
742
+ decrypt(n6) {
743
+ let A3 = n6 >> 32n;
744
+ let B3 = n6 & 0xFFFFFFFFn;
745
+ const radix = 2n ** 32n;
746
+ for (let i6 = 9; i6 >= 0; i6--) {
747
+ const tweakInfoBuffer = Buffer.alloc(8);
748
+ tweakInfoBuffer.writeUInt32BE(i6, 0);
749
+ tweakInfoBuffer.writeUInt32BE(Number(A3), 4);
750
+ const tweakInfoCombined = Buffer.concat([this.tweak, tweakInfoBuffer]);
751
+ const h6 = crypto2__namespace.createHmac("sha256", this.key).update(tweakInfoCombined).digest();
752
+ const roundVal = BigInt(h6.readUInt32BE(0));
753
+ const Bprev = A3;
754
+ const Aprev = (B3 - roundVal + radix) % radix;
755
+ A3 = Aprev;
756
+ B3 = Bprev;
757
+ }
758
+ return A3 << 32n | B3;
759
+ }
760
+ };
442
761
  }
443
762
  });
444
763
 
@@ -2906,7 +3225,7 @@ var init_crypto = __esm({
2906
3225
  let key;
2907
3226
  if (!keyFromProvider) {
2908
3227
  if (config.MASK_DEV_MODE) {
2909
- key = cryptoNode__namespace.randomBytes(32).toString("base64");
3228
+ key = crypto2__namespace.randomBytes(32).toString("base64");
2910
3229
  process.env.MASK_ENCRYPTION_KEY = key;
2911
3230
  console.warn(
2912
3231
  "MASK_DEV_MODE is enabled. Using a generated throwaway key. DO NOT USE THIS IN PRODUCTION \u2014 tokens will be lost on restart."
@@ -2919,10 +3238,10 @@ var init_crypto = __esm({
2919
3238
  } else {
2920
3239
  key = keyFromProvider;
2921
3240
  }
2922
- this._aesKey = cryptoNode__namespace.createHash("sha256").update(key).digest();
3241
+ this._aesKey = crypto2__namespace.createHash("sha256").update(key).digest();
2923
3242
  const masterKey = await provider.getMasterKey() || key;
2924
3243
  const salt = config.MASK_BLIND_INDEX_SALT;
2925
- this._indexSecret = cryptoNode__namespace.createHmac("sha256", masterKey).update(salt).digest();
3244
+ this._indexSecret = crypto2__namespace.createHmac("sha256", masterKey).update(salt).digest();
2926
3245
  }
2927
3246
  /** Return the secret used for HMAC-based blind indexing. */
2928
3247
  async getIndexSecret() {
@@ -2935,8 +3254,8 @@ var init_crypto = __esm({
2935
3254
  if (!this._aesKey) {
2936
3255
  throw new Error("CryptoEngine not initialised. AES key missing.");
2937
3256
  }
2938
- const iv = cryptoNode__namespace.randomBytes(GCM_IV_BYTES);
2939
- const cipher = cryptoNode__namespace.createCipheriv(GCM_ALGORITHM, this._aesKey, iv);
3257
+ const iv = crypto2__namespace.randomBytes(GCM_IV_BYTES);
3258
+ const cipher = crypto2__namespace.createCipheriv(GCM_ALGORITHM, this._aesKey, iv);
2940
3259
  const encrypted = Buffer.concat([
2941
3260
  cipher.update(plaintext, "utf8"),
2942
3261
  cipher.final()
@@ -2968,7 +3287,7 @@ var init_crypto = __esm({
2968
3287
  const iv = combined.subarray(0, GCM_IV_BYTES);
2969
3288
  const authTag = combined.subarray(GCM_IV_BYTES, GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
2970
3289
  const encrypted = combined.subarray(GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
2971
- const decipher = cryptoNode__namespace.createDecipheriv(GCM_ALGORITHM, this._aesKey, iv);
3290
+ const decipher = crypto2__namespace.createDecipheriv(GCM_ALGORITHM, this._aesKey, iv);
2972
3291
  decipher.setAuthTag(authTag);
2973
3292
  const decrypted = Buffer.concat([
2974
3293
  decipher.update(encrypted),
@@ -3152,7 +3471,8 @@ var init_audit_logger = __esm({
3152
3471
  this._buffer = [];
3153
3472
  this._bufferFullWarned = false;
3154
3473
  for (const evt of events) {
3155
- console.info(JSON.stringify(evt));
3474
+ const json = JSON.stringify(evt, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
3475
+ console.info(json);
3156
3476
  }
3157
3477
  } finally {
3158
3478
  this._isFlushing = false;
@@ -3216,7 +3536,7 @@ var init_search = __esm({
3216
3536
  static async getBucketIndex(bucketVal) {
3217
3537
  const engine = await getCryptoEngine();
3218
3538
  const secret = await engine.getIndexSecret();
3219
- return cryptoNode__namespace.createHmac("sha256", secret).update(bucketVal).digest("hex");
3539
+ return crypto2__namespace.createHmac("sha256", secret).update(bucketVal).digest("hex");
3220
3540
  }
3221
3541
  };
3222
3542
  }
@@ -17760,7 +18080,7 @@ var init_date_utils = __esm({
17760
18080
  var randomUUID;
17761
18081
  var init_randomUUID = __esm({
17762
18082
  "node_modules/@smithy/uuid/dist-es/randomUUID.js"() {
17763
- randomUUID = cryptoNode__namespace.default.randomUUID.bind(cryptoNode__namespace.default);
18083
+ randomUUID = crypto2__namespace.default.randomUUID.bind(crypto2__namespace.default);
17764
18084
  }
17765
18085
  });
17766
18086
 
@@ -27480,7 +27800,7 @@ var init_getSSOTokenFilepath = __esm({
27480
27800
  "node_modules/@smithy/shared-ini-file-loader/dist-es/getSSOTokenFilepath.js"() {
27481
27801
  init_getHomeDir();
27482
27802
  getSSOTokenFilepath = (id) => {
27483
- const hasher = cryptoNode.createHash("sha1");
27803
+ const hasher = crypto2.createHash("sha1");
27484
27804
  const cacheName = hasher.update(id).digest("hex");
27485
27805
  return path.join(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
27486
27806
  };
@@ -34145,7 +34465,7 @@ var init_dist_es46 = __esm({
34145
34465
  return Promise.resolve(this.hash.digest());
34146
34466
  }
34147
34467
  reset() {
34148
- this.hash = this.secret ? cryptoNode.createHmac(this.algorithmIdentifier, castSourceData(this.secret)) : cryptoNode.createHash(this.algorithmIdentifier);
34468
+ this.hash = this.secret ? crypto2.createHmac(this.algorithmIdentifier, castSourceData(this.secret)) : crypto2.createHash(this.algorithmIdentifier);
34149
34469
  }
34150
34470
  };
34151
34471
  }
@@ -38380,7 +38700,7 @@ var init_LoginCredentialsFetcher = __esm({
38380
38700
  getTokenFilePath() {
38381
38701
  const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? path.join(os.homedir(), ".aws", "login", "cache");
38382
38702
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
38383
- const loginSessionSha256 = cryptoNode.createHash("sha256").update(loginSessionBytes).digest("hex");
38703
+ const loginSessionSha256 = crypto2.createHash("sha256").update(loginSessionBytes).digest("hex");
38384
38704
  return path.join(directory, `${loginSessionSha256}.json`);
38385
38705
  }
38386
38706
  derToRawSignature(derSignature) {
@@ -38425,12 +38745,12 @@ var init_LoginCredentialsFetcher = __esm({
38425
38745
  async generateDpop(method = "POST", endpoint) {
38426
38746
  const token = await this.loadToken();
38427
38747
  try {
38428
- const privateKey = cryptoNode.createPrivateKey({
38748
+ const privateKey = crypto2.createPrivateKey({
38429
38749
  key: token.dpopKey,
38430
38750
  format: "pem",
38431
38751
  type: "sec1"
38432
38752
  });
38433
- const publicKey = cryptoNode.createPublicKey(privateKey);
38753
+ const publicKey = crypto2.createPublicKey(privateKey);
38434
38754
  const publicDer = publicKey.export({ format: "der", type: "spki" });
38435
38755
  let pointStart = -1;
38436
38756
  for (let i6 = 0; i6 < publicDer.length; i6++) {
@@ -38460,7 +38780,7 @@ var init_LoginCredentialsFetcher = __esm({
38460
38780
  const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
38461
38781
  const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
38462
38782
  const message = `${headerB64}.${payloadB64}`;
38463
- const asn1Signature = cryptoNode.sign("sha256", Buffer.from(message), privateKey);
38783
+ const asn1Signature = crypto2.sign("sha256", Buffer.from(message), privateKey);
38464
38784
  const rawSignature = this.derToRawSignature(asn1Signature);
38465
38785
  const signatureB64 = rawSignature.toString("base64url");
38466
38786
  return `${message}.${signatureB64}`;
@@ -42996,9 +43316,9 @@ function _getFailStrategy() {
42996
43316
  function _hashPlaintext(plaintext, secret) {
42997
43317
  const trimmed = plaintext.trim();
42998
43318
  if (secret) {
42999
- return cryptoNode__namespace.createHmac("sha256", secret).update(trimmed, "utf-8").digest("hex");
43319
+ return crypto2__namespace.createHmac("sha256", secret).update(trimmed, "utf-8").digest("hex");
43000
43320
  }
43001
- return cryptoNode__namespace.createHash("sha256").update(trimmed, "utf-8").digest("hex");
43321
+ return crypto2__namespace.createHash("sha256").update(trimmed, "utf-8").digest("hex");
43002
43322
  }
43003
43323
  function getVault() {
43004
43324
  if (_vaultInstance === null) {
@@ -43913,7 +44233,7 @@ var init_registry = __esm({
43913
44233
  }
43914
44234
  buildCatalogue(restrict) {
43915
44235
  for (const entry of RAW_PATTERNS) {
43916
- const [typeName, regexSource, terms, risk, cat, vtag, isHighEntropy, supportedLocales] = entry;
44236
+ const [typeName, regexSource, terms, risk, cat, vtag, isHighEntropy, supportedLocales, ruleId, complianceScope] = entry;
43917
44237
  if (restrict !== null && !restrict.has(cat)) continue;
43918
44238
  let re;
43919
44239
  if (regexSource instanceof RegExp) {
@@ -43928,7 +44248,9 @@ var init_registry = __esm({
43928
44248
  category: cat,
43929
44249
  validatorTag: vtag,
43930
44250
  isHighEntropy: isHighEntropy ?? vtag !== null,
43931
- supportedLocales: supportedLocales ?? ["*"]
44251
+ supportedLocales: supportedLocales ?? ["*"],
44252
+ ruleId: ruleId ?? `MASK-${cat.slice(0, 3)}-${typeName}`,
44253
+ complianceScope: new Set(complianceScope ?? [])
43932
44254
  });
43933
44255
  }
43934
44256
  }
@@ -59206,7 +59528,9 @@ var init_scanner = __esm({
59206
59528
  originalValue: matchedStr,
59207
59529
  confidence: conf,
59208
59530
  method: "dlp_heuristic",
59209
- language: detectedLanguage
59531
+ language: detectedLanguage,
59532
+ ruleId: descriptor.ruleId,
59533
+ complianceScope: descriptor.complianceScope
59210
59534
  });
59211
59535
  }
59212
59536
  }