@privacyscrubber/sdk 2.4.1 → 2.4.2
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/cli.js +7 -1
- package/examples/python-bridge/bridge_daemon.cjs +1 -1
- package/examples/python-bridge/fastapi_example.py +1 -1
- package/examples/python-bridge/privacyscrubber/__init__.py +1 -1
- package/examples/python-bridge/privacyscrubber/bridge_daemon.cjs +1 -1
- package/examples/python-bridge/privacyscrubber/cli.py +1 -1
- package/examples/python-bridge/pyproject.toml +1 -1
- package/examples/python-bridge/setup.py +1 -1
- package/examples/python-bridge/test_python_bridge.py +1 -1
- package/index.cjs +21 -7
- package/index.js +21 -7
- package/package.json +5 -1
- package/ps-license-manager.js +261 -11
- package/ps-pii-engine.cjs +3611 -8
- package/scrubber-core.cjs +1801 -8
package/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ const __dirname = path.dirname(__filename);
|
|
|
23
23
|
|
|
24
24
|
const args = process.argv.slice(2);
|
|
25
25
|
|
|
26
|
-
let sdkVersion = '2.4.
|
|
26
|
+
let sdkVersion = '2.4.2';
|
|
27
27
|
try {
|
|
28
28
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
29
29
|
sdkVersion = pkg.version || sdkVersion;
|
|
@@ -389,6 +389,7 @@ fi
|
|
|
389
389
|
try { fs.chmodSync(preCommitPath, 0o755); } catch (_) {}
|
|
390
390
|
console.log('[PrivacyScrubber Hook] Successfully installed Zero-Trust pre-commit hook in .git/hooks/pre-commit.');
|
|
391
391
|
console.log('[PrivacyScrubber Hook] Staged changes will now be audited for unmasked secrets before commit.');
|
|
392
|
+
console.log('[GitHub] Star the open-source repository: https://github.com/moxno/privacyscrubber-mcp (CLI: gh repo star moxno/privacyscrubber-mcp)');
|
|
392
393
|
process.exit(0);
|
|
393
394
|
}
|
|
394
395
|
|
|
@@ -404,10 +405,15 @@ fi
|
|
|
404
405
|
fs.unlinkSync(preCommitPath);
|
|
405
406
|
}
|
|
406
407
|
console.log('[PrivacyScrubber Hook] Pre-commit hook removed successfully.');
|
|
408
|
+
console.log('[Feedback] Why did you remove the hook? (1-click instant log):');
|
|
409
|
+
console.log(' - False positive / Accuracy: https://privacyscrubber.com/uninstall/?src=sdk&reason=accuracy');
|
|
410
|
+
console.log(' - Workflow / Setup issue: https://privacyscrubber.com/uninstall/?src=sdk&reason=setup');
|
|
411
|
+
console.log(' - General feedback: https://privacyscrubber.com/uninstall/?mode=feedback&src=sdk');
|
|
407
412
|
process.exit(0);
|
|
408
413
|
}
|
|
409
414
|
}
|
|
410
415
|
console.log('[PrivacyScrubber Hook] Pre-commit hook was not found in active repository.');
|
|
416
|
+
console.log('[Feedback] Share feedback or report an issue: https://privacyscrubber.com/uninstall/?mode=feedback&src=sdk');
|
|
411
417
|
process.exit(0);
|
|
412
418
|
}
|
|
413
419
|
}
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "privacyscrubber"
|
|
7
|
-
version = "2.4.
|
|
7
|
+
version = "2.4.2"
|
|
8
8
|
description = "Zero-Trust Data Sanitization & In-Memory PII Shield for Python AI Pipelines (ZTDS RFC v1.0)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -13,7 +13,7 @@ with open(os.path.join(here, "README.md"), encoding="utf-8") as f:
|
|
|
13
13
|
|
|
14
14
|
setup(
|
|
15
15
|
name="privacyscrubber",
|
|
16
|
-
version="2.4.
|
|
16
|
+
version="2.4.2",
|
|
17
17
|
description="Zero-Trust Data Sanitization & In-Memory PII Shield for Python AI Pipelines (ZTDS RFC v1.0)",
|
|
18
18
|
long_description=long_description,
|
|
19
19
|
long_description_content_type="text/markdown",
|
package/index.cjs
CHANGED
|
@@ -238,7 +238,7 @@ const buildCisoAuditTelemetry = buildAuditTelemetry;
|
|
|
238
238
|
function formatAuditReceipt(telemetry) {
|
|
239
239
|
if (!telemetry || telemetry.totalCount === 0) {
|
|
240
240
|
return "> 🛡️ **PrivacyScrubber Audit Receipt**: CLEAN (ZERO PII DETECTED)\n" +
|
|
241
|
-
"> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing)\n";
|
|
241
|
+
"> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **7-Day B2B Trial:** `npx @privacyscrubber/sdk trial` | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=audit_receipt)\n";
|
|
242
242
|
}
|
|
243
243
|
const entitiesList = Object.entries(telemetry.entities)
|
|
244
244
|
.map(([type, count]) => `${count} ${type}`)
|
|
@@ -250,7 +250,7 @@ function formatAuditReceipt(telemetry) {
|
|
|
250
250
|
`> * **Risk Level:** ${icon} ${telemetry.riskLevel}\n` +
|
|
251
251
|
`> * **Framework References (informational):** ${telemetry.frameworksList.join(', ')}\n` +
|
|
252
252
|
`> * **Tokens Masked:** ${telemetry.totalCount} (${entitiesList})\n` +
|
|
253
|
-
`> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing)\n`;
|
|
253
|
+
`> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **7-Day B2B Trial:** \`npx @privacyscrubber/sdk trial\` | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=audit_receipt)\n`;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
let communityNoticeLogged = false;
|
|
@@ -259,7 +259,7 @@ function emitCommunityNoticeIfNeeded(isPro) {
|
|
|
259
259
|
if (communityNoticeLogged || isPro) return;
|
|
260
260
|
if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
|
|
261
261
|
communityNoticeLogged = true;
|
|
262
|
-
console.info('[@privacyscrubber/sdk] Running Community Edition (Core PII).\nTo unlock
|
|
262
|
+
console.info('[@privacyscrubber/sdk] Running Community Edition (Core PII).\nTo unlock 30 Enterprise Profiles & DevOps Secrets in production: https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=prod_notice (7-Day Trial: npx @privacyscrubber/sdk trial | CISO Memo: npx @privacyscrubber/sdk memo)');
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
@@ -291,7 +291,8 @@ function emitDevSecretNoticeIfNeeded(isPro, tokenMap = {}, limit = 15000) {
|
|
|
291
291
|
process.stderr.write(
|
|
292
292
|
`\n[PrivacyScrubber] Intercepted ${count} API secret(s) before LLM egress: ${secretSample}\n` +
|
|
293
293
|
`[PrivacyScrubber] Protected in local RAM (0 byte network egress). Free Tier active (${limit.toLocaleString()} char cap).\n` +
|
|
294
|
-
`[PrivacyScrubber] Developer SDK ($299/mo flat) for unlimited backend nodes, CI/CD gates & ETL pipelines: https://privacyscrubber.com/pricing?tier=sdk&src=cli_leak_guard\n
|
|
294
|
+
`[PrivacyScrubber] Developer SDK ($299/mo flat) for unlimited backend nodes, CI/CD gates & ETL pipelines: https://privacyscrubber.com/pricing?tier=sdk&src=cli_leak_guard\n` +
|
|
295
|
+
`[PrivacyScrubber] Instant 7-Day Free B2B Trial: npx @privacyscrubber/sdk trial | CISO Approval Memo: npx @privacyscrubber/sdk memo\n\n`
|
|
295
296
|
);
|
|
296
297
|
}
|
|
297
298
|
}
|
|
@@ -478,6 +479,18 @@ function sanitize(text, options = {}) {
|
|
|
478
479
|
|
|
479
480
|
const licenseCheck = validateLicense(licenseKey);
|
|
480
481
|
const rawTier = licenseCheck.valid ? (licenseCheck.tier || 'PRO') : 'FREE';
|
|
482
|
+
const isExpiredKey = !licenseCheck.valid && typeof licenseCheck.error === 'string' && /expired/i.test(licenseCheck.error);
|
|
483
|
+
const isExpiringSoon = licenseCheck.valid && typeof licenseCheck.expires === 'number' && (licenseCheck.expires - Date.now() <= 48 * 3600 * 1000);
|
|
484
|
+
|
|
485
|
+
if (isExpiringSoon && typeof process !== 'undefined' && process.stderr && !globalThis.__psSdkPreExpiryLogged) {
|
|
486
|
+
globalThis.__psSdkPreExpiryLogged = true;
|
|
487
|
+
const hrs = Math.max(0, Math.round((licenseCheck.expires - Date.now()) / 3600000));
|
|
488
|
+
process.stderr.write(
|
|
489
|
+
`\n[@privacyscrubber/sdk] ⏳ 7-Day Evaluation Key expires in ~${hrs}h. Prevent pipeline interruption:\n` +
|
|
490
|
+
` - Commercial SDK ($299/mo flat): https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=pilot_expiring_48h\n` +
|
|
491
|
+
` - CISO Approval Memo: npx @privacyscrubber/sdk memo\n\n`
|
|
492
|
+
);
|
|
493
|
+
}
|
|
481
494
|
|
|
482
495
|
// Anti-Cannibalization Barrier (SSOT):
|
|
483
496
|
// PRO ($15/mo) and TEAMS ($99/mo) licenses are strictly human-seat licenses for Web App & Chrome Extension.
|
|
@@ -511,7 +524,8 @@ function sanitize(text, options = {}) {
|
|
|
511
524
|
|
|
512
525
|
if (!isPro && text.length > limit) {
|
|
513
526
|
if (shouldThrow) {
|
|
514
|
-
const
|
|
527
|
+
const expiredPrefix = isExpiredKey ? `[PILOT/TRIAL EXPIRED: ${licenseCheck.error}] ` : '';
|
|
528
|
+
const errorMsg = `[PrivacyScrubber] ${expiredPrefix}Free Tier character limit exceeded (${limit.toLocaleString()} chars for profile '${profile}', received ${text.length.toLocaleString()} chars). Upgrade to Developer SDK ($299/mo) for unlimited throughput: https://privacyscrubber.com/pricing?tier=sdk&src=${isExpiredKey ? 'pilot_expired' : 'dev_limit'} (Run 'npx @privacyscrubber/sdk memo' for CISO approval memo)`;
|
|
515
529
|
throw new PrivacyScrubberLicenseError(errorMsg, {
|
|
516
530
|
tier: 'FREE',
|
|
517
531
|
currentLength: text.length,
|
|
@@ -1917,7 +1931,7 @@ function formatCefEvent(eventData = {}) {
|
|
|
1917
1931
|
const {
|
|
1918
1932
|
vendor = 'PrivacyScrubber',
|
|
1919
1933
|
product = 'ZTDS',
|
|
1920
|
-
version = '2.4.
|
|
1934
|
+
version = '2.4.2',
|
|
1921
1935
|
eventClassId = 'PII_REDACTION',
|
|
1922
1936
|
eventName = 'Zero-Trust PII Sanitization Executed',
|
|
1923
1937
|
riskLevel = 'LOW EXPOSURE',
|
|
@@ -1986,7 +2000,7 @@ function formatSyslogEvent(eventData = {}) {
|
|
|
1986
2000
|
function formatJsonlEvent(eventData = {}) {
|
|
1987
2001
|
const {
|
|
1988
2002
|
timestamp = new Date().toISOString(),
|
|
1989
|
-
version = '2.4.
|
|
2003
|
+
version = '2.4.2',
|
|
1990
2004
|
protocol = 'ZTDS',
|
|
1991
2005
|
event = 'sanitization',
|
|
1992
2006
|
riskLevel = 'LOW EXPOSURE',
|
package/index.js
CHANGED
|
@@ -240,7 +240,7 @@ export const buildCisoAuditTelemetry = buildAuditTelemetry;
|
|
|
240
240
|
export function formatAuditReceipt(telemetry) {
|
|
241
241
|
if (!telemetry || telemetry.totalCount === 0) {
|
|
242
242
|
return "> 🛡️ **PrivacyScrubber Audit Receipt**: CLEAN (ZERO PII DETECTED)\n" +
|
|
243
|
-
"> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing)\n";
|
|
243
|
+
"> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **7-Day B2B Trial:** `npx @privacyscrubber/sdk trial` | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=audit_receipt)\n";
|
|
244
244
|
}
|
|
245
245
|
const entitiesList = Object.entries(telemetry.entities)
|
|
246
246
|
.map(([type, count]) => `${count} ${type}`)
|
|
@@ -252,7 +252,7 @@ export function formatAuditReceipt(telemetry) {
|
|
|
252
252
|
`> * **Risk Level:** ${icon} ${telemetry.riskLevel}\n` +
|
|
253
253
|
`> * **Framework References (informational):** ${telemetry.frameworksList.join(', ')}\n` +
|
|
254
254
|
`> * **Tokens Masked:** ${telemetry.totalCount} (${entitiesList})\n` +
|
|
255
|
-
`> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing)\n`;
|
|
255
|
+
`> * ⭐ **Star on GitHub:** [moxno/privacyscrubber-mcp](https://github.com/moxno/privacyscrubber-mcp) | **7-Day B2B Trial:** \`npx @privacyscrubber/sdk trial\` | **SDK & Enterprise:** [privacyscrubber.com/pricing](https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=audit_receipt)\n`;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
let communityNoticeLogged = false;
|
|
@@ -261,7 +261,7 @@ function emitCommunityNoticeIfNeeded(isPro) {
|
|
|
261
261
|
if (communityNoticeLogged || isPro) return;
|
|
262
262
|
if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
|
|
263
263
|
communityNoticeLogged = true;
|
|
264
|
-
console.info('[@privacyscrubber/sdk] Running Community Edition (Core PII).\nTo unlock
|
|
264
|
+
console.info('[@privacyscrubber/sdk] Running Community Edition (Core PII).\nTo unlock 30 Enterprise Profiles & DevOps Secrets in production: https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=prod_notice (7-Day Trial: npx @privacyscrubber/sdk trial | CISO Memo: npx @privacyscrubber/sdk memo)');
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -293,7 +293,8 @@ function emitDevSecretNoticeIfNeeded(isPro, tokenMap = {}, limit = 15000) {
|
|
|
293
293
|
process.stderr.write(
|
|
294
294
|
`\n[PrivacyScrubber] Intercepted ${count} API secret(s) before LLM egress: ${secretSample}\n` +
|
|
295
295
|
`[PrivacyScrubber] Protected in local RAM (0 byte network egress). Free Tier active (${limit.toLocaleString()} char cap).\n` +
|
|
296
|
-
`[PrivacyScrubber] Developer SDK ($299/mo flat) for unlimited backend nodes, CI/CD gates & ETL pipelines: https://privacyscrubber.com/pricing?tier=sdk&src=cli_leak_guard\n
|
|
296
|
+
`[PrivacyScrubber] Developer SDK ($299/mo flat) for unlimited backend nodes, CI/CD gates & ETL pipelines: https://privacyscrubber.com/pricing?tier=sdk&src=cli_leak_guard\n` +
|
|
297
|
+
`[PrivacyScrubber] Instant 7-Day Free B2B Trial: npx @privacyscrubber/sdk trial | CISO Approval Memo: npx @privacyscrubber/sdk memo\n\n`
|
|
297
298
|
);
|
|
298
299
|
}
|
|
299
300
|
}
|
|
@@ -480,6 +481,18 @@ export function sanitize(text, options = {}) {
|
|
|
480
481
|
|
|
481
482
|
const licenseCheck = validateLicense(licenseKey);
|
|
482
483
|
const rawTier = licenseCheck.valid ? (licenseCheck.tier || 'PRO') : 'FREE';
|
|
484
|
+
const isExpiredKey = !licenseCheck.valid && typeof licenseCheck.error === 'string' && /expired/i.test(licenseCheck.error);
|
|
485
|
+
const isExpiringSoon = licenseCheck.valid && typeof licenseCheck.expires === 'number' && (licenseCheck.expires - Date.now() <= 48 * 3600 * 1000);
|
|
486
|
+
|
|
487
|
+
if (isExpiringSoon && typeof process !== 'undefined' && process.stderr && !globalThis.__psSdkPreExpiryLogged) {
|
|
488
|
+
globalThis.__psSdkPreExpiryLogged = true;
|
|
489
|
+
const hrs = Math.max(0, Math.round((licenseCheck.expires - Date.now()) / 3600000));
|
|
490
|
+
process.stderr.write(
|
|
491
|
+
`\n[@privacyscrubber/sdk] ⏳ 7-Day Evaluation Key expires in ~${hrs}h. Prevent pipeline interruption:\n` +
|
|
492
|
+
` - Commercial SDK ($299/mo flat): https://privacyscrubber.com/pricing/?tier=sdk&utm_source=npm_sdk&utm_medium=pilot_expiring_48h\n` +
|
|
493
|
+
` - CISO Approval Memo: npx @privacyscrubber/sdk memo\n\n`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
483
496
|
|
|
484
497
|
// Anti-Cannibalization Barrier (SSOT):
|
|
485
498
|
// PRO ($15/mo) and TEAMS ($99/mo) licenses are strictly human-seat licenses for Web App & Chrome Extension.
|
|
@@ -513,7 +526,8 @@ export function sanitize(text, options = {}) {
|
|
|
513
526
|
|
|
514
527
|
if (!isPro && text.length > limit) {
|
|
515
528
|
if (shouldThrow) {
|
|
516
|
-
const
|
|
529
|
+
const expiredPrefix = isExpiredKey ? `[PILOT/TRIAL EXPIRED: ${licenseCheck.error}] ` : '';
|
|
530
|
+
const errorMsg = `[PrivacyScrubber] ${expiredPrefix}Free Tier character limit exceeded (${limit.toLocaleString()} chars for profile '${profile}', received ${text.length.toLocaleString()} chars). Upgrade to Developer SDK ($299/mo) for unlimited throughput: https://privacyscrubber.com/pricing?tier=sdk&src=${isExpiredKey ? 'pilot_expired' : 'dev_limit'} (Run 'npx @privacyscrubber/sdk memo' for CISO approval memo)`;
|
|
517
531
|
throw new PrivacyScrubberLicenseError(errorMsg, {
|
|
518
532
|
tier: 'FREE',
|
|
519
533
|
currentLength: text.length,
|
|
@@ -1919,7 +1933,7 @@ export function formatCefEvent(eventData = {}) {
|
|
|
1919
1933
|
const {
|
|
1920
1934
|
vendor = 'PrivacyScrubber',
|
|
1921
1935
|
product = 'ZTDS',
|
|
1922
|
-
version = '2.4.
|
|
1936
|
+
version = '2.4.2',
|
|
1923
1937
|
eventClassId = 'PII_REDACTION',
|
|
1924
1938
|
eventName = 'Zero-Trust PII Sanitization Executed',
|
|
1925
1939
|
riskLevel = 'LOW EXPOSURE',
|
|
@@ -1988,7 +2002,7 @@ export function formatSyslogEvent(eventData = {}) {
|
|
|
1988
2002
|
export function formatJsonlEvent(eventData = {}) {
|
|
1989
2003
|
const {
|
|
1990
2004
|
timestamp = new Date().toISOString(),
|
|
1991
|
-
version = '2.4.
|
|
2005
|
+
version = '2.4.2',
|
|
1992
2006
|
protocol = 'ZTDS',
|
|
1993
2007
|
event = 'sanitization',
|
|
1994
2008
|
riskLevel = 'LOW EXPOSURE',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@privacyscrubber/sdk",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "In-process consumer privacy defense and pre-emptive PII interception SDK for Node.js, Next.js, and AI pipelines. Zero data loss, zero third parties, sub-millisecond in-memory execution.",
|
|
5
5
|
"main": "index.cjs",
|
|
6
6
|
"module": "index.js",
|
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
"type": "git",
|
|
102
102
|
"url": "git+https://github.com/moxno/privacyscrubber-mcp.git"
|
|
103
103
|
},
|
|
104
|
+
"funding": {
|
|
105
|
+
"type": "github",
|
|
106
|
+
"url": "https://github.com/moxno/privacyscrubber-mcp"
|
|
107
|
+
},
|
|
104
108
|
"engines": {
|
|
105
109
|
"node": ">=18.0.0"
|
|
106
110
|
}
|