Skip to main content

English | Русский

SafeGate

Self-hosted AI security platform for LLM applications

Protect sensitive data · Stop prompt attacks · Control inference cost · Audit everything

Python 3.10+ License: MIT CI Version

Features · Quick start · What we detect · Examples · How it works · Docs

pip install safegate


Features

SafeGate sits between your app and the LLM (and around RAG embeddings). You enable only the stages you need.

Capability What you get How to use
PII / secrets detection 60+ entity types across identity, finance, health, network, vehicles, RU/US/UK IDs SafeGate() / entity_types=[...]
Substitution or mask Prompt: replace with dictionary fakes, or ***. Response: always *** (never fake values to the user) protection_mode="substitute" / "mask"
Prompt & response guards Protect text before the LLM call; scan the answer for leaks; mask residual PII in the reply protect_prompt → invoke → protect_response
Choose what to detect Enable only the sensitive types you care about; everything else is ignored entity_types=["email", "ssn", …]
EDOS guard (optional) Score “cognitive bomb” prompts; strip wasteful instructions, route to a fallback LLM, or block edos_enabled, edos_high_risk_action
Vector privacy (RAG) ε-differential privacy noise + lineage obfuscation for embeddings VectorPrivacyGuard / ContextGuard
Policies & industry packs YAML rules, presets (health_hipaa, bank_ru, …), simulator preset="…", safegate policy catalog
Audit & SIEM JSONL trail, CEF/ECS/CSV export, approval workflow audit_path=…
Prompt  →  PII guard  →  EDOS*  →  your LLM  →  response guard  →  user
RAG     →  context guard  →  vector privacy*  →  vector DB

* optional stages

Quick start

Install

pip install safegate

1) Protect text (no LLM required)

from safegate import SafeGate

guard = SafeGate(protection_mode="substitute")  # or "mask"
session = guard.protect_prompt(
    "Contact Alice at alice@company.com or +1 (415) 555-0100"
)
print(session.prompt_result.text)
# Contact … at <dictionary email> or <dictionary phone>
print(session.prompt_mappings)

2) Detect only selected types

from safegate import SafeGate, list_entity_types

# only email + phone + SSN
guard = SafeGate(entity_types=["email", "phone", "ssn"])

# or a whole domain
guard = SafeGate(entity_types=list_entity_types("financial"))

Full catalog: docs/SENSITIVE_ATTRIBUTES.md
CLI: safegate entities list --domains

3) Wire your real LLM

from safegate import SafeGate
from safegate.llm import OpenAIAdapter  # or OllamaAdapter

guard = SafeGate(protection_mode="substitute")
session = (
    guard.protect_prompt("My SSN is 123-45-6789")
    .invoke(OpenAIAdapter(client, model="gpt-4o-mini"))
    .protect_response()
)
print(session.result)

OpenAIAdapter works with any OpenAI-compatible API. OllamaAdapter is for local models.

About MockLLM: it is a tiny stub that returns a fixed string. SafeGate uses it only in unit tests and offline demos so CI does not need API keys. It is not a production model — pass your own adapter to invoke() / chat().

4) Optional: EDOS cost protection

guard = SafeGate(
    edos_enabled=True,                          # set False to skip the stage
    edos_high_risk_action="block",              # or "route_fallback"
    fallback_llm=OpenAIAdapter(cheap_client, model="gpt-4o-mini"),
)

5) Optional: RAG embedding privacy

from safegate import VectorPrivacyGuard
from safegate.guards import ContextChunk, ContextGuard

vector_guard = VectorPrivacyGuard(epsilon=1.0)
ctx = ContextGuard(vector_privacy=vector_guard)
result = ctx.protect_embeddings(
    [ContextChunk(id="doc-1", text=text, embedding=vector)]
)

What we detect

Entities are grouped into domains. Enable a domain or pick individual types.

Domain Types (examples)
identity full_name, date_of_birth, passport, us_passport, driver licenses
contact email, phone, address, zip_code
national_ids ssn, nino (UK), inn/snils (RU), ein, itin, employee_id
financial credit_card, cvv, card_expiration, iban, swift_bic, salary, bank accounts
health medical, member_id, insurance_id, npi, medicare_id
credentials password, username, api_key
network ip_address, mac_address, domain, social_handle (LinkedIn, @handles)
vehicles vin, vehicle_registration, ru_license_plate, frequent_flyer
business commercial_secret
attacks prompt_injection, jailbreak (ThreatFeed)
safegate entities list --domains

Complete tables with examples: docs/SENSITIVE_ATTRIBUTES.md


Examples

