Skip to content

Privacy & PII Masking

ContextRouter includes a built-in privacy subsystem (cortex.privacy) that runs entirely in-process — no external service, no gRPC hop. PII masking is applied transparently at the SecureNode level before any LLM call and reversed after.

Architecture

User prompt → SecureNode → PiiSession.hide() → LLM Provider → PiiSession.reveal() → Response
│ │
└── AES-256-GCM ephemeral key (RAM only) ────────────┘

Privacy sits inside the Router process. There is no external “ContextZero” service — all masking, encryption, and persona logic is a direct function call.

PII Masking Pipeline

How It Works

  1. DetectionPIIMasker scans text using configurable entity rules (regex + NER)
  2. Tokenization — detected entities are replaced with reversible tokens (<PII_EMAIL_a1b2c3>)
  3. Encryption — original values are encrypted with ephemeral AES-256-GCM keys (RAM-only, CSPRNG)
  4. Storage — encrypted mappings live in an in-memory SQLite MappingStore (per-session)
  5. Reversal — after LLM response, PIIUnmasker decrypts and restores original values
  6. DestructionPiiSession.destroy() wipes all mappings and encryption keys from RAM

Supported Entity Types

EntityPatternExample
EmailRegexuser@example.com<PII_EMAIL_x>
PhoneRegex+380 67 123 4567<PII_PHONE_x>
Credit CardRegex + Luhn4111-1111-1111-1111<PII_CC_x>
NameNER (spaCy)John Smith<PII_NAME_x>
AddressNER (spaCy)123 Main St<PII_ADDRESS_x>
CustomConfigurableProject-specific patterns via EntityRule

Token Scope Requirements

PII masking activates when the node’s ContextToken carries both:

  • privacy:anonymize
  • privacy:deanonymize

These scopes are derived automatically from the project manifest when pii_masking: true is set on a graph node.

PiiSession API

PiiSession is the infrastructure-level wrapper created per-node by secure_node.py:

from contextunity.router.cortex.utils.pii import PiiSession
session = PiiSession(session_id="abc-123")
# Hide various data types before LLM call
masked_messages = session.hide_messages(messages)
masked_dict = session.hide_dict(state_data)
masked_text = session.hide_text("Call me at +380 67 123 4567")
masked_request = session.hide_model_request(model_request)
# Reveal after LLM response
revealed_dict = session.reveal_dict(response_data)
revealed_text = session.reveal_text(masked_response)
# Destroy session — wipe all keys from RAM
session.destroy()

Encryption

Each PiiSession creates its own EphemeralAES256Backend:

  • Key generation: os.urandom(32) — CSPRNG, never persisted
  • Algorithm: AES-256-GCM (authenticated encryption)
  • TTL: Configurable via privacy.pii_encryption_ttl_seconds (default: 60s)
  • Destruction: destroy() zeroes all keys in RAM — no recovery possible

If the cryptography package is not installed, falls back to PlaintextBackend with a warning.

Persona Engine

The PersonaEngine injects synthetic identity and behavioral guidelines into LLM conversations:

from contextunity.router.cortex.privacy import PersonaEngine, PersonaTemplate
engine = PersonaEngine()
# Use a built-in persona
persona = engine.create_persona("professional", session_id="session-123")
enriched = persona.inject_into_prompt("What is the best approach?")
# Register a custom persona
engine.register_template(PersonaTemplate(
name="medical_ua",
display_name="Медичний аналітик",
system_prompt="Ти — медичний аналітик. Відповідай українською.",
traits={"tone": "professional", "domain": "medical"},
restrictions=["Не ставити діагнози"],
language="uk",
))

Built-in Personas

NamePurposeTone
contextunity-harmless-agentDefault safe agent (default)Neutral, strict safety
neutralMinimal assistantNeutral, concise
professionalFormal advisorFormal, detailed
creativeCreative writing helperWarm, moderate

Configuration

Privacy settings are part of the Router config (router.yml):

privacy:
pii_encryption_ttl_seconds: 60 # AES key TTL
default_persona: "contextunity-harmless-agent"

Module Layout

cortex/privacy/
├── __init__.py # Public API exports
├── anonymizer.py # Anonymizer — orchestrates mask/unmask
├── persona.py # PersonaEngine, PersonaTemplate, Persona
└── masking/
├── config.py # MaskingConfig, EntityRule
├── contracts.py # Abstract protocols (PandasSeriesLike, PresidioResultLike)
├── defaults.py # DEFAULT_MASKING_CONFIG
├── encryption.py # EphemeralAES256Backend, PlaintextBackend
├── masker.py # PIIMasker
├── scanner.py # Entity detection (regex + NER)
├── store.py # MappingStore (SQLite in-memory)
├── tokens.py # PII token format
├── unmasker.py # PIIUnmasker
└── rules/
└── defaults.yaml # Default entity masking rules
cortex/utils/pii.py # PiiSession — infrastructure wrapper for SecureNode