Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
# OpenSpec Change: enterprise-data-masking
- **Change ID**: enterprise-data-masking
- **Package**: `@suaveplan/data-masking`
- **Category**: universal
- **Target path**: `universal/data/data-masking`
- **Status**: PROPOSED
- **Date**: 2026-04-19
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/data-masking.md`
## Summary
Greenfield rebuild of `@suaveplan/data-masking` — structured PII masking with type detection, pattern-based redaction, conditional role/field-permission masking, strategy library (`hash`, `partial`, `redact`, `maskEmail`, `maskPhone`, `maskIp`, `maskCreditCard`), pluggable `MaskingRegistry`, and an `AuditEntry` trail.
## Current-state audit (genesis)
Package does not exist yet — fresh build.
## Dependencies
- Workspace: `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/types`
- External (via catalog): `zod`, `tslib`, `@opentelemetry/api`
- Dev (via catalog): `vitest`, `@vitest/coverage-istanbul`, `fast-check`, `mitata`
## Preserved public surface
### Masker / registry
- `DataMasker`, `MaskingRegistry`, `RegistryErrorCode`
- Strategies: `hash`, `maskCreditCard`, `maskEmail`, `maskIp`, `maskPhone`, `partial`, `redact`
### Patterns
- `PatternMasker`, `PatternMaskerOptions`, `PatternMatch`, `PatternRule`
### Detection
- `TypeDetector`, `DetectionOptions`, `DetectionResult`, `SensitiveDataType`
### Rules
- `ConditionalMasker`, `ConditionalMaskResult`, `FieldPermission`, `MaskingContext`, `MaskingPolicy`, `MaskingRole`
### Audit
- `MaskingAudit`, `AuditEntry`, `AuditFilter`, `AuditOptions`, `AuditSink`
### Error codes
- `DataMaskingErrorCode`, `DATA_MASKING_ERROR_METADATA`, `registerDataMaskingErrorCodes`
### Hooks / types
- `DataMaskingHandler`, `MaskingHookData`, `MaskingHookMap`
- `MaskingConfig`, `MaskingOptions`, `MaskingRule`, `MaskingStrategy`, `MaskResult`
## New genesis additions
- Additional codes: `DATA_MASKING.INVALID_POLICY`, `DATA_MASKING.UNKNOWN_STRATEGY`, `DATA_MASKING.AUDIT_SINK_FAILED`.
- Zod schemas for every config type.
- OTel counter `data_masking.masked.total{type}`, histogram `data_masking.mask.duration_ms`.
- Property tests: idempotency (mask twice = mask once), never-leak property on PII patterns.
## Impact
- Adds one new package: `universal/data/data-masking`
- Adds one new spec capability: `data-masking`

View File

@@ -0,0 +1,41 @@
# Capability Spec: data-masking
**Package**: `@suaveplan/data-masking`
**Version**: 0.0.0 (genesis)
**Status**: ADDED
---
## ADDED Requirements
### DM-01 — Strategy contract
Every `MaskingStrategy` MUST expose `{ name, mask(value, options?): MaskResult }`. Built-in strategies `hash`, `partial`, `redact`, `maskEmail`, `maskPhone`, `maskIp`, `maskCreditCard` MUST all implement this contract.
### DM-02 — Registry
`MaskingRegistry.register(name, strategy)` MUST reject duplicates unless `overwrite: true`. `MaskingRegistry.resolve(name)` MUST throw `DATA_MASKING.UNKNOWN_STRATEGY` when the name is absent.
### DM-03 — Idempotency
`DataMasker.mask` MUST be idempotent: `mask(mask(x)) === mask(x)` (structural equality) for every built-in strategy on PII inputs.
### DM-04 — Type detection
`TypeDetector.detect(value)` MUST return an array of `DetectionResult { type, start, end, confidence }`. Built-in `SensitiveDataType` values MUST include `email`, `phone`, `credit-card`, `ssn`, `ipv4`, `ipv6`, `jwt`, `api-key`.
### DM-05 — Conditional masking
`ConditionalMasker.apply(value, ctx)` MUST evaluate the `MaskingPolicy` with `MaskingContext { role, permissions: FieldPermission[] }`. Policies MUST either mask, allow, or redact per-field. Unknown policies MUST surface as `DATA_MASKING.INVALID_POLICY`.
### DM-06 — Audit trail
`MaskingAudit.record(entry)` MUST write `AuditEntry { at, actor?, field, strategy, outcome }` to every registered `AuditSink`. Sink failures MUST be captured and surfaced as `DATA_MASKING.AUDIT_SINK_FAILED` without aborting the mask itself.
### DM-07 — Credit-card mask
`maskCreditCard` MUST preserve the last 4 digits and validate Luhn; non-Luhn inputs MUST pass through unchanged (they're not actually credit cards) and record a lower-confidence detection result.
### DM-08 — Observability
Every mask call MUST record `data_masking.mask.duration_ms` histogram and `data_masking.masked.total{type}` counter. Masked values MUST NOT appear in OTel attributes.

View File

@@ -0,0 +1,49 @@
# Tasks: enterprise-data-masking
## 1. Scaffold
- [x] 1.1 `universal/data/data-masking/`; 100/100/100/100; guard tests; CLAUDE/README/FOLDERS.
## 2. Errors + schemas
- [x] 2.1 `src/error-codes.ts` + side-effect register.
- [x] 2.2 Zod schemas for `MaskingConfig`, `MaskingRule`, `MaskingPolicy`, `AuditEntry`.
## 3. Strategies
- [x] 3.1 `src/strategies/strategies.ts` — `hash` (HMAC-SHA256), `partial`, `redact`, `maskEmail`, `maskPhone`, `maskIp`, `maskCreditCard` (Luhn-aware).
## 4. Detection
- [x] 4.1 `src/detection/type-detector.ts` — `TypeDetector` with built-in `SensitiveDataType` patterns.
## 5. Patterns
- [x] 5.1 `src/patterns/pattern-masker.ts`.
## 6. Registry
- [x] 6.1 `src/registry/registry.ts` — `MaskingRegistry` + registry error codes.
## 7. Conditional rules
- [x] 7.1 `src/rules/conditional-masker.ts` — role + field permissions.
## 8. Masker façade
- [x] 8.1 `src/masker/masker.ts` — `DataMasker` orchestrator; OTel instrumentation.
- [x] 8.2 `src/types/masking-hooks.ts` — hook surface.
## 9. Audit
- [x] 9.1 `src/audit/masking-audit.ts` — `MaskingAudit`, `AuditSink` interface, filter helpers.
## 10. Docs / barrel / subpath exports / README
## 11. Benchmarks
- [x] 11.1 `mask.bench.ts` on 10 k-record JSON trees.
## 12. Ship gate
- [x] 12.1 Verification sequence; fold + archive.