Skip to main content

pii-shield-llm 🔒

PyPI version Python License: MIT

Safe LLM usage by automatically masking PII/PFI before it leaves your system.

pii-shield-llm intercepts sensitive data, replaces it with typed UUID tokens (EMAIL_3f2a1b), sends the clean text to your LLM, then restores original values in the response — all transparently.


Installation

pip install pii-shield-llm                    # core (regex detection only)
pip install "pii-shield-llm[nlp]"             # + spaCy NER for names & orgs
pip install "pii-shield-llm[openai]"          # + OpenAI wrapper
pip install "pii-shield-llm[anthropic]"       # + Anthropic wrapper
pip install "pii-shield-llm[all]"             # everything

Quick Start

Basic masking & restoration

from pii_shield import PIISession

with PIISession() as session:
    masked, mapping = session.mask(
        "Hi, I'm Alice Smith. Reach me at alice@acme.com or 415-555-0199."
    )
    print(masked)
    # → "Hi, I'm Alice Smith. Reach me at <<EMAIL_d3a1f9>> or <<PHONE_7b2c04>>."
    #   (Names need spaCy NER; emails & phones detected by regex)

    llm_response = your_llm_call(masked)          # send safe text to LLM
    clean = session.restore(llm_response)          # PII restored in response
    print(clean)
# Session auto-saved to encrypted vault on context manager exit

With the built-in LLM wrapper (OpenAI)

import openai
from pii_shield import PIISession
from pii_shield.llm_client import LLMClient

client = LLMClient(
    session=PIISession(),
    backend="openai",
    openai_client=openai.OpenAI(),
    model="gpt-4o",
    system_prompt="You are a helpful customer support agent.",
)

result = client.chat(
    "Please look up account for john@corp.com, SSN 123-45-6789."
)
print(result.restored_text)    # PII restored
print(result.masked_prompt)    # What was actually sent to OpenAI

With Anthropic Claude

import anthropic
from pii_shield import PIISession
from pii_shield.llm_client import LLMClient

client = LLMClient(
    session=PIISession(),
    backend="anthropic",
    anthropic_client=anthropic.Anthropic(),
    model="claude-sonnet-4-20250514",
)

result = client.chat("Summarise the risk profile for card 4111111111111111.")
print(result.restored_text)

Multi-turn conversation

client = LLMClient(session=PIISession(), backend="openai", openai_client=..., model="gpt-4o")

r1 = client.chat("My name is Bob and my email is bob@corp.com.")
r2 = client.chat("What was the email I just gave you?")
# History is maintained; PII masked/restored across all turns

Entity Types Detected

Entity Method Example
EMAIL Regex alice@acme.com
PHONE Regex +1 415-555-0199
SSN Regex 123-45-6789
CREDIT_CARD Regex + Luhn 4111 1111 1111 1111
ADDRESS Regex 123 Main St, NY 10001
IP_ADDRESS Regex 192.168.1.100
PASSPORT Regex A12345678
DOB Regex 01/15/1990
NAME spaCy NER* Alice Smith
ORG spaCy NER* Goldman Sachs

*Requires pip install "pii-shield-llm[nlp]" + python -m spacy download en_core_web_sm


Token Format

<<ENTITY_TYPE_shortid>>

Examples:
  <<EMAIL_d3a1f9>>
  <<PHONE_7b2c04>>
  <<SSN_1a9e3c>>
  <<CREDIT_CARD_f00b12>>
  • Deterministic within a session: same raw value → same token (LLM output stays coherent)
  • Cross-session isolated: different sessions never share tokens
  • Type-preserving: LLM sees the entity category without the actual data

Vault & Key Management

Session mappings are persisted in an AES-encrypted file (Fernet / AES-128-CBC + HMAC-SHA256).

On first use, a key is auto-generated and written to .env:

PII_SHIELD_KEY="base64url-encoded-32-byte-key"

Keep this key safe — losing it means mappings in the vault cannot be decrypted.

To use a custom vault path or bring your own key:

from pii_shield import PIIVault, PIISession

vault = PIIVault(
    vault_path="/secure/path/pii.vault.enc",
    env_path="/secure/path/.env",
)
session = PIISession(vault=vault)

Advanced Usage

Restrict entity types

from pii_shield import PIISession, EntityType

session = PIISession(entity_types=[EntityType.EMAIL, EntityType.CREDIT_CARD])

Resume a named session

# Session 1 — mask and save
s = PIISession(session_id="order-12345")
masked, _ = s.mask("Card: 4111111111111111")
s.save()

# Later — restore using the same session
s2 = PIISession(session_id="order-12345")
print(s2.restore(masked))   # → "Card: 4111111111111111"

Custom LLM backend

def my_llm(prompt: str) -> str:
    # Call your own model
    return my_model.generate(prompt)

client = LLMClient(session=PIISession(), backend="custom", custom_fn=my_llm)

Architecture

Input Text
    │
    ▼
[PIIDetector]   regex patterns + optional spaCy NER
    │
    ▼
[PIIReplacer]   value → <<TYPE_shortid>> (deterministic, collision-safe)
    │
    ▼
Masked Text ──→ LLM API  (OpenAI / Anthropic / custom)
    │
    ▼
LLM Response (may echo tokens back)
    │
    ▼
[PIIRestorer]   <<TYPE_shortid>> → original value
    │
    ▼
Restored Output

[PIIVault]  ←→  AES-encrypted session mappings on disk

Running Tests

pip install pytest
pytest tests/ -v

License

MIT

Metadata

Release files for pii-shield-llm 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pii-shield-llm 1.0.2
File Size Uploaded Provenance Actions
pii_shield_llm-1.0.2.tar.gz 18.4 kB With provenance Details for pii_shield_llm-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pii-shield-llm 1.0.2
File Interpreter ABI Platform Actions
pii_shield_llm-1.0.2-py3-none-any.whl Python 3 none any Details for pii_shield_llm-1.0.2-py3-none-any.whl

Total release size: 34.7 kB

Release files / pii_shield_llm-1.0.2.tar.gz

Download URL pii_shield_llm-1.0.2.tar.gz
Size 18.4 kB
Tags Source
SHA-256 checksum
How to use checksums
79cac0730680a438ac186c795d8444c0ce0dbc97ea97e8be43bb0d2c818a3a1a
BLAKE2b-256 checksum
How to use checksums
8c5b6914ac5e9021a3663ed8ad3cb7e3cd4760bac8241c021e6c75fcc0396f06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Release files / pii_shield_llm-1.0.2-py3-none-any.whl

Download URL pii_shield_llm-1.0.2-py3-none-any.whl
Size 16.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9feceaa77773a0ccbe2d0a5152d4217240c3e1d39d83f864d848513c3aaa6605
BLAKE2b-256 checksum
How to use checksums
95a2f6f7a04255e19f6cd6ad4384609b9207be92ec72a285bea500de3607b31c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Security for pii-shield-llm 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pii_shield_llm-1.0.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page