Alienseeker commited on
Commit
7c262d4
Β·
verified Β·
1 Parent(s): 68dd54f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -98
app.py CHANGED
@@ -5,12 +5,14 @@ GitHub: https://github.com/thyrisAI/safe-zone
5
  Website: https://thyris.ai
6
  """
7
 
 
8
  import re
9
  import uuid
10
  import hashlib
11
  from dataclasses import dataclass
12
  from typing import List, Tuple
13
 
 
14
  @dataclass
15
  class Detection:
16
  type: str
@@ -21,6 +23,7 @@ class Detection:
21
  confidence: str
22
  mask_id: str
23
 
 
24
  class TSZDetector:
25
  PATTERNS = {
26
  "EMAIL": {
@@ -72,34 +75,31 @@ class TSZDetector:
72
  "description": "JSON Web Tokens"
73
  }
74
  }
75
-
76
  def _generate_mask_id(self, value: str) -> str:
77
  """Generate a short unique mask ID based on value hash"""
78
  hash_val = hashlib.md5(value.encode()).hexdigest()[:6]
79
  return hash_val
80
-
81
  def detect(self, text: str, rid: str = "NO-RID") -> Tuple[List[Detection], str]:
82
  detections = []
83
  redacted_text = text
84
  type_counters = {}
85
-
86
  for pii_type, config in self.PATTERNS.items():
87
  pattern = config["pattern"]
88
  for match in re.finditer(pattern, text, re.IGNORECASE):
89
  value = match.group()
90
  if pii_type == "TC_KIMLIK" and len(value) != 11:
91
  continue
92
-
93
- # Generate unique mask ID
94
  if pii_type not in type_counters:
95
  type_counters[pii_type] = 0
96
  type_counters[pii_type] += 1
97
-
98
  mask_id = self._generate_mask_id(value)
99
-
100
- # Format: [RID_TYPE_maskId]
101
  placeholder = f"[{rid}_{pii_type}_{mask_id}]"
102
-
103
  detections.append(Detection(
104
  type=pii_type,
105
  value=value,
@@ -109,39 +109,37 @@ class TSZDetector:
109
  confidence="HIGH" if len(value) > 8 else "MEDIUM",
110
  mask_id=mask_id
111
  ))
112
-
113
- # Sort by position (reverse) for correct replacement
114
  detections.sort(key=lambda x: x.start, reverse=True)
115
  for det in detections:
116
  redacted_text = redacted_text[:det.start] + det.placeholder + redacted_text[det.end:]
117
-
118
- # Re-sort for display
119
  detections.sort(key=lambda x: x.start)
120
-
121
  return detections, redacted_text
122
 
 
123
  detector = TSZDetector()
124
 
 
125
  def analyze_text(text: str, rid: str) -> Tuple[str, str, str, str]:
126
  if not text.strip():
127
  return "", "Please enter some text to analyze.", "", ""
128
-
129
- # Use provided RID or generate one
130
  if not rid.strip():
131
  rid = f"TSZ-{uuid.uuid4().hex[:8].upper()}"
132
-
133
  detections, redacted_text = detector.detect(text, rid)
134
-
135
  if not detections:
136
  return text, "No sensitive information detected.", "**0** PII entities found", f"Request ID: `{rid}`"
137
-
138
  report_lines = ["### Detected Entities\n"]
139
  by_type = {}
140
  for det in detections:
141
  if det.type not in by_type:
142
  by_type[det.type] = []
143
  by_type[det.type].append(det)
144
-
145
  for pii_type, items in by_type.items():
146
  desc = detector.PATTERNS[pii_type]["description"]
147
  report_lines.append(f"\n**{pii_type}** ({desc})")
@@ -149,13 +147,14 @@ def analyze_text(text: str, rid: str) -> Tuple[str, str, str, str]:
149
  masked_value = item.value[:3] + "***" + item.value[-2:] if len(item.value) > 5 else "***"
150
  report_lines.append(f"- `{masked_value}` β†’ `{item.placeholder}`")
151
  report_lines.append(f" - Mask ID: `{item.mask_id}` | Confidence: {item.confidence}")
152
-
153
  report = "\n".join(report_lines)
154
  stats = f"**{len(detections)}** PII entities found across **{len(by_type)}** categories"
155
  rid_display = f"Request ID: `{rid}`"
156
-
157
  return redacted_text, report, stats, rid_display
158
 
 
159
  EXAMPLES = [
160
  ["Hi, my name is John Smith and my email is john.smith@company.com. You can reach me at +1-555-123-4567. My SSN is 123-45-6789.", "REQ-001"],
161
  ["Customer Order #12345\nName: Jane Doe\nEmail: jane.doe@example.org\nPhone: (555) 987-6543\nCredit Card: 4532015112830366", "ORDER-12345"],
@@ -163,19 +162,19 @@ EXAMPLES = [
163
  ["Merhaba, ben Ahmet Yilmaz. TC Kimlik numaram 12345678901.\nTelefon: 0532 123 45 67\nIBAN: TR330006100519786457841326", "TR-REQ-001"],
164
  ]
165
 
 
166
  with gr.Blocks(title="TSZ - Thyris Safe Zone Demo", theme=gr.themes.Soft()) as demo:
167
-
168
  gr.Markdown("""
