🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@epilot/anonymization

Package Overview
Dependencies
Maintainers
49
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@epilot/anonymization - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+6
-0
dist/defaults.d.ts

@@ -27,2 +27,8 @@ import type { AnonymizationStrategy } from './types';

/**
* Per-key rules applied inside an embedded user object (the `user` strategy).
* Keys not listed are kept (ids, status, language, notification settings, timestamps).
* Matching is case-insensitive and also applies at any nesting depth.
*/
export declare const USER_FIELD_STRATEGY: Record<string, AnonymizationStrategy>;
/**
* Additional field-name heuristics used ONLY by the non-schema-aware mode

@@ -29,0 +35,0 @@ * (`anonymizeUnknown`) for arbitrary JSON such as audit logs or inbound integration events.

+35
-1
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SYSTEM_KEEP_KEYS = exports.PAYMENT_PSEUDONYMIZE_KEY_PATTERN = exports.ADDRESS_KEEP_KEYS = exports.UNKNOWN_FIELD_HEURISTICS = exports.DEFAULT_PII_FIELDS = exports.STRATEGY_BY_ATTRIBUTE_TYPE = exports.PSEUDONYM_EMAIL_DOMAIN = exports.REDACTED_PLACEHOLDER = void 0;
exports.SYSTEM_KEEP_KEYS = exports.PAYMENT_PSEUDONYMIZE_KEY_PATTERN = exports.ADDRESS_KEEP_KEYS = exports.UNKNOWN_FIELD_HEURISTICS = exports.USER_FIELD_STRATEGY = exports.DEFAULT_PII_FIELDS = exports.STRATEGY_BY_ATTRIBUTE_TYPE = exports.PSEUDONYM_EMAIL_DOMAIN = exports.REDACTED_PLACEHOLDER = void 0;
/**

@@ -24,2 +24,5 @@ * Curated classification defaults.

payment: 'payment',
// user-relation attributes embed full epilot user objects (name, email, and often an auth
// `token`) — never pass them through raw
relation_user: 'user',
};

@@ -62,4 +65,35 @@ /**

'thread:topic': 'redact',
// common user-relation attribute names — safety net for when the schema (and thus the
// `relation_user` type) is unavailable; type-based classification covers custom-named ones
'*:contact_owner': 'user',
'*:owner': 'user',
'*:assigned_to': 'user',
'*:agent': 'user',
};
/**
* Per-key rules applied inside an embedded user object (the `user` strategy).
* Keys not listed are kept (ids, status, language, notification settings, timestamps).
* Matching is case-insensitive and also applies at any nesting depth.
*/
exports.USER_FIELD_STRATEGY = {
email: 'email',
name: 'person',
display_name: 'person',
full_name: 'person',
first_name: 'person',
last_name: 'person',
given_name: 'person',
family_name: 'person',
phone: 'phone',
// credentials that must never appear in an anonymized response
token: 'redact',
access_token: 'redact',
refresh_token: 'redact',
api_key: 'redact',
apikey: 'redact',
secret: 'redact',
password: 'redact',
authorization: 'redact',
};
/**
* Additional field-name heuristics used ONLY by the non-schema-aware mode

@@ -66,0 +100,0 @@ * (`anonymizeUnknown`) for arbitrary JSON such as audit logs or inbound integration events.

@@ -94,2 +94,4 @@ "use strict";

return mapValue(value, (item) => anonymizePaymentItem(item, pseudonymizer));
case 'user':
return mapValue(value, (item) => anonymizeUserItem(item, pseudonymizer));
case 'date_year':

@@ -176,1 +178,32 @@ return (0, exports.mapStringLeaves)(value, (str) => pseudonymizer.dateToYear(str));

};
/**
* Anonymize an embedded epilot user object (user-relation attributes such as `contact_owner`).
* Pseudonymizes name/email fields and REDACTS credentials (`token`, `password`, `secret`, …),
* while keeping non-identifying operational metadata (ids, status, language, notification
* settings, timestamps). Rules are applied by key at every nesting depth.
*/
const anonymizeUserItem = (item, pseudonymizer) => {
if (typeof item === 'string') {
return pseudonymizer.person(item);
}
if (Array.isArray(item)) {
return item.map((i) => anonymizeUserItem(i, pseudonymizer));
}
if (!(0, utils_1.isPlainObject)(item)) {
return item;
}
return (0, utils_1.mapEntries)(item, (val, key) => {
if (defaults_1.SYSTEM_KEEP_KEYS.includes(key)) {
return val;
}
const strategy = defaults_1.USER_FIELD_STRATEGY[key.toLowerCase()];
if (strategy) {
return (0, exports.applyStrategy)({ value: val, strategy, pseudonymizer });
}
// recurse so a sensitive key nested deeper (e.g. token inside a settings object) is caught
if ((0, utils_1.isPlainObject)(val) || Array.isArray(val)) {
return anonymizeUserItem(val, pseudonymizer);
}
return val;
});
};

@@ -31,3 +31,9 @@ /**

/** scrub payment details: pseudonymize IBAN/holder identifiers, keep bank metadata */
| 'payment';
| 'payment'
/**
* anonymize an embedded epilot user object (user-relation attributes, e.g. `contact_owner`):
* pseudonymize name/email, redact credentials (`token`, `password`, `secret`), keep ids and
* operational metadata (status, language, notification settings)
*/
| 'user';
/** Data classification set on a schema attribute (`data_classification` in the Entity API) */

@@ -34,0 +40,0 @@ export type DataClassification = 'public' | 'pii';

+2
-2
{
"name": "@epilot/anonymization",
"version": "0.1.0",
"description": "Deterministic PII pseudonymization and redaction for epilot entity data and arbitrary JSON — data minimization for AI agents, analytics, logs and integrations",
"version": "0.1.1",
"description": "Deterministic PII pseudonymization and redaction for epilot entity data and arbitrary JSON \u2014 data minimization for AI agents, analytics, logs and integrations",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": "epilot GmbH",

@@ -174,2 +174,3 @@ # @epilot/anonymization

| Payment items | pseudonymize IBAN/holder; keep bank name / BIC |
| User-relation attributes (`relation_user`, e.g. `contact_owner`) | pseudonymize name/email, **redact credentials** (`token`, `password`, …), keep ids/status/settings |
| Curated free-text (note/message content, opportunity description, …) | `[REDACTED]` |

@@ -176,0 +177,0 @@ | `data_classification: 'pii'` fields | pseudonym (single-line) / `[REDACTED]` (multiline) |