Enterprise-Grade PII Redaction for Pydantic Models.
Project description
GhostPII 👻 (ghost-pii-pydantic)
Enterprise-Grade PII Redaction for Pydantic. Type-Safe, Invisible by Default.
GhostPII (published as ghost-pii-pydantic) solves the "Logged Secret" problem once and for all. It provides a smart string proxy that automatically redacts itself when accessed by unsafe contexts (logging, printing, tracebacks) but remains fully functional for your business logic, databases, and APIs.
Features
| Feature | Description |
|---|---|
| Auto-Magical Redaction | Automatically detects print() and logging calls to mask PII. |
| Pydantic Native | First-class support for Pydantic v2 Annotated types. |
| Strict Mode | Opt-in for 100% redaction everywhere unless explicitly unmasked. |
| Tainted Memory | Operations on PII (like concatenation) stay PII. No accidental leaks. |
| Context Aware | Use unmask_pii() context manager for explicit, safe data access. |
| Zero-Performance-Cost | Optimized stack inspection with fast-fail logic. |
Installation
pip install ghost-pii-pydantic
Quick Start
from pydantic import BaseModel, EmailStr
from ghost_pii import PII, unmask_pii
class User(BaseModel):
name: PII[str]
email: PII[EmailStr]
user = User(name="John Doe", email="john@example.com")
# 1. Safe by Default: Redacts in logs/prints
print(user)
# Output: name=GhostString('[REDACTED]') email=GhostString('[REDACTED]')
# 2. Functional: Works in business logic/DBs
# (Internal calls to user.email return the real string)
db.execute("INSERT INTO users VALUES (?)", [user.email])
# Successfully inserts "john@example.com"
# 3. Explicit: Use context manager for sensitive tasks
with unmask_pii():
print(user)
# Output: name=GhostString('John Doe') email=GhostString('john@example.com')
Advanced Scenarios
Nested Models and Collections
GhostPII seamlessly handles nested Pydantic models and lists of PII.
from typing import List
from ghost_pii import PII
class Address(BaseModel):
street: PII[str]
city: str
class Organization(BaseModel):
name: str
admin_emails: List[PII[EmailStr]]
headquarters: Address
org = Organization(
name="Acme Corp",
admin_emails=["admin@acme.com", "sec@acme.com"],
headquarters=Address(street="123 Secret Lane", city="New York")
)
print(org.model_dump())
# Output: {
# 'name': 'Acme Corp',
# 'admin_emails': ['[REDACTED]', '[REDACTED]'],
# 'headquarters': {'street': '[REDACTED]', 'city': 'New York'}
# }
Tainted Memory (Concatenation)
PII "infects" any string it touches. If you combine a PII field with a normal string, the result is a new GhostString that is also redacted by default.
labeled_name = "User: " + user.name
print(labeled_name) # Output: [REDACTED]
with unmask_pii():
print(labeled_name) # Output: User: John Doe
Enterprise Strategy
GhostPII is designed to adapt to different compliance levels:
| Mode | Recommended For | Mechanism |
|---|---|---|
| Auto-Magical | General microservices, high developer velocity. | Uses stack inspection to detect logging, print, etc. |
| Strict Mode | FinTech, HealthTech, High-Compliance environments. | Redacts everywhere. Requires explicit unmask_pii() to access data. |
Enabling Strict Mode
from ghost_pii import set_strict_mode
set_strict_mode(True) # Best practice for production PII handling
Contributing
We follow strict engineering standards. Please ensure you run linters and tests before submitting PRs.
pip install -e ".[dev]"
pytest # run test suite
ruff check src/ghost_pii # lint
mypy src/ghost_pii # type-check
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright (c) 2026 Sthitaprajna Sahoo and contributors.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ghost_pii_pydantic-0.1.1.tar.gz.
File metadata
- Download URL: ghost_pii_pydantic-0.1.1.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
967edb22c0688ff08ed16f71f30e7427c0206285624cd4c7200fb8793319a372
|
|
| MD5 |
cc3eecd28b02f0406c501acb9d0832fe
|
|
| BLAKE2b-256 |
75f49bbdbf6252142310ae9f3e2f4d5b80e791b898e49b9eebda588714e69834
|
Provenance
The following attestation bundles were made for ghost_pii_pydantic-0.1.1.tar.gz:
Publisher:
release.yml on STHITAPRAJNAS/ghost-pii-pydantic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghost_pii_pydantic-0.1.1.tar.gz -
Subject digest:
967edb22c0688ff08ed16f71f30e7427c0206285624cd4c7200fb8793319a372 - Sigstore transparency entry: 1280927955
- Sigstore integration time:
-
Permalink:
STHITAPRAJNAS/ghost-pii-pydantic@edf663bdda8241b24b14e723223287f73d07e2a1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/STHITAPRAJNAS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@edf663bdda8241b24b14e723223287f73d07e2a1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ghost_pii_pydantic-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ghost_pii_pydantic-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28188059b95804e4be5e68fb485a52e36193e57ebe5ac0bbda44091f74995c6c
|
|
| MD5 |
b173842d6e159378eceda36ea82014e1
|
|
| BLAKE2b-256 |
943673544f1e6f1d9628576ebd976a6770d737f0230982858b7b339060cd9f7a
|
Provenance
The following attestation bundles were made for ghost_pii_pydantic-0.1.1-py3-none-any.whl:
Publisher:
release.yml on STHITAPRAJNAS/ghost-pii-pydantic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghost_pii_pydantic-0.1.1-py3-none-any.whl -
Subject digest:
28188059b95804e4be5e68fb485a52e36193e57ebe5ac0bbda44091f74995c6c - Sigstore transparency entry: 1280927958
- Sigstore integration time:
-
Permalink:
STHITAPRAJNAS/ghost-pii-pydantic@edf663bdda8241b24b14e723223287f73d07e2a1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/STHITAPRAJNAS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@edf663bdda8241b24b14e723223287f73d07e2a1 -
Trigger Event:
push
-
Statement type: