פרויקט: zer0pii.ai - Enterprise AI Security Gateway & DLP
גרסה: 1.0.0-SPEC
תאימות: RFC 9110 (HTTP Semantics), RFC 8895 (Server-Sent Events), OpenAPI v3.1.0, OpenAI API v1
יעד: צוותי הנדסת פלטפורמה (AI Platform Engineers), מפתחי צד-לקוח וארכיטקטי אינטגרציה
עדכון מחייב 08.09.2026: פורמט התגיות בסעיף 3.1 השתנה ל-
[LABEL_8hex]דטרמיניסטי בהיקף שיחה (כותרת בקשה חדשה:X-zer0pii-Conversation-ID; בהיעדרה - היקף ארגוני). אין יותר מונים ונונסים פר-בקשה - זה מה שמבטיח בפועל את שימור ה-prompt cache בשיחות מרובות-סבבים. ה-TTL של הכספת: 300 שניות שקט מתחדש בפעילות, תקרה 3600 שניות. פרטים: docs/ZDR-SCOPE.md סעיף 4.
1. סקירה כללית ועקרונות אינטגרציה (API Design Overview)
zer0pii.ai פועלת כשער שקוף (Drop-in Transparent Gateway) התואם במדויק את הממשקים הסטנדרטיים של ספקי מודלי שפה מובילים (OpenAI, Anthropic, AWS Bedrock, vLLM).
כל לקוח או ספרית קוד סטנדרטית (OpenAI Python/TypeScript SDK, LangChain, LlamaIndex, Instructor) מתחברים לשער על ידי שינוי כתובת הבסיס בלבד:
# כתובת בסיס ברירת מחדל (Geo-Routed Anycast):
https://api.zer0pii.ai/v1
# כתובות בסיס ייעודיות לריבונות מידע אזורית (Data Residency Enforced):
https://eu.api.zer0pii.ai/v1 # Frankfurt, Germany (EU Only)
https://us.api.zer0pii.ai/v1 # Virginia, USA (US Only)
2. מפרט כותרות HTTP ייעודיות (Custom Headers Specification)
2.1 כותרות בקשה (Ingress Headers - Client ➔ Gateway)
| שם הכותרת (Header) | טיפוס | חובה/אופציונלי | תיאור והתנהגות המערכת |
|---|---|---|---|
Authorization |
string |
חובה | טוקן האימות של zer0pii בפורמט: Bearer zpii_live_<hash>. משמש לסליקה, בדיקת מכסות וטעינת חוקי ה-CISO. |
X-zer0pii-Upstream-Key |
string |
אופציונלי | מפתח ה-API הגולמי של ספק היעד (OpenAI/Anthropic). במצב Pass-Through טהור, השער אינו שומר מפתחות בשרת אלא מעביר ערך זה ישירות לספק. |
X-zer0pii-Upstream-URL |
string (url) |
אופציונלי | עקיפת יעד ברירת המחדל (למשל הפניה ל-vLLM פנימי: http://internal-vllm.corp:8000/v1). |
X-zer0pii-Policy-Group |
string |
אופציונלי | שיוך מחלקתי ידני (למשל finance, dev, hr). אם אינו מוגדר, נקבע אוטומטית לפי ה-API Key. |
X-zer0pii-Debug |
boolean |
אופציונלי | תקף בסביבות Staging/Dev בלבד (true/false). מחזיר פירוט חוקים שהופעלו בכותרות התגובה ללא חשיפת המידע. |
X-zer0pii-Org-Salt |
string |
אופציונלי | מפתח הצפנה ארגוני לצורך מיסוך עקבי של ה-Prefix (משמר Prompt Caching). מנוהל כברירת מחדל ב-KMS. |
2.2 כותרות תגובה (Egress Headers - Gateway ➔ Client)
| שם הכותרת (Header) | טיפוס | דוגמת ערך | משמעות טכנולוגית |
|---|---|---|---|
X-zer0pii-Mode |
string |
standard / degraded-deterministic |
מציין אם הבקשה עובדה במלואה (כולל מודל ONNX) או שנכנסה למצב מעקף דטרמיניסטי עקב עומס/חריגת זמן. |
X-zer0pii-Latency |
string |
total=11.4ms; ast=0.2ms; det=0.8ms; onnx=9.6ms; vault=0.8ms |
פירוט מלא של תקציב השיהוי הפנימי שנצרך על ידי הפרוקסי (אינו כולל את זמן ההסקה של ספק המודל). |
X-zer0pii-Redacted-Count |
integer |
3 |
מספר הישויות הרגישות שאותרו ומוסכו בפרומפט הקלט. |
X-zer0pii-Attestation |
string |
t=1772985600;sig=ed25519:...;status=purged |
חתימה דיגיטלית קריפטוגרפית (ZDR Receipt) המאשרת שהגייטווי אינו שומר את הבקשה הגולמית מעבר לזמן עיבודה, ודורס פיזית את עותק ה-buffer שבשליטתו הישירה. status=purged אינו מבטיח דריסת זיכרון של כל עותק ש-framework יצר (למשל מטמון פנימי של Starlette) - ראו core/scrub.py. |
X-zer0pii-Request-ID |
string (uuid) |
req_7f8a9b2c-1234-4567-89ab-cdef01234567 |
מזהה חד-חד-ערכי לצורכי מעקב ותחקור מול הדשבורד ויומני ה-SIEM. |
3. הגדרת נקודות קצה (API Endpoints Definition)
3.1 יצירת שיחה והשלמת טקסט: POST /v1/chat/completions
נקודת הקצה המרכזית לעיבוד ומיסוך שיחות, תומכת במודל הסינכרוני ובמודל הסטרימינג (SSE).
גוף הבקשה (Request Body)
תואם 100% לסכמת OpenAI Chat Completion API, עם הרחבות אבטחה:
{
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a customer service assistant for Acme Corp."
},
{
"role": "user",
"content": "Please review the loan application for John Doe, Israeli ID 012345672, email john@example.com."
}
],
"temperature": 0.7,
"stream": true,
"tools": [
{
"type": "function",
"function": {
"name": "fetch_credit_score",
"description": "Lookup credit score by citizen ID",
"parameters": {
"type": "object",
"properties": {
"citizen_id": {
"type": "string",
"description": "National ID number"
}
},
"required": ["citizen_id"]
}
}
}
]
}
נתיב עיבוד הבקשה (Payload Transformation Pipeline)
- עיבוד הודעת ה-
system(Static Prefix): טקסט המערכת סורק ישויות. אם אותרו, הן ממוסכות באמצעות Hash דטרמיניסטי המשמר Caching:John Doe➔[PERSON_01_7c2b]. - עיבוד הודעת ה-
user(Dynamic Tail): ישויות ממוסכות עם Nonce אקראי:012345672➔[IL_ID_01_a8f9],john@example.com➔[EMAIL_01_3d1e]. - שמירה בכספת ארעית (In-Memory Redis Vault):
Key: vault:org_acme:req_7f8a9b2c
TTL: 300s
Hash Fields:
"[PERSON_01_7c2b]" -> "John Doe"
"[IL_ID_01_a8f9]" -> "012345672"
"[EMAIL_01_3d1e]" -> "john@example.com"
- שידור גוף מנוקה בלבד לספק ה-LLM המקורי.
3.2 יצירת וקטורים: POST /v1/embeddings
מטפל באינדוקס מסמכים למסדי נתונים וקטוריים ומערכות RAG.
Opt-in, lossy (next-phase Q6, 22.09.2026). The endpoint ships DARK: it exists only for an org whose owner has enabled the
embeddings_lossy_optinfeature flag (console: Settings, Feature flags; self-hosted gateways with no control plane:ZER0PII_FEATURE_FLAGS=embeddings_lossy_optin). For every other org the route answers FastAPI's plain 404 ({"detail":"Not Found"}), indistinguishable from a route that does not exist. The current implementation redacts input with vault tags and the tags SHIFT the vectors: masked embeddings are not equivalent to embeddings of the unmasked text, and similarity search or clustering over them will differ. Every successful response carries"zer0pii_caveat"in the body andX-zer0pii-Lossy: truein the headers. The "Upstream Surrogate" mode described below (synthetic same-space replacements) is the deferred design, not what runs today.
גוף הבקשה
{
"model": "text-embedding-3-small",
"input": [
"Meeting notes with Israel Israeli regarding project Chimera budget."
],
"encoding_format": "float"
}
התנהגות השער (Semantic Preserving Mode)
- מצב Local Engine (ברירת מחדל): אם הוגדר בהגדרות הארגון, הבקשה מעובדת לוקאלית על גבי מודל ONNX זעיר (
bge-small-en-v1.5) בתוך הפרוקסי ב-3ms, ללא העברת טקסט ל-OpenAI. - מצב Upstream Surrogate: אם נדרש מודל של OpenAI/Cohere, המערכת אינה מחליפה ישויות בתגיות נוקשות (המשבשות את המרחק הווקטורי), אלא בשמות חלופיים סינתטיים קבועים מאותו מרחב סמנטי הנגזרים מגיבוב עקבי:
"Israel Israeli"➔ מוחלף ב-"David Cohen".- הווקטור נוצר על בסיס הטקסט הסינתטי ומחזיר ייצוג סמנטי תקין ל-Vector DB.
3.3 אימות קבלות השמדה ומפתחות: GET /.well-known/jwks.json
מספק את המפתחות הציבוריים של ה-Gateway לצורך אימות בלתי תלוי של חתימות ה-Attestation בצד הלקוח.
פלט תגובה
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"kid": "gateway-eu-frankfurt-2026-01",
"use": "sig",
"x": "O27R_8iQz1oX3L0yT4w_Z8bKp9MnVqWs7XuY_123456"
}
]
}
3.4 אישור אצוות מקומי (Pre-Flight CLI Ticket): POST /v1/batch/authorize
מאפשר ל-zer0pii-cli להריץ סריקה מקומית של קובצי .jsonl ענקיים במחשב הלקוח עבור OpenAI Batch API מבלי לשלוח את המידע לשער.
גוף הבקשה
{
"record_count": 50000,
"estimated_bytes": 104857600
}
פלט תגובה (Signed Execution Lease)
{
"lease_id": "lease_8829f0a",
"authorized_records": 50000,
"expires_at": "2026-09-08T11:06:11Z",
"lease_token": "eyJhbGciOiJFRDI1NTE5Iiw..."
}
4. מפרט פרוטוקול סטרימינג (Server-Sent Events - SSE Protocol)
כאשר מוגדר stream: true, השער פועל כמתווך הזרמה בעל שיהוי מזערי. הוא מיירט את זרם ה-SSE של הספק, משחזר את התגיות הממוסכות לערכים המקוריים, ופולט את הסטרים חזרה ללקוח.
Upstream LLM Event Stream (SSE)
│
▼
[ HTTP/2 Chunk Buffer ]
│
▼
[ Sliding-Window State Machine ]
├── Window Capacity: 32 UTF-8 Characters
├── State 1: EMIT_PASSTHROUGH (אין סוגר פותח '[' מזוהה)
├── State 2: ACCUMULATE_TAG (זוהה '[', אוגר תווים עד ']')
└── State 3: SWAP_AND_FLUSH (התאמה מול ה-Vault ופליטה מיידית)
│
▼
Reconstituted SSE Stream (Delivered to Client)
4.1 אלגוריתם ה-Sliding-Window Tail Buffer
- רוחב חלון מקסימלי: 32 תווים (האורך המרבי של תגית ממוסכת, כגון
[CREDIT_CARD_01_7f8a9b2c]). - מכונת מצבים:
- מצב רגיל (Pass-Through): כל טקסט שאינו מכיל את התו
[משוחרר מיידית ב-Chunk הנוכחי ללא עיכוב (שיהוי < 0.1ms). - זיהוי תגית אפשרית: ברגע שהתו
[מופיע ללא תו סוגר]באותו צ'אנק, החלון מחזיק את הזנב החל מ-[וממתין לצ'אנק הבא. - פתרון התגית (Resolution): ברגע שהתו
]מתקבל: - נבדק האם המחרוזת בתוך הסוגריים קיימת ב-Redis Vault של אותה בקשה.
- אם קיימת: התגית מוחלפת בערך המקורי, והטקסט המשוחזר נפלט מיידית לזרם הלקוח.
- אם אינה קיימת: הטקסט נפלט כמות שהוא (זיהוי של טקסט לגיטימי שנכתב עם סוגריים מרובעים).
- סגירת זרם (Stream Termination):
עם קבלת ההודעה
data: [DONE]:
- הבאפר מרוקן (Flush) מכל שארית טקסט.
- פקודת מחיקה אטומית מוחקת את מפתח ה-Vault ב-Redis (
DEL vault:org:req_id). - מופעל מנגנון דריסת הזיכרון ב-RAM (
secure_scrub_memory). - האירוע
data: [DONE]\n\nמועבר לסיום הקריאה בצד הלקוח.
5. חוזה קריאות כלים וסכמות מובנות (Tool Calling & JSON Contract)
כאשר מודל השפה משתמש ב-Function Calling / Tool Calling, השער מחיל חוקי מיסוך מבניים מחמירים:
5.1 שמירה על טיפוסי נתונים (Type-Preservation Laws)
- ערכים מחרוזתיים (Strings): מוחלפים בתגיות מיסוך מחרוזתיות תקניות (
"[PERSON_01_a8f9]"). - ערכים מספריים (Integers / Floats): ספקי LLM וסכמות ולידציה של לקוחות (כגון Pydantic) יקרסו אם שדה המוגדר כמספר יוחלף במחרוזת טקסט. לכן, מזהים מספריים מוחלפים במספר סינתטי אקראי בעל אורך זהה:
- ערך מקורי:
{"account_id": 987654321} - ערך ממוסך המועבר ל-LLM:
{"account_id": 104928374}(טיפוסintנשמר). - ערכים בוליאניים ושמות שדות (Keys): לעולם אינם משתנים ואינם נסרקים.
5.2 דוגמת שחזור פרמטרים של כלי (Tool Call Argument Reconstruction)
ה-LLM מחזיר קריאת כלי ממוסכת:
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "fetch_credit_score",
"arguments": "{\"citizen_id\":\"[IL_ID_01_a8f9]\"}"
}
}
לפני שהתשובה מוחזרת לאפליקציה של הלקוח, השער משחזר את הארגומנטים בזיכרון ומחזיר:
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "fetch_credit_score",
"arguments": "{\"citizen_id\":\"012345672\"}"
}
}
האפליקציה של הלקוח מקבלת את הערך הנקי המקורי ומפעילה את השאילתה בבסיס הנתונים הפנימי שלה בצורה שקופה.
6. קודי שגיאה ומבנה שגיאות תקני (Error Handling & RFC 7807)
כל תגובות השגיאה מוחזרות בתקן RFC 7807 (Problem Details for HTTP APIs), ומבטיחות אפס דליפת PII בגוף השגיאה:
{
"type": "https://zer0pii.ai/errors/credential-block",
"title": "Critical Security Exfiltration Blocked",
"status": 403,
"detail": "The request was terminated because it contained a high-entropy secret (AWS_KEY) violating enterprise security policy.",
"instance": "req_7f8a9b2c-1234-4567-89ab-cdef01234567",
"code": "SECURITY_POLICY_VIOLATION",
"rule_triggered": "ENTROPY_CRITICAL_SECRET",
"confidence": 0.99
}
טבלת קודי שגיאה ייעודיים
| קוד HTTP | קוד שגיאה פנימי | סיבת שגיאה ומשמעות |
|---|---|---|
400 Bad Request |
INVALID_JSON_SCHEMA |
מבנה ה-JSON אינו תקין או פגום תחבירית. |
401 Unauthorized |
INVALID_API_KEY |
טוקן ה-zer0pii שגוי, אינו קיים או שפג תוקפו. |
403 Forbidden |
SECURITY_POLICY_VIOLATION |
הבקשה נחסמה אקטיבית עקב זיהוי מפתח ענן, סיסמה או חריגה מסף ה-PII. |
403 Forbidden |
PROMPT_INJECTION_DETECTED |
שומר הסף זיהה תבנית Jailbreak / Injection ברמת ביטחון גבוהה. |
429 Too Many Requests |
RATE_LIMIT_EXCEEDED |
חריגה ממכסת הקריאות החודשית או מקצב הקריאות לשנייה (RPS). |
502 Bad Gateway |
UPSTREAM_PROVIDER_ERROR |
ספק המודל החיצוני (OpenAI/Anthropic) החזיר שגיאה או לא הגיב. |
503 Service Unavailable |
CIRCUIT_BREAKER_ACTIVE |
מצב Fail-Closed הופעל בארגון והשער בעומס יתר חריג. |
7. מפרט OpenAPI 3.1 מלא (Machine-Readable YAML)
להלן הגדרת ה-OpenAPI 3.1 הרשמית של השער:
openapi: 3.1.0
info:
title: zer0pii Enterprise Security Gateway API
description: High-performance, zero-latency, zero-retention DLP gateway for LLM traffic.
version: 1.0.0
servers:
- url: https://api.zer0pii.ai/v1
description: Global Anycast Production Gateway
- url: https://eu.api.zer0pii.ai/v1
description: EU-Only Dedicated Sovereign Gateway (Frankfurt)
- url: https://us.api.zer0pii.ai/v1
description: US-Only Dedicated Sovereign Gateway (Virginia)
paths:
/chat/completions:
post:
summary: Sanitize prompt, route to LLM, and stream reconstituted response.
operationId: createChatCompletion
security:
- BearerAuth: []
parameters:
- name: X-zer0pii-Upstream-Key
in: header
required: false
schema:
type: string
description: Optional direct customer LLM API key (Pure Pass-Through Mode).
- name: X-zer0pii-Debug
in: header
required: false
schema:
type: boolean
description: Return non-sensitive detection telemetry headers (Staging only).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompletionRequest'
responses:
'200':
description: Successful completion or streaming event source.
headers:
X-zer0pii-Mode:
schema:
type: string
example: standard
X-zer0pii-Latency:
schema:
type: string
example: "total=11.4ms; ast=0.2ms; det=0.8ms; onnx=9.6ms; vault=0.8ms"
X-zer0pii-Attestation:
schema:
type: string
example: "t=1772985600;sig=ed25519:...;status=purged"
X-zer0pii-Request-ID:
schema:
type: string
format: uuid
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompletionResponse'
text/event-stream:
schema:
type: string
description: Server-Sent Events stream containing reconstituted completion chunks.
'403':
description: Security policy violation or prompt injection intercepted.
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetails'
'502':
description: Upstream LLM provider failure.
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetails'
/embeddings:
post:
summary: Vectorize text using local ONNX model or upstream surrogate masking.
operationId: createEmbeddings
security:
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- input
- model
properties:
model:
type: string
example: text-embedding-3-small
input:
oneOf:
- type: string
- type: array
items:
type: string
example: "Sensitive contract text with Acme Corp."
responses:
'200':
description: Vector embeddings returned.
content:
application/json:
schema:
type: object
properties:
object:
type: string
example: list
data:
type: array
items:
type: object
properties:
embedding:
type: array
items:
type: number
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: zpii_live_*
schemas:
ChatCompletionRequest:
type: object
required:
- model
- messages
properties:
model:
type: string
example: gpt-4o
messages:
type: array
items:
type: object
required:
- role
- content
properties:
role:
type: string
enum: [system, user, assistant, tool]
content:
type: string
stream:
type: boolean
default: false
temperature:
type: number
minimum: 0
maximum: 2
tools:
type: array
items:
type: object
ChatCompletionResponse:
type: object
properties:
id:
type: string
object:
type: string
example: chat.completion
created:
type: integer
model:
type: string
choices:
type: array
items:
type: object
properties:
index:
type: integer
message:
type: object
properties:
role:
type: string
content:
type: string
finish_reason:
type: string
ProblemDetails:
type: object
required:
- type
- title
- status
- code
properties:
type:
type: string
title:
type: string
status:
type: integer
detail:
type: string
instance:
type: string
code:
type: string
rule_triggered:
type: string
confidence:
type: number
הערה מקומית (build): בסכמת ה-/embeddings המקורית שנמסרה, מבנה oneOf היה חסר מקף רשימה (string/array) - תוקן כאן לתחביר OpenAPI תקין מבלי לשנות את הכוונה.