English | Русский
SafeGate
Self-hosted AI security platform for LLM applications
Protect sensitive data · Stop prompt attacks · Control inference cost · Audit everything
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 toinvoke()/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).
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)
Mode B — Mask with asterisks
guard = SafeGate(protection_mode="mask")
# michael.carter@example.com → **************************
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.
| 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
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 safegate-2.0.0.tar.gz.
File metadata
- Download URL: safegate-2.0.0.tar.gz
- Upload date:
- Size: 128.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
394efe941d15da63a645ff61898552ff60bfdc472792960df549cb4e128c7743
|
|
| MD5 |
dd05a63e64e784d25659171ed26d564e
|
|
| BLAKE2b-256 |
c3b51e6e2eaec277a0ede4e6d9bfe97829d50a9692031f9e35e4c183f4eb2994
|
File details
Details for the file safegate-2.0.0-py3-none-any.whl.
File metadata
- Download URL: safegate-2.0.0-py3-none-any.whl
- Upload date:
- Size: 148.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3f98ab81ab463be9728500a7b3eb09d234acc41c715bf4b0ad7f8fc344b5c9a
|
|
| MD5 |
1e301c2ef937bf204870c953ba7d2054
|
|
| BLAKE2b-256 |
916c70f68315c0685131dba6ab7270bb3f58b9ea1d4f52e1d452cd03dd042240
|