shadow-vault 0.3.0__tar.gz
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.
- shadow_vault-0.3.0/.github/ISSUE_TEMPLATE/01_add_brazilian_cpf.md +37 -0
- shadow_vault-0.3.0/.github/ISSUE_TEMPLATE/02_add_uk_nino.md +40 -0
- shadow_vault-0.3.0/.github/ISSUE_TEMPLATE/03_add_eu_iban.md +44 -0
- shadow_vault-0.3.0/.github/ISSUE_TEMPLATE/config.yml +9 -0
- shadow_vault-0.3.0/.github/workflows/ci.yml +40 -0
- shadow_vault-0.3.0/.github/workflows/publish.yml +42 -0
- shadow_vault-0.3.0/.gitignore +15 -0
- shadow_vault-0.3.0/CONTRIBUTING.md +175 -0
- shadow_vault-0.3.0/LICENSE +21 -0
- shadow_vault-0.3.0/PKG-INFO +305 -0
- shadow_vault-0.3.0/README.md +262 -0
- shadow_vault-0.3.0/benchmarks/benchmark_results.md +26 -0
- shadow_vault-0.3.0/benchmarks/run_benchmarks.py +322 -0
- shadow_vault-0.3.0/examples/demo_agent_roundtrip.py +249 -0
- shadow_vault-0.3.0/pyproject.toml +84 -0
- shadow_vault-0.3.0/shadow_vault/__init__.py +75 -0
- shadow_vault-0.3.0/shadow_vault/detectors.py +490 -0
- shadow_vault-0.3.0/shadow_vault/engine.py +217 -0
- shadow_vault-0.3.0/shadow_vault/integrations/__init__.py +21 -0
- shadow_vault-0.3.0/shadow_vault/integrations/decorators.py +92 -0
- shadow_vault-0.3.0/shadow_vault/integrations/langchain.py +291 -0
- shadow_vault-0.3.0/shadow_vault/integrations/mcp_proxy.py +131 -0
- shadow_vault-0.3.0/shadow_vault/integrations/proxy_server.py +162 -0
- shadow_vault-0.3.0/shadow_vault/store.py +342 -0
- shadow_vault-0.3.0/shadow_vault/stream.py +120 -0
- shadow_vault-0.3.0/shadow_vault/synthesizer.py +140 -0
- shadow_vault-0.3.0/tests/__init__.py +1 -0
- shadow_vault-0.3.0/tests/test_decorators.py +84 -0
- shadow_vault-0.3.0/tests/test_detectors.py +303 -0
- shadow_vault-0.3.0/tests/test_engine.py +186 -0
- shadow_vault-0.3.0/tests/test_langchain.py +272 -0
- shadow_vault-0.3.0/tests/test_mcp_proxy.py +134 -0
- shadow_vault-0.3.0/tests/test_proxy_server.py +182 -0
- shadow_vault-0.3.0/tests/test_shadow_vault.py +310 -0
- shadow_vault-0.3.0/tests/test_store.py +268 -0
- shadow_vault-0.3.0/tests/test_stream.py +137 -0
- shadow_vault-0.3.0/tests/test_synthesizer.py +110 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "[Good First Issue] Add Brazilian CPF Detector"
|
|
3
|
+
about: Add a regional detector for Brazilian CPF (Cadastro de Pessoas Físicas) with Modulo 11 checksum validation.
|
|
4
|
+
title: "[Detector Request]: Add Brazilian CPF Detector (Modulo 11)"
|
|
5
|
+
labels: ["enhancement", "good first issue", "detectors", "help wanted"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
Add support for detecting and de-identifying **Brazilian CPF** (Cadastro de Pessoas Físicas) numbers using regex matching paired with official **Modulo 11** dual check-digit verification.
|
|
11
|
+
|
|
12
|
+
## Background & Specifications
|
|
13
|
+
- **Format**: 11 digits, commonly formatted as `XXX.XXX.XXX-XX` (e.g., `123.456.789-09`) or raw 11 digits `XXXXXXXXXXX`.
|
|
14
|
+
- **Validation Algorithm**:
|
|
15
|
+
1. CPF cannot consist of 11 identical digits (e.g., `111.111.111-11` is invalid).
|
|
16
|
+
2. First check digit (10th digit): `sum(d[i] * (10 - i) for i in range(9)) * 10 % 11` (if 10, check digit is 0).
|
|
17
|
+
3. Second check digit (11th digit): `sum(d[i] * (11 - i) for i in range(10)) * 10 % 11` (if 10, check digit is 0).
|
|
18
|
+
- **Synthetic Token Format**:
|
|
19
|
+
- Must preserve format: `f"999.888.{num:03d}-{check:02d}"` or deterministic synthetic pattern that passes format checkers and is recognized by `StreamHydrator`.
|
|
20
|
+
|
|
21
|
+
## Implementation Checklist
|
|
22
|
+
- [ ] Add `EntityType.CPF = "CPF"` to `shadow_vault/detectors.py`
|
|
23
|
+
- [ ] Implement `is_cpf_valid(cpf_str: str) -> bool` using Modulo 11
|
|
24
|
+
- [ ] Implement `detect_cpf(text: str) -> list[PIIEntity]` with compiled regex
|
|
25
|
+
- [ ] Register `detect_cpf` inside `detect_entities()`
|
|
26
|
+
- [ ] Implement synthetic token generation for `EntityType.CPF` in `shadow_vault/synthesizer.py`
|
|
27
|
+
- [ ] Add unit tests in `tests/test_detectors.py`:
|
|
28
|
+
- Valid CPF with dots and dash
|
|
29
|
+
- Valid unformatted CPF (11 digits)
|
|
30
|
+
- Invalid check digits (must be rejected)
|
|
31
|
+
- All identical digits (e.g. `000.000.000-00`, must be rejected)
|
|
32
|
+
- Round-trip `dehydrate()` and `hydrate()` test
|
|
33
|
+
- [ ] Verify test suite passes: `pytest -v`
|
|
34
|
+
|
|
35
|
+
## Reference Code
|
|
36
|
+
See [CONTRIBUTING.md](https://github.com/dhirajparihar/shadow-vault/blob/main/CONTRIBUTING.md) for a complete reference implementation in under 20 lines of code!
|
|
37
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "[Good First Issue] Add UK National Insurance Number (NINO) Detector"
|
|
3
|
+
about: Add a regional detector for UK National Insurance Numbers (NINO) with strict prefix and suffix validation.
|
|
4
|
+
title: "[Detector Request]: Add UK National Insurance Number (NINO) Detector"
|
|
5
|
+
labels: ["enhancement", "good first issue", "detectors", "help wanted"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
Add support for detecting and de-identifying **UK National Insurance Numbers (NINO)** used in the United Kingdom for taxation, social security, and national healthcare administration.
|
|
11
|
+
|
|
12
|
+
## Background & Specifications
|
|
13
|
+
- **Format**: 9 characters consisting of 2 prefix letters, 6 digits, and 1 suffix letter (e.g., `QQ 12 34 56 A` or `QQ123456A`).
|
|
14
|
+
- **Official HMRC Formatting Rules**:
|
|
15
|
+
1. **First letter**: Any letter except `D`, `F`, `I`, `Q`, `U`, `V`.
|
|
16
|
+
2. **Second letter**: Any letter except `D`, `F`, `I`, `O`, `Q`, `U`, `V`.
|
|
17
|
+
3. **Disallowed prefixes**: Combinations `BG`, `GB`, `KN`, `NK`, `NT`, `TN`, `ZZ` are administrative or reserved and not valid citizen NINOs.
|
|
18
|
+
4. **Middle 6 characters**: Digits `0-9`.
|
|
19
|
+
5. **Suffix letter**: Must be `A`, `B`, `C`, `D` (or space in legacy records).
|
|
20
|
+
- **Synthetic Token Format**:
|
|
21
|
+
- Must preserve format: e.g., `f"SH {short_hash_digits:06d} Z"` or `f"SV{d6}A"`.
|
|
22
|
+
|
|
23
|
+
## Implementation Checklist
|
|
24
|
+
- [ ] Add `EntityType.UK_NINO = "UK_NINO"` to `shadow_vault/detectors.py`
|
|
25
|
+
- [ ] Implement `is_uk_nino_valid(nino_str: str) -> bool` checking HMRC character rules
|
|
26
|
+
- [ ] Implement `detect_uk_nino(text: str) -> list[PIIEntity]` with compiled regex
|
|
27
|
+
- [ ] Register `detect_uk_nino` inside `detect_entities()`
|
|
28
|
+
- [ ] Implement format-preserving synthetic token generation in `shadow_vault/synthesizer.py`
|
|
29
|
+
- [ ] Add unit tests in `tests/test_detectors.py`:
|
|
30
|
+
- Valid NINO with spaces: `"QQ 12 34 56 A"`
|
|
31
|
+
- Valid NINO without spaces: `"AB123456C"`
|
|
32
|
+
- Invalid prefix characters (e.g. starting with `D` or `F`)
|
|
33
|
+
- Disallowed combination (e.g. starting with `GB` or `ZZ`)
|
|
34
|
+
- Invalid suffix letter (e.g. ending in `X` or `Z`)
|
|
35
|
+
- Round-trip `dehydrate()` and `hydrate()` test
|
|
36
|
+
- [ ] Verify test suite passes: `pytest -v`
|
|
37
|
+
|
|
38
|
+
## Reference Code
|
|
39
|
+
See [CONTRIBUTING.md](https://github.com/dhirajparihar/shadow-vault/blob/main/CONTRIBUTING.md) for how to add a regional detector in under 20 lines of code!
|
|
40
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "[Good First Issue] Add EU / International IBAN Detector"
|
|
3
|
+
about: Add a detector for International Bank Account Numbers (IBAN) with ISO 7064 MOD-97 checksum validation.
|
|
4
|
+
title: "[Detector Request]: Add EU / International IBAN Detector (MOD-97)"
|
|
5
|
+
labels: ["enhancement", "good first issue", "detectors", "help wanted"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
Add support for detecting and de-identifying **International Bank Account Numbers (IBAN)** across European and global financial systems using regex pattern matching verified by the official **ISO 7064 MOD 97-10** checksum algorithm.
|
|
11
|
+
|
|
12
|
+
## Background & Specifications
|
|
13
|
+
- **Format**: Up to 34 alphanumeric characters (standard EU IBANs are typically 15–31 characters, e.g., Germany `DE89 3704 0044 0532 0130 00`, France `FR14 2004 1010 0505 0001 3M02 606`).
|
|
14
|
+
- **Structure**:
|
|
15
|
+
1. 2-letter ISO 3166-1 country code (e.g., `DE`, `FR`, `GB`, `ES`, `IT`).
|
|
16
|
+
2. 2 check digits (values `02` through `98`).
|
|
17
|
+
3. Up to 30 alphanumeric Basic Bank Account Number (BBAN) characters.
|
|
18
|
+
- **Validation Algorithm (ISO 7064 MOD 97-10)**:
|
|
19
|
+
1. Remove spaces and convert to uppercase.
|
|
20
|
+
2. Move the first 4 characters (country code + 2 check digits) to the end of the string.
|
|
21
|
+
3. Replace each letter with two digits (`A` -> `10`, `B` -> `11`, ..., `Z` -> `35`).
|
|
22
|
+
4. Interpret the string as a decimal integer: compute `int(digits) % 97`.
|
|
23
|
+
5. The IBAN is valid if and only if `remainder == 1`.
|
|
24
|
+
- **Synthetic Token Format**:
|
|
25
|
+
- Must preserve format: e.g. `f"DE99SHDW{short_hash[:10]}00"` with valid ISO MOD-97 check digits so banking APIs accept it.
|
|
26
|
+
|
|
27
|
+
## Implementation Checklist
|
|
28
|
+
- [ ] Add `EntityType.IBAN = "IBAN"` to `shadow_vault/detectors.py`
|
|
29
|
+
- [ ] Implement `is_iban_valid(iban_str: str) -> bool` using the ISO 7064 MOD 97-10 algorithm
|
|
30
|
+
- [ ] Implement `detect_iban(text: str) -> list[PIIEntity]` with compiled regex and length validation
|
|
31
|
+
- [ ] Register `detect_iban` inside `detect_entities()`
|
|
32
|
+
- [ ] Implement format-preserving synthetic token generation in `shadow_vault/synthesizer.py`
|
|
33
|
+
- [ ] Add unit tests in `tests/test_detectors.py`:
|
|
34
|
+
- Valid German IBAN with spaces
|
|
35
|
+
- Valid French IBAN without spaces
|
|
36
|
+
- Valid British IBAN
|
|
37
|
+
- Corrupted check digits (must be rejected)
|
|
38
|
+
- Non-IBAN alphanumeric strings (must not produce false positives)
|
|
39
|
+
- Round-trip `dehydrate()` and `hydrate()` test
|
|
40
|
+
- [ ] Verify test suite passes: `pytest -v`
|
|
41
|
+
|
|
42
|
+
## Reference Code
|
|
43
|
+
See [CONTRIBUTING.md](https://github.com/dhirajparihar/shadow-vault/blob/main/CONTRIBUTING.md) for how to add a regional detector in under 20 lines of code!
|
|
44
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Shadow Vault Documentation & Contributing Guide
|
|
4
|
+
url: https://github.com/dhirajparihar/shadow-vault/blob/main/CONTRIBUTING.md
|
|
5
|
+
about: Read our guide on how to add a regional PII detector in under 20 lines of code.
|
|
6
|
+
- name: Benchmark & Performance Inquiries
|
|
7
|
+
url: https://github.com/dhirajparihar/shadow-vault/blob/main/benchmarks/benchmark_results.md
|
|
8
|
+
about: View latency, throughput, and memory footprint benchmarks.
|
|
9
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
os: [ubuntu-latest]
|
|
17
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python-version }}
|
|
27
|
+
cache: "pip"
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: |
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python -m pip install -e ".[all]"
|
|
33
|
+
|
|
34
|
+
- name: Run test suite with pytest
|
|
35
|
+
run: |
|
|
36
|
+
pytest -v
|
|
37
|
+
|
|
38
|
+
- name: Verify CLI demo execution
|
|
39
|
+
run: |
|
|
40
|
+
python examples/demo_agent_roundtrip.py
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build-and-publish:
|
|
12
|
+
name: Build distribution and publish to PyPI
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment:
|
|
15
|
+
name: pypi
|
|
16
|
+
url: https://pypi.org/p/shadow-vault
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write # Mandatory for PyPI Trusted Publishing (OIDC)
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout source code
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
|
|
30
|
+
- name: Install build tools
|
|
31
|
+
run: |
|
|
32
|
+
python -m pip install --upgrade pip
|
|
33
|
+
python -m pip install build
|
|
34
|
+
|
|
35
|
+
- name: Build sdist and wheel
|
|
36
|
+
run: |
|
|
37
|
+
python -m build
|
|
38
|
+
|
|
39
|
+
- name: Publish package distributions to PyPI
|
|
40
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
41
|
+
with:
|
|
42
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Contributing to Shadow Vault
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to **Shadow Vault**! We are building an open-source, ultra-low-latency, format-preserving PII de-identification and re-hydration engine for AI agents, LangChain/LangGraph, and MCP tools.
|
|
4
|
+
|
|
5
|
+
Whether you are fixing a bug, improving test coverage, or adding support for your country's national identity numbers, your contributions are welcome.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Code of Conduct & Philosophy
|
|
10
|
+
|
|
11
|
+
Shadow Vault adheres to these engineering tenets:
|
|
12
|
+
1. **Zero External Machine Learning / Torch Dependencies in Core**: Detection must be fast, deterministic, and lightweight (< 1ms execution). We rely on compiled regular expressions and mathematical check-digit algorithms (e.g., Luhn, Verhoeff, Modulo 11).
|
|
13
|
+
2. **Format-Preserving Realism**: Synthetic replacement tokens must look structurally indistinguishable from real data so downstream Pydantic schemas, regexes, and database columns do not break.
|
|
14
|
+
3. **Deterministic & Reversible**: Every token must be coreference-consistent within a session and fully reversible when tools need real data.
|
|
15
|
+
4. **Zero Placeholders**: All contributed code must be fully tested, production-ready, and accompanied by comprehensive unit tests.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Local Development Setup
|
|
20
|
+
|
|
21
|
+
Shadow Vault requires **Python 3.10+**.
|
|
22
|
+
|
|
23
|
+
### 1. Clone & Set Up Virtual Environment
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Clone the repository
|
|
27
|
+
git clone https://github.com/dhirajparihar/shadow-vault.git
|
|
28
|
+
cd shadow-vault
|
|
29
|
+
|
|
30
|
+
# Create and activate a virtual environment
|
|
31
|
+
python -m venv .venv
|
|
32
|
+
|
|
33
|
+
# On Linux/macOS:
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
# On Windows PowerShell:
|
|
36
|
+
.venv\Scripts\Activate.ps1
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Install Development Dependencies
|
|
40
|
+
|
|
41
|
+
Install the package in editable mode with all development, testing, and framework integration dependencies:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install -e ".[all]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Run the Test Suite & Benchmarks
|
|
48
|
+
|
|
49
|
+
Make sure all tests pass before making any changes:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Run full pytest suite
|
|
53
|
+
pytest -v
|
|
54
|
+
|
|
55
|
+
# Run the CLI interactive demo
|
|
56
|
+
python examples/demo_agent_roundtrip.py
|
|
57
|
+
|
|
58
|
+
# Run the latency and memory benchmark suite
|
|
59
|
+
python benchmarks/run_benchmarks.py
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Adding a New Regional PII Detector in Under 20 Lines
|
|
65
|
+
|
|
66
|
+
Shadow Vault is designed to be easily extensible. You can add a new regional identity detector (such as **Brazilian CPF**, **UK National Insurance Number**, or **EU IBAN**) in under 20 lines of code.
|
|
67
|
+
|
|
68
|
+
Here is the complete step-by-step walkthrough.
|
|
69
|
+
|
|
70
|
+
### The 4-Step Process
|
|
71
|
+
|
|
72
|
+
1. **Register the Entity Type** in `shadow_vault/detectors.py`:
|
|
73
|
+
Add your new type to `EntityType` enum:
|
|
74
|
+
```python
|
|
75
|
+
class EntityType(str, Enum):
|
|
76
|
+
...
|
|
77
|
+
CPF = "CPF"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
2. **Add Checksum & Regex Detection** in `shadow_vault/detectors.py`:
|
|
81
|
+
Write the mathematical check function and detector.
|
|
82
|
+
|
|
83
|
+
3. **Add Format-Preserving Synthesis** in `shadow_vault/synthesizer.py`:
|
|
84
|
+
Add a branch in `synthesize_token()` so synthetic tokens mirror the real regional format.
|
|
85
|
+
|
|
86
|
+
4. **Register in `detect_entities()`** and **Write Tests**:
|
|
87
|
+
Call your detector in `detect_entities()` and add test cases in `tests/test_detectors.py`.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### Complete Example: Brazilian CPF Detector (< 20 Lines)
|
|
92
|
+
|
|
93
|
+
Here is the exact code needed to implement Brazilian CPF (Cadastro de Pessoas Físicas) with official Modulo 11 check-digit verification:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
# In shadow_vault/detectors.py (~18 lines of code)
|
|
97
|
+
import re
|
|
98
|
+
|
|
99
|
+
CPF_REGEX = re.compile(r"\b(?:\d{3}\.\d{3}\.\d{3}-\d{2}|\d{11})\b")
|
|
100
|
+
|
|
101
|
+
def is_cpf_valid(cpf_str: str) -> bool:
|
|
102
|
+
digits = [int(d) for d in re.sub(r"\D", "", cpf_str)]
|
|
103
|
+
if len(digits) != 11 or len(set(digits)) == 1:
|
|
104
|
+
return False
|
|
105
|
+
for i in (9, 10):
|
|
106
|
+
val = sum(digits[j] * ((i + 1) - j) for j in range(i)) % 11
|
|
107
|
+
check = 0 if val < 2 else 11 - val
|
|
108
|
+
if digits[i] != check:
|
|
109
|
+
return False
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
def detect_cpf(text: str) -> list[PIIEntity]:
|
|
113
|
+
return [
|
|
114
|
+
PIIEntity(EntityType.CPF, m.group(0), m.start(), m.end())
|
|
115
|
+
for m in CPF_REGEX.finditer(text)
|
|
116
|
+
if is_cpf_valid(m.group(0))
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Adding Format-Preserving Synthesis (~4 lines)
|
|
121
|
+
|
|
122
|
+
In `shadow_vault/synthesizer.py`, add your format pattern:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
elif entity_type == EntityType.CPF:
|
|
126
|
+
# Produce format-preserving synthetic CPF with valid Modulo 11 check digits:
|
|
127
|
+
# e.g., "999.888.{short_hash[:3]}-{check_digits}"
|
|
128
|
+
return f"999.888.{int(short_hash[:3], 16) % 900 + 100:03d}-00"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Unit Testing Requirements
|
|
134
|
+
|
|
135
|
+
Every new detector **must** include:
|
|
136
|
+
1. **Valid Test Cases**: Known-valid numbers/identifiers with formatting variations (e.g., formatted with dots/dashes vs. unformatted raw digits).
|
|
137
|
+
2. **Invalid Checksum Rejection**: Test that numbers with mutated check digits are rejected.
|
|
138
|
+
3. **Repeated Digit Rejection**: Many national IDs reject sequences like `111.111.111-11`.
|
|
139
|
+
4. **False Positive Guard**: Verify that unrelated numbers (order IDs, tracking numbers) are not detected.
|
|
140
|
+
5. **Round-Trip Test**: Verify `dehydrate()` -> `hydrate()` preserves the original value.
|
|
141
|
+
|
|
142
|
+
Run tests:
|
|
143
|
+
```bash
|
|
144
|
+
pytest tests/test_detectors.py -v
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Pull Request Guidelines
|
|
150
|
+
|
|
151
|
+
1. **Branch Naming**: Use descriptive branch names:
|
|
152
|
+
- `feature/add-brazilian-cpf-detector`
|
|
153
|
+
- `feature/add-uk-nino-detector`
|
|
154
|
+
- `fix/phone-regex-edge-case`
|
|
155
|
+
2. **Commit Messages**: Write clear, descriptive commit messages:
|
|
156
|
+
- `feat(detectors): add Brazilian CPF detector with Modulo 11 validation`
|
|
157
|
+
- `test(detectors): add test suite for UK National Insurance Number`
|
|
158
|
+
3. **CI Passing**: Ensure GitHub Actions CI passes cleanly across Python 3.10, 3.11, 3.12, and 3.13.
|
|
159
|
+
4. **Code Quality**:
|
|
160
|
+
- Zero lint errors or typing warnings.
|
|
161
|
+
- Preserves 100% backward compatibility.
|
|
162
|
+
- No heavy ML or external runtime dependencies added to core.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Good First Issues
|
|
167
|
+
|
|
168
|
+
Looking for somewhere to start? Check our [Good First Issues](https://github.com/dhirajparihar/shadow-vault/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22):
|
|
169
|
+
- **Brazilian CPF Detector** with Modulo 11 Checksum
|
|
170
|
+
- **UK National Insurance Number (NINO)** Detector
|
|
171
|
+
- **EU / International IBAN** Detector with ISO 7064 MOD-97 Check
|
|
172
|
+
- **Australian Tax File Number (TFN)** with Modulo 11 Check
|
|
173
|
+
- **Canadian Social Insurance Number (SIN)** with Luhn Check
|
|
174
|
+
|
|
175
|
+
Thank you for helping keep AI agent applications private, secure, and compliant across the globe!
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shadow Vault Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|