169
  # πŸ›‘οΈ TSZ (Thyris Safe Zone)
170
  **Enterprise-grade PII detection and guardrails gateway** that prevents sensitive data from leaking to LLMs and third-party APIs.
171
-
172
  [![GitHub](https://img.shields.io/badge/GitHub-Repository-black?logo=github)](https://github.com/thyrisAI/safe-zone)
173
  [![Website](https://img.shields.io/badge/Website-thyris.ai-blue)](https://thyris.ai)
174
  [![License](https://img.shields.io/badge/License-Apache%202.0-green)](https://github.com/thyrisAI/safe-zone/blob/main/LICENSE)
175
  """)
176
-
177
  with gr.Tabs():
178
- # Tab 1: Interactive Demo
179
  with gr.TabItem("οΏ½οΏ½ Interactive Demo"):
180
  with gr.Row():
181
  with gr.Column():
@@ -192,7 +191,7 @@ with gr.Blocks(title="TSZ - Thyris Safe Zone Demo", theme=gr.themes.Soft()) as d
192
  analyze_btn = gr.Button("Analyze & Redact", variant="primary")
193
  gr.Markdown("### Try These Examples")
194
  gr.Examples(examples=EXAMPLES, inputs=[input_text, rid_input])
195
-
196
  with gr.Column():
197
  rid_display = gr.Markdown(label="Request ID")
198
  stats_output = gr.Markdown(label="Statistics")
@@ -202,48 +201,40 @@ with gr.Blocks(title="TSZ - Thyris Safe Zone Demo", theme=gr.themes.Soft()) as d
202
  interactive=False
203
  )
204
  detection_report = gr.Markdown(label="Detection Report")
205
-
206
  gr.Markdown("""
207
  ---
208
  ### Placeholder Format
209
-
210
  TSZ uses the format `[RID_TYPE_maskId]` for placeholders:
211
  - **RID**: Request ID for audit correlation
212
  - **TYPE**: Detection type (EMAIL, PHONE, etc.)
213
  - **maskId**: Unique identifier derived from the original value
214
-
215
  Example: `[REQ-001_EMAIL_a1b2c3]`
216
-
217
  This allows you to:
218
  - Track which request generated the redaction
219
  - Identify the type of sensitive data
220
  - Correlate with audit logs for compliance
221
  """)
222
-
223
  analyze_btn.click(fn=analyze_text, inputs=[input_text, rid_input], outputs=[redacted_output, detection_report, stats_output, rid_display])
224
  input_text.submit(fn=analyze_text, inputs=[input_text, rid_input], outputs=[redacted_output, detection_report, stats_output, rid_display])
225
-
226
- # Tab 2: API Reference
227
  with gr.TabItem("πŸ“š API Reference"):
228
  gr.Markdown("""
229
  ## TSZ API Reference
230
-
231
  TSZ is an enterprise-grade PII detection and guardrails gateway. It acts as a zero-trust middleware between your applications and external systems.
232
-
233
  ---
234
-
235
  ### Confidence & Guardrails Model
236
-
237
  | Confidence | Action |
238
  |------------|--------|
239
  | < 0.30 | ALLOW (ignored) |
240
  | 0.30 – 0.85 | MASK (redact) |
241
  | β‰₯ 0.85 | AUTO-BLOCK |
242
-
243
  ---
244
-
245
  ### POST /detect
246
-
247
  **Request:**
248
  ```json
249
  {
@@ -252,7 +243,6 @@ TSZ is an enterprise-grade PII detection and guardrails gateway. It acts as a ze
252
  "guardrails": ["TOXIC_LANGUAGE"]
253
  }
254
  ```
255
-
256
  **Response:**
257
  ```json
258
  {
@@ -278,34 +268,23 @@ TSZ is an enterprise-grade PII detection and guardrails gateway. It acts as a ze
278
  "overall_confidence": "0.78"
279
  }
280
  ```
281
-
282
  ---
283
-
284
  ### Placeholder Format
285
-
286
  TSZ generates unique placeholders in the format:
287
-
288
  ```
289
  [{RID}_{TYPE}_{maskId}]
290
  ```
291
-
292
  - **RID**: Request ID for audit log correlation
293
  - **TYPE**: Detection type (EMAIL, CREDIT_CARD, etc.)
294
  - **maskId**: Hash-based unique identifier
295
-
296
  Example: `[RID-GW-001_EMAIL_a1b2c3]`
297
-
298
  ---
299
-
300
  ### POST /v1/chat/completions
301
-
302
  OpenAI-compatible LLM Gateway with built-in guardrails.
303
-
304
  **Headers:**
305
  - `X-TSZ-RID`: Request ID for audit logs
306
  - `X-TSZ-Guardrails`: Comma-separated validators
307
  - `X-TSZ-Guardrails-Mode`: `final-only` | `stream-sync` | `stream-async`
308
-
309
  **Response with tsz_meta:**
310
  ```json
311
  {
@@ -325,21 +304,15 @@ OpenAI-compatible LLM Gateway with built-in guardrails.
325
  }
326
  }
327
  ```
328
-
329
  ---
330
-
331
  ### Pattern Management
332
-
333
  | Method | Endpoint | Description |
334
  |--------|----------|-------------|
335
  | `POST` | `/patterns` | Create pattern |
336
  | `GET` | `/patterns` | List patterns |
337
  | `DELETE` | `/patterns/{id}` | Delete pattern |
338
-
339
  ---
340
-
341
  ### Validators & Guardrails
342
-
343
  ```json
344
  {
345
  "name": "TOXIC_LANGUAGE",
@@ -348,59 +321,42 @@ OpenAI-compatible LLM Gateway with built-in guardrails.
348
  "expected_response": "NO"
349
  }
350
  ```
351
-
352
  ---
353
-
354
  ### Health & Admin
355
-
356
  | Endpoint | Description |
357
  |----------|-------------|
358
  | `GET /healthz` | Liveness probe |
359
  | `GET /ready` | Readiness probe |
360
  | `POST /admin/reload` | Clear caches |
361
-
362
  ---
363
-
364
  πŸ“– **Full Documentation:** [API_REFERENCE.md](https://github.com/thyrisAI/safe-zone/blob/main/docs/API_REFERENCE.md)
365
  """)
366
-
367
- # Tab 3: Quick Start
368
  with gr.TabItem("πŸš€ Quick Start"):
369
  gr.Markdown("""
370
  ## Get Started with TSZ
371
-
372
  ### Docker (Recommended)
373
-
374
  ```bash
375
  git clone https://github.com/thyrisAI/safe-zone.git
376
  cd safe-zone
377
  docker-compose up -d
378
  ```
379
-
380
  TSZ will be available at `http://localhost:8080`
381
-
382
  ---
383
-
384
  ### Environment Variables
385
-
386
  ```bash
387
  # LLM Gateway Configuration
388
  THYRIS_AI_MODEL_URL=https://api.openai.com/v1
389
  THYRIS_AI_API_KEY=sk-your-key
390
-
391
  # Confidence Thresholds
392
  CONFIDENCE_ALLOW_THRESHOLD=0.30
393
  CONFIDENCE_BLOCK_THRESHOLD=0.85
394
-
395
  # PII Mode
396
  PII_MODE=MASK # or BLOCK
397
  GATEWAY_BLOCK_MODE=BLOCK # BLOCK, MASK, or WARN
398
  ```
399
-
400
  ---
401
-
402
  ### Test with Request ID
403
-
404
  ```bash
405
  curl -X POST http://localhost:8080/detect \\
406
  -H "Content-Type: application/json" \\
@@ -409,7 +365,6 @@ curl -X POST http://localhost:8080/detect \\
409
  "rid": "MY-REQ-001"
410
  }'
411
  ```
412
-
413
  **Response:**
414
  ```json
415
  {
@@ -418,11 +373,8 @@ curl -X POST http://localhost:8080/detect \\
418
  "contains_pii": true
419
  }
420
  ```
421
-
422
  ---
423
-
424
  ### Architecture
425
-
426
  ```
427
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
428
  β”‚ Your App │────▢│ TSZ │────▢│ LLM API β”‚
@@ -433,21 +385,15 @@ curl -X POST http://localhost:8080/detect \\
433
  β”‚ β”‚ (with RID)β”‚
434
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
435
  ```
436
-
437
  ---
438
-
439
  πŸ“– **Documentation:** [github.com/thyrisAI/safe-zone/docs](https://github.com/thyrisAI/safe-zone/tree/main/docs)
440
  """)
441
-
442
- # Tab 4: About
443
  with gr.TabItem("ℹ️ About"):
444
  gr.Markdown("""
445
  ## About TSZ (Thyris Safe Zone)
446
-
447
  Developed by **Thyris.AI** as an open-source enterprise AI security solution.
448
-
449
  ### Key Features
450
-
451
  | Feature | Description |
452
  |---------|-------------|
453
  | **Hybrid Detection** | Regex + AI-powered confidence scoring |
@@ -455,13 +401,9 @@ Developed by **Thyris.AI** as an open-source enterprise AI security solution.
455
  | **LLM Gateway** | OpenAI-compatible proxy |
456
  | **Streaming Support** | sync/async modes for SSE |
457
  | **Guardrails** | AI validators (toxic, schema, custom) |
458
-
459
  ---
460
-
461
  ### Placeholder System
462
-
463
  Each redacted value gets a unique, traceable placeholder:
464
-
465
  ```
466
  [RID-GW-001_EMAIL_a1b2c3]
467
  β”‚ β”‚ β”‚
@@ -469,27 +411,22 @@ Each redacted value gets a unique, traceable placeholder:
469
  β”‚ └── Detection type
470
  └── Request ID for correlation
471
  ```
472
-
473
  Benefits:
474
  - Full audit trail
475
  - SIEM integration
476
  - Compliance reporting
477
  - Debug & investigation
478
-
479
  ---
480
-
481
  ### Compliance Ready
482
-
483
  - βœ… GDPR (EU)
484
  - βœ… KVKK (Turkey)
485
  - βœ… CCPA (California)
486
  - βœ… HIPAA (Healthcare)
487
  - βœ… PCI-DSS (Payment)
488
-
489
  ---
490
-
491
  Built with ❀️ by [Thyris.AI](https://thyris.ai)
492
  """)
493
 
 
494
  if __name__ == "__main__":
495
  demo.launch()
 
5
  Website: https://thyris.ai
6
  """
7
 
8
+ import gradio as gr
9
  import re
10
  import uuid
11
  import hashlib
12
  from dataclasses import dataclass
13
  from typing import List, Tuple
14
 
15
+
16
  @dataclass
17
  class Detection:
18
  type: str
 
23
  confidence: str
24
  mask_id: str
25
 
26
+
27
  class TSZDetector:
28
  PATTERNS = {
29
  "EMAIL": {
 
75
  "description": "JSON Web Tokens"
76
  }
77
  }
78
+
79
  def _generate_mask_id(self, value: str) -> str:
80
  """Generate a short unique mask ID based on value hash"""
81
  hash_val = hashlib.md5(value.encode()).hexdigest()[:6]
82
  return hash_val
83
+
84
  def detect(self, text: str, rid: str = "NO-RID") -> Tuple[List[Detection], str]:
85
  detections = []
86
  redacted_text = text
87
  type_counters = {}
88
+
89
  for pii_type, config in self.PATTERNS.items():
90
  pattern = config["pattern"]
91
  for match in re.finditer(pattern, text, re.IGNORECASE):
92
  value = match.group()
93
  if pii_type == "TC_KIMLIK" and len(value) != 11:
94
  continue
95
+
 
96
  if pii_type not in type_counters:
97
  type_counters[pii_type] = 0
98
  type_counters[pii_type] += 1
99
+
100
  mask_id = self._generate_mask_id(value)
 
 
101
  placeholder = f"[{rid}_{pii_type}_{mask_id}]"
102
+
103
  detections.append(Detection(
104
  type=pii_type,
105
  value=value,
 
109
  confidence="HIGH" if len(value) > 8 else "MEDIUM",
110
  mask_id=mask_id
111
  ))
112
+
 
113
  detections.sort(key=lambda x: x.start, reverse=True)
114
  for det in detections:
115
  redacted_text = redacted_text[:det.start] + det.placeholder + redacted_text[det.end:]
116
+
 
117
  detections.sort(key=lambda x: x.start)
 
118
  return detections, redacted_text
119
 
120
+
121
  detector = TSZDetector()
122
 
123
+
124
  def analyze_text(text: str, rid: str) -> Tuple[str, str, str, str]:
125
  if not text.strip():
126
  return "", "Please enter some text to analyze.", "", ""
127
+
 
128
  if not rid.strip():
129
  rid = f"TSZ-{uuid.uuid4().hex[:8].upper()}"
130
+
131
  detections, redacted_text = detector.detect(text, rid)
132
+
133
  if not detections:
134
  return text, "No sensitive information detected.", "**0** PII entities found", f"Request ID: `{rid}`"
135
+
136
  report_lines = ["### Detected Entities\n"]
137
  by_type = {}
138
  for det in detections:
139
  if det.type not in by_type:
140
  by_type[det.type] = []
141
  by_type[det.type].append(det)
142
+
143
  for pii_type, items in by_type.items():
144
  desc = detector.PATTERNS[pii_type]["description"]
145
  report_lines.append(f"\n**{pii_type}** ({desc})")
 
147
  masked_value = item.value[:3] + "***" + item.value[-2:] if len(item.value) > 5 else "***"
148
  report_lines.append(f"- `{masked_value}` β†’ `{item.placeholder}`")
149
  report_lines.append(f" - Mask ID: `{item.mask_id}` | Confidence: {item.confidence}")
150
+
151
  report = "\n".join(report_lines)
152
  stats = f"**{len(detections)}** PII entities found across **{len(by_type)}** categories"
153
  rid_display = f"Request ID: `{rid}`"
154
+
155
  return redacted_text, report, stats, rid_display
156
 
157
+
158
  EXAMPLES = [
159
  ["Hi, my name is John Smith and my email is john.smith@company.com. You can reach me at +1-555-123-4567. My SSN is 123-45-6789.", "REQ-001"],
160
  ["Customer Order #12345\nName: Jane Doe\nEmail: jane.doe@example.org\nPhone: (555) 987-6543\nCredit Card: 4532015112830366", "ORDER-12345"],
 
162
  ["Merhaba, ben Ahmet Yilmaz. TC Kimlik numaram 12345678901.\nTelefon: 0532 123 45 67\nIBAN: TR330006100519786457841326", "TR-REQ-001"],
163
  ]
164
 
165
+
166
  with gr.Blocks(title="TSZ - Thyris Safe Zone Demo", theme=gr.themes.Soft()) as demo:
167
+
168
  gr.Markdown("""
169
  # πŸ›‘οΈ TSZ (Thyris Safe Zone)
170
  **Enterprise-grade PII detection and guardrails gateway** that prevents sensitive data from leaking to LLMs and third-party APIs.
171
+
172
  [![GitHub](https://img.shields.io/badge/GitHub-Repository-black?logo=github)](https://github.com/thyrisAI/safe-zone)
173
  [![Website](https://img.shields.io/badge/Website-thyris.ai-blue)](https://thyris.ai)
174
  [![License](https://img.shields.io/badge/License-Apache%202.0-green)](https://github.com/thyrisAI/safe-zone/blob/main/LICENSE)
175
  """)
176
+
177
  with gr.Tabs():
 
178
  with gr.TabItem("οΏ½οΏ½ Interactive Demo"):
179
  with gr.Row():
180
  with gr.Column():
 
191
  analyze_btn = gr.Button("Analyze & Redact", variant="primary")
192
  gr.Markdown("### Try These Examples")
193
  gr.Examples(examples=EXAMPLES, inputs=[input_text, rid_input])
194
+
195
  with gr.Column():
196
  rid_display = gr.Markdown(label="Request ID")
197
  stats_output = gr.Markdown(label="Statistics")
 
201
  interactive=False
202
  )
203
  detection_report = gr.Markdown(label="Detection Report")
204
+
205
  gr.Markdown("""
206
  ---
207
  ### Placeholder Format
208
+
209
  TSZ uses the format `[RID_TYPE_maskId]` for placeholders:
210
  - **RID**: Request ID for audit correlation
211
  - **TYPE**: Detection type (EMAIL, PHONE, etc.)
212
  - **maskId**: Unique identifier derived from the original value
213
+
214
  Example: `[REQ-001_EMAIL_a1b2c3]`
215
+
216
  This allows you to:
217
  - Track which request generated the redaction
218
  - Identify the type of sensitive data
219
  - Correlate with audit logs for compliance
220
  """)
221
+
222
  analyze_btn.click(fn=analyze_text, inputs=[input_text, rid_input], outputs=[redacted_output, detection_report, stats_output, rid_display])
223
  input_text.submit(fn=analyze_text, inputs=[input_text, rid_input], outputs=[redacted_output, detection_report, stats_output, rid_display])
224
+
 
225
  with gr.TabItem("πŸ“š API Reference"):
226
  gr.Markdown("""
227
  ## TSZ API Reference
 
228
  TSZ is an enterprise-grade PII detection and guardrails gateway. It acts as a zero-trust middleware between your applications and external systems.
 
229
  ---
 
230
  ### Confidence & Guardrails Model
 
231
  | Confidence | Action |
232
  |------------|--------|
233
  | < 0.30 | ALLOW (ignored) |
234
  | 0.30 – 0.85 | MASK (redact) |
235
  | β‰₯ 0.85 | AUTO-BLOCK |
 
236
  ---
 
237
  ### POST /detect
 
238
  **Request:**
239
  ```json
240
  {
 
243
  "guardrails": ["TOXIC_LANGUAGE"]
244
  }
245
  ```
 
246
  **Response:**
247
  ```json
248
  {
 
268
  "overall_confidence": "0.78"
269
  }
270
  ```
 
271
  ---
 
272
  ### Placeholder Format
 
273
  TSZ generates unique placeholders in the format:
 
274
  ```
275
  [{RID}_{TYPE}_{maskId}]
276
  ```
 
277
  - **RID**: Request ID for audit log correlation
278
  - **TYPE**: Detection type (EMAIL, CREDIT_CARD, etc.)
279
  - **maskId**: Hash-based unique identifier
 
280
  Example: `[RID-GW-001_EMAIL_a1b2c3]`
 
281
  ---
 
282
  ### POST /v1/chat/completions
 
283
  OpenAI-compatible LLM Gateway with built-in guardrails.
 
284
  **Headers:**
285
  - `X-TSZ-RID`: Request ID for audit logs
286
  - `X-TSZ-Guardrails`: Comma-separated validators
287
  - `X-TSZ-Guardrails-Mode`: `final-only` | `stream-sync` | `stream-async`
 
288
  **Response with tsz_meta:**
289
  ```json
290
  {
 
304
  }
305
  }
306
  ```
 
307
  ---
 
308
  ### Pattern Management
 
309
  | Method | Endpoint | Description |
310
  |--------|----------|-------------|
311
  | `POST` | `/patterns` | Create pattern |
312
  | `GET` | `/patterns` | List patterns |
313
  | `DELETE` | `/patterns/{id}` | Delete pattern |
 
314
  ---
 
315
  ### Validators & Guardrails
 
316
  ```json
317
  {
318
  "name": "TOXIC_LANGUAGE",
 
321
  "expected_response": "NO"
322
  }
323
  ```
 
324
  ---
 
325
  ### Health & Admin
 
326
  | Endpoint | Description |
327
  |----------|-------------|
328
  | `GET /healthz` | Liveness probe |
329
  | `GET /ready` | Readiness probe |
330
  | `POST /admin/reload` | Clear caches |
 
331
  ---
 
332
  πŸ“– **Full Documentation:** [API_REFERENCE.md](https://github.com/thyrisAI/safe-zone/blob/main/docs/API_REFERENCE.md)
333
  """)
334
+
 
335
  with gr.TabItem("πŸš€ Quick Start"):
336
  gr.Markdown("""
337
  ## Get Started with TSZ
 
338
  ### Docker (Recommended)
 
339
  ```bash
340
  git clone https://github.com/thyrisAI/safe-zone.git
341
  cd safe-zone
342
  docker-compose up -d
343
  ```
 
344
  TSZ will be available at `http://localhost:8080`
 
345
  ---
 
346
  ### Environment Variables
 
347
  ```bash
348
  # LLM Gateway Configuration
349
  THYRIS_AI_MODEL_URL=https://api.openai.com/v1
350
  THYRIS_AI_API_KEY=sk-your-key
 
351
  # Confidence Thresholds
352
  CONFIDENCE_ALLOW_THRESHOLD=0.30
353
  CONFIDENCE_BLOCK_THRESHOLD=0.85
 
354
  # PII Mode
355
  PII_MODE=MASK # or BLOCK
356
  GATEWAY_BLOCK_MODE=BLOCK # BLOCK, MASK, or WARN
357
  ```
 
358
  ---
 
359
  ### Test with Request ID
 
360
  ```bash
361
  curl -X POST http://localhost:8080/detect \\
362
  -H "Content-Type: application/json" \\
 
365
  "rid": "MY-REQ-001"
366
  }'
367
  ```
 
368
  **Response:**
369
  ```json
370
  {
 
373
  "contains_pii": true
374
  }
375
  ```
 
376
  ---
 
377
  ### Architecture
 
378
  ```
379
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
380
  β”‚ Your App │────▢│ TSZ │────▢│ LLM API β”‚
 
385
  β”‚ β”‚ (with RID)β”‚
386
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
387
  ```
 
388
  ---
 
389
  πŸ“– **Documentation:** [github.com/thyrisAI/safe-zone/docs](https://github.com/thyrisAI/safe-zone/tree/main/docs)
390
  """)
391
+
 
392
  with gr.TabItem("ℹ️ About"):
393
  gr.Markdown("""
394
  ## About TSZ (Thyris Safe Zone)
 
395
  Developed by **Thyris.AI** as an open-source enterprise AI security solution.
 
396
  ### Key Features
 
397
  | Feature | Description |
398
  |---------|-------------|
399
  | **Hybrid Detection** | Regex + AI-powered confidence scoring |
 
401
  | **LLM Gateway** | OpenAI-compatible proxy |
402
  | **Streaming Support** | sync/async modes for SSE |
403
  | **Guardrails** | AI validators (toxic, schema, custom) |
 
404
  ---
 
405
  ### Placeholder System
 
406
  Each redacted value gets a unique, traceable placeholder:
 
407
  ```
408
  [RID-GW-001_EMAIL_a1b2c3]
409
  β”‚ β”‚ β”‚
 
411
  β”‚ └── Detection type
412
  └── Request ID for correlation
413
  ```
 
414
  Benefits:
415
  - Full audit trail
416
  - SIEM integration
417
  - Compliance reporting
418
  - Debug & investigation
 
419
  ---
 
420
  ### Compliance Ready
 
421
  - βœ… GDPR (EU)
422
  - βœ… KVKK (Turkey)
423
  - βœ… CCPA (California)
424
  - βœ… HIPAA (Healthcare)
425
  - βœ… PCI-DSS (Payment)
 
426
  ---
 
427
  Built with ❀️ by [Thyris.AI](https://thyris.ai)
428
  """)
429
 
430
+
431
  if __name__ == "__main__":
432
  demo.launch()