Sensitive values are found first, then either substituted from a built-in dictionary (prompt path) or masked with * (mask mode, and always on the LLM response).

PII detectors highlighting sensitive fields

Mode A — Dictionary substitution (prompt → LLM)

Fake values come from generated dictionary pools shipped with SafeGate (gdpr_fakes, default, industry packs). The vault maps each real value → one synthetic token for the session, so the LLM still sees realistic emails, phones, and IDs — not your real data.

guard = SafeGate(protection_mode="substitute")
# michael.carter@example.com  →  sofia.brennan@privacy.test   (from dictionary)
# +1 (415) 555-0187           →  +49 30 4829173               (from dictionary)

Prompt Guard substitutions from dictionary

Mode B — Mask with asterisks

guard = SafeGate(protection_mode="mask")
# michael.carter@example.com  →  **************************

Prompt Guard masking with asterisks

LLM response — always masked

Whatever comes back from the model is never filled with dictionary fakes and is never restored to real PII by default. Residual PII and echoed substitute tokens are replaced with *. Opt-in detokenize=True restores real values only when you explicitly need that legacy behaviour.

Prompt sent to the LLM after masking

Direction Substitute mode Mask mode
Prompt → LLM Dictionary fakes ****
LLM → user **** (always) **** (always)

Local UI to try both modes:

cd local-demo && python app.py
# http://127.0.0.1:8765/

How it works

flowchart LR
    A[Input] --> B[Detectors — optional entity filter]
    B --> C[Policy]
    C -->|substitute / mask / block| D[Prompt guard]
    D --> E[EDOS optional]
    E --> F[Your LLM]
    F --> G[Response guard — always mask]
    G --> H[Output]
Stage Role
Detectors Find sensitive values (filtered by entity_types if set)
Policy Decide action per type: substitute · mask · block · remove
Prompt guard Apply policy before the LLM call (dictionary or ****)
EDOS Optional complexity scoring / strip / route / block
Response guard Leak check; always mask residual PII and echoed tokens with ****
Audit JSONL + SIEM fields including EDOS

Examples

Example Use case
chatbot_demo.py Chatbot with PII substitution
rag_demo.py RAG context guard
mcp_demo.py MCP tool filter
gateway_client.py REST AI gateway
langchain_demo.py LangChain handler

Full list: examples/README.md


Industry packs

bank_ru · health_hipaa · gov_fz152 · retail_eu · fintech_us · insurance_us · saas_global · telecom_eu · education_us · energy_eu · legal_eu · logistics_eu

safegate policy catalog --format markdown
guard = SafeGate(preset="health_hipaa", region="us")

Documentation

Doc Contents
SENSITIVE_ATTRIBUTES.md Full entity catalog + how to select types
INSTALL.md Install / Docker
COMPARISON.md vs Presidio / LLM Guard
PRODUCT_ROADMAP.md Platform roadmap

Contributing

SafeGate is open source (MIT).

git clone https://github.com/patonkikh/SafeGate.git
cd SafeGate
python -m pip install -e ".[dev]"
pytest -v
Issues github.com/patonkikh/SafeGate/issues
Guidelines CONTRIBUTING.md
Security SECURITY.md

License

MIT

Metadata

Release files for safegate 2.0.0

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

Source distribution (sdist)

Source distribution for safegate 2.0.0
File Size Uploaded Provenance Actions
safegate-2.0.0.tar.gz 128.5 kB Without provenance Details for safegate-2.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for safegate 2.0.0
File Interpreter ABI Platform Actions
safegate-2.0.0-py3-none-any.whl Python 3 none any Details for safegate-2.0.0-py3-none-any.whl

Total release size: 277.0 kB

Release files / safegate-2.0.0.tar.gz

Download URL safegate-2.0.0.tar.gz
Size 128.5 kB
Tags Source
SHA-256 checksum
How to use checksums
394efe941d15da63a645ff61898552ff60bfdc472792960df549cb4e128c7743
BLAKE2b-256 checksum
How to use checksums
c3b51e6e2eaec277a0ede4e6d9bfe97829d50a9692031f9e35e4c183f4eb2994
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.0

Release files / safegate-2.0.0-py3-none-any.whl

Download URL safegate-2.0.0-py3-none-any.whl
Size 148.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f3f98ab81ab463be9728500a7b3eb09d234acc41c715bf4b0ad7f8fc344b5c9a
BLAKE2b-256 checksum
How to use checksums
916c70f68315c0685131dba6ab7270bb3f58b9ea1d4f52e1d452cd03dd042240
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.0

Security for safegate 2.0.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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

2.0.0 This release

2 release files No 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