Docs
Put the Tamga proxy in front of your app, configure the policy, and monitor findings on the dashboard.
1. Quickstart
Tamga is a reverse-proxy placed in front of LLM provider traffic. The only change you make in your application is using the proxy URL instead of the provider URL. No SDK changes, no code changes — just update the base URL.
Docker Compose
# docker-compose.yml
version: "3.9"
services:
tamga:
image: ghcr.io/tamga-dev/tamga:latest
environment:
- TAMGA_ADMIN_KEY=change-me
- TAMGA_UPSTREAM_OPENAI=https://api.openai.com
- TAMGA_UPSTREAM_ANTHROPIC=https://api.anthropic.com
- TAMGA_UPSTREAM_GEMINI=https://generativelanguage.googleapis.com
ports:
- "8443:8443"
volumes:
- ./policy.yaml:/etc/tamga/policy.yaml
- tamga-data:/var/lib/tamga
volumes:
tamga-data:Application side
# Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="http://tamga:8443/v1", # ← the only change
api_key="your-openai-key",
)
# Go
// Every OpenAI-compatible SDK works
// OPENAI_BASE_URL=http://tamga:8443/v1First request
curl -X POST http://localhost:8443/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Merhaba, TC kimlik numaram 12345678901"}]
}'
# Response:
# {
# "choices": [{
# "message": {
# "content": "Merhaba, TC kimlik numaram [REDACTED-TC_KIMLIK]"
# }
# }],
# "x-tamga-action": "REDACT",
# "x-tamga-findings": "pii:tc_kimlik"
# }2. Architecture
Tamga runs inline between your application and the LLM provider. Each request passes through three scanning stages:
Scanning engine
- Aho-Corasick DFA — multi-pattern substring matching, O(n+m) complexity
- Regex engine — 200+ patterns (PII, secret, injection, custom patterns)
- BIN/IIN radix lookup — credit card issuer validation (Luhn + bank match)
- MERNIS checksum — Turkish ID number algorithmic verification
- Shadow ML sidecar — Piiranha (HuggingFace) integration, optional GPU acceleration
Latency budget
| Stage | p50 | p95 | p99 |
|---|---|---|---|
| Regex scan | < 0.3ms | < 1.2ms | < 2.0ms |
| DFA pattern match | < 0.1ms | < 0.4ms | < 0.8ms |
| Policy evaluation | < 0.05ms | < 0.1ms | < 0.2ms |
| BIN/Checksum | < 0.2ms | < 0.6ms | < 1.0ms |
| ML sidecar (opt.) | ~4ms | ~12ms | ~25ms |
| Total (regex only) | < 0.8ms | < 2.5ms | < 5.0ms |
3. Policy model
Policy is defined via policy.yaml. Each rule applies to a finding type/category and produces one of four actions:
Example policy
name: default
rules:
- id: block-secrets
when: { type: secret }
action: BLOCK
- id: redact-pii-tr
when: { type: pii, category_in: [tc_kimlik, phone_tr, credit_card, iban_tr] }
action: REDACT
- id: block-injection
when: { type: injection, confidence_gte: 80 }
action: BLOCK
- id: log-internal
when: { type: pii, user_in: ["internal-*"] }
action: LOG
- id: pass-low-conf
when: { type: pii, confidence_lt: 50 }
action: PASSRule ordering
Rules are evaluated top-to-bottom. The first matching rule is applied. If multiple findings trigger on the same request, the highest-priority action wins (BLOCK > REDACT > LOG > PASS).
Try it live in the Policy Simulator or the dashboard Playground.
4. Finding types
The Tamga scanner detects four main finding types:
| Type | Categories | Description |
|---|---|---|
| pii | tc_kimlik, phone_tr, credit_card, iban_tr, email, ip_address, passport_tr, health_id | Personally identifiable information (PII) detection |
| secret | api_key, github_token, aws_key, jwt, private_key, db_connection, slack_token | Hardcoded secret/credential detection |
| injection | prompt_injection, jailbreak, dan, encoding_obfuscation, delimiter_attack | Prompt injection and jailbreak attempts |
| custom | regex(pattern), keyword(word_list), context(proximity_rules) | User-defined custom patterns |
Confidence scoring
Each finding comes with a 0–100 confidence score. The score is calculated from regex match precision, checksum validation, context proximity, and ML model output.
- ≥ 95 — high confidence, suitable for auto BLOCK
- ≥ 80 — medium-high confidence, suitable for REDACT
- ≥ 50 — low-medium confidence, suitable for LOG
- < 50 — low confidence, PASS or manual review
5. Integration
Tamga is wire-compatible with the OpenAI API specification. All supported endpoints:
Provider support
| Provider | Endpoint | Models |
|---|---|---|
| OpenAI | /v1 | gpt-4o, gpt-4.1, o4-mini, o3 |
| Anthropic | /v1 (Messages API) | claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5 |
| Google Gemini | /v1 | gemini-2.5-pro, gemini-2.0-flash |
| Azure OpenAI | /v1 | gpt-4o, gpt-4.1-mini (Azure deployment) |
| AWS Bedrock | /v1 | claude, llama (via Bedrock) |
| Mistral | /v1 | mistral-large, mixtral, codestral |
| Groq | /v1 | llama-4-maverick, mixtral (LPU inference) |
| DeepSeek | /v1 | deepseek-v4, deepseek-r1 |
| xAI | /v1 | grok-3 |
| Together | /v1 | llama-4, mixtral (open-source) |
| Ollama | /v1 | self-hosted (her model) |
SDK examples
# Python
from openai import OpenAI
client = OpenAI(base_url="https://proxy.tamga.dev/v1", api_key="...")
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "..."}],
extra_headers={"X-Tamga-Policy": "strict"},
)
# JavaScript / TypeScript
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://proxy.tamga.dev/v1" });
# Go
// OPENAI_BASE_URL=https://proxy.tamga.dev/v1 go run .
// the SDK reads the environment variable automatically
# cURL
curl https://proxy.tamga.dev/v1/chat/completions \
-H "Authorization: Bearer sk-..." \
-H "X-Tamga-Policy: default" \
-d '{"model":"gpt-4o","messages":[...]}'Custom headers
| Header | Description |
|---|---|
| X-Tamga-Policy | Policy name to use (default: "default") |
| X-Tamga-Action | Response: PASS / LOG / REDACT / BLOCK |
| X-Tamga-Findings | Response: comma-separated finding list |
| X-Tamga-Confidence | Response: highest confidence score (0–100) |
| X-Tamga-Trace-Id | Response: request trace ID (for audit log) |
6. Admin API
All management endpoints require X-Tamga-Admin-Key or a scoped API key.
Stats & Metrics
| Endpoint | Description |
|---|---|
| GET /api/v1/stats | Total, blocked, redacted, pass counters. Query: ?range=24h|7d|30d |
| GET /api/v1/timeseries | Hourly/daily traffic + finding series. ?range=&granularity=hour|day |
| GET /api/v1/findings/breakdown | Finding type/category distribution. ?range=&group_by=type|category |
| GET /api/v1/metrics | Prometheus exposition format (/metrics) |
Events & Incidents
| Endpoint | Description |
|---|---|
| GET /api/v1/events | Paged event list. ?page=&limit=&action=&type=&category=&provider=&since= |
| GET /api/v1/events/export | CSV/JSON export. ?format=csv|json&range= |
| GET /api/v1/live/events | Server-Sent Events live stream (text/event-stream) |
| GET /api/v1/incidents | Incident list. ?status=open|in_progress|closed|false_positive |
| PUT /api/v1/incidents/:id | Incident status update (status, assignee, comment) |
| GET /api/v1/auditlog | Audit trail. ?request_id=&user=&action=&since= |
Policy Management
| Endpoint | Description |
|---|---|
| GET /api/v1/policies | List all policies |
| PUT /api/v1/policies/:name | Create/update policy (YAML body) |
| DELETE /api/v1/policies/:name | Delete policy |
| POST /api/v1/policies/simulate | Policy simulation: policy YAML + test payload → findings |
| GET /api/v1/policies/:name/history | Policy revision history |
7. Webhooks
Tamga delivers finding events to external systems via HTTP POST. Each webhook can filter for one or more finding types/categories.
Supported integrations
Payload format
{
"event": "finding.detected",
"timestamp": "2026-06-12T10:30:00Z",
"request_id": "req_abc123",
"provider": "openai",
"model": "gpt-4o",
"findings": [
{
"type": "pii",
"category": "tc_kimlik",
"confidence": 97,
"action": "REDACT",
"position": { "start": 42, "end": 53 }
}
],
"action": "REDACT",
"scan_latency_ms": 2.3
}8. Deployment
Self-hosted
# Docker (tek konteyner) docker run -d --name tamga \ -p 8443:8443 \ -e TAMGA_ADMIN_KEY=change-me \ -e TAMGA_UPSTREAM_OPENAI=https://api.openai.com \ -v ./policy.yaml:/etc/tamga/policy.yaml \ ghcr.io/tamga-dev/tamga:latest # Kubernetes kubectl apply -f https://docs.tamga.dev/deploy/k8s.yaml # Systemd (bare metal) # Bkz: https://docs.tamga.dev/deploy/systemd
Environment variables
| Variable | Required | Description |
|---|---|---|
| TAMGA_ADMIN_KEY | Yes | Admin API and dashboard access key |
| TAMGA_UPSTREAM_OPENAI | No | OpenAI upstream URL |
| TAMGA_UPSTREAM_ANTHROPIC | No | Anthropic upstream URL |
| TAMGA_UPSTREAM_GEMINI | No | Google Gemini upstream URL |
| TAMGA_POLICY_PATH | No | policy.yaml file path (default: /etc/tamga/policy.yaml) |
| TAMGA_DATA_DIR | No | Data directory (default: /var/lib/tamga) |
| TAMGA_LOG_LEVEL | No | Log level: debug/info/warn/error (default: info) |
| TAMGA_PORT | No | Proxy port (default: 8443) |
| TAMGA_ML_SIDECAR_URL | No | ML sidecar URL (e.g. unix:///run/tamga/ml.sock) |
Resource requirements
| Tier | CPU | RAM | Throughput |
|---|---|---|---|
| Minimal (regex only) | 1 vCPU | 256 MB | ~500 req/s |
| Standard | 2 vCPU | 512 MB | ~2000 req/s |
| ML sidecar URL (e.g. unix:///run/tamga/ml.sock) | 4 vCPU + GPU (opt.) | 2 GB + 4 GB VRAM | ~200 req/s (ML path) |
9. Compliance
OWASP LLM Top 10
Tamga's scanning matrix is mapped to OWASP LLM Top 10 (LLM01–LLM10):
- LLM01: Prompt Injection — injection/jailbreak detection
- LLM02: Insecure Output Handling — output scan, canary token detection
- LLM03: Training Data Poisoning — Shadow ML feedback loop monitoring
- LLM04: Model Denial of Service — rate limiting, token budget enforcement
- LLM05: Supply Chain — model/provider inventory, audit log
- LLM06: Sensitive Info Disclosure — PII/secret REDACT engine
- LLM07: Insecure Plugin Design — action-level policy rules
- LLM08: Excessive Agency — BLOCK on high-risk action patterns
- LLM09: Overreliance — confidence scoring, human-in-the-loop
- LLM10: Model Theft — request logging, anomaly detection
KVKK & GDPR
PII regex sets cover common categories under KVKK (Turkish Data Protection Law) and GDPR:
Certification status
- SOC 2 Type II — in preparation (2026 Q3 target)
- ISO 27001 — in certification process (2026 Q4 target)
- KVKK VERBIS — registration complete
- PCI-DSS — SAQ-A compliant (proxy PII masking)
- OWASP — LLM Top 10 2025 compliant
For more information: Trust Center · KVKK · Privacy Policy · DPA
