sender-id-registry-service — AI Integration
Version: 1.0 Status: Draft Owner: Trust & Safety + Regulator-facing Last Updated: 2026-04-21 Companion: SECURITY_MODEL · APPLICATION_LOGIC · services/compliance-engine/AI_INTEGRATION.md
1. Purpose
sender-id-registry-service uses AI strictly as decision support for human reviewers, never as a primary decision-maker. The KYC and verification workflows are human-controlled (US-SID-002, US-SID-004, US-SID-008). AI lowers reviewer cognitive load and surfaces high-risk submissions, but the final approval, rejection, suspension, and revocation decisions are made by accountable humans with audit trails.
The three AI use cases:
- Registrant-name impersonation detection — flag submissions whose
valueis suspiciously close to existing high-trust sender-IDs (typo-squatting, homoglyph attack, restricted-pattern bypass attempt). - KYC document OCR + structural validation — extract key fields, sanity-check consistency between documents, flag potential forgery indicators.
- Restricted-name fuzzy matching — augment the regex-based
RestrictedPatternmatcher with embedding similarity to catch creative obfuscations (B4NK,8ANK,BANCK).
All three are local-only — no KYC document content ever crosses the trust boundary. This is a non-negotiable constraint following NIST SP 800-122 (Guide to Protecting Personally Identifiable Information) and consistent with the data-residency posture established for the broader platform.
2. Provider strategy — local-only
| Provider | Status | Use case |
|---|---|---|
| Local LLM (self-hosted) | Primary and only | All three use cases, served by the shared local-llm deployment described in services/compliance-engine/AI_INTEGRATION §3 |
| Local OCR (Tesseract / PaddleOCR + GPU) | Primary | KYC OCR; runs in sid-kyc-ocr sidecar pod |
| Local embedding model (BGE-M3 multilingual) | Primary | Fuzzy matching for restricted-name detection |
| External LLM | Forbidden | Cloud LLM calls on KYC content are explicitly disallowed by Security policy |
The local-LLM deployment is shared with compliance-engine (per services/compliance-engine/DEPLOYMENT_TOPOLOGY.md); sender-id-registry-service calls it as a separate logical client with its own concurrency budget.
3. Use case 1 — Registrant-name impersonation detection (Reviewer hint)
When invoked: At submission time (UC-01) and again when reviewer claims (UC-02), the service computes a similarity score between value and the top-1000 high-trust active sender-IDs (defined as: category ∈ {BANKING, GOVERNMENT, HEALTHCARE, MNO_INTERNAL} AND currentVerificationLevel = NOTARISED).
How:
- Embedding model: BGE-M3 (multilingual) embedding of
value+registrantOrgName. - Cosine similarity against pre-computed embeddings of high-trust sender-IDs (refreshed nightly, indexed in pgvector).
- Threshold: similarity ≥ 0.88 ⇒ flag as
IMPERSONATION_RISK.
Output: { impersonationRiskScore: 0..1, matchedHighTrustValues: [...] } attached to the reviewer-queue row in admin-dashboard. Does not block submission; reviewer sees a warning banner.
HITL: Reviewer reviews the matched candidates and decides. The AI flag is recorded in the audit row with evidence field.
4. Use case 2 — KYC document OCR + structural validation
When invoked: Asynchronously after KYC document upload completes (UC-01 step 7).
Pipeline:
S3 KYC blob
│
▼
sid-kyc-ocr sidecar (PaddleOCR-en + PaddleOCR-ar/fa for Pashto/Dari)
│ Extracts text + structure (tables, signatures, stamps)
▼
Structural validator (Python pydantic models per docType)
│ Validates: licence number format, issuing authority, expiry date, signatures present
▼
Local LLM (Qwen2.5-7B-Instruct) — structured prompt
│ Returns JSON: { extractedFields, anomalies, forgeryIndicators }
▼
Persist to kyc_documents.verification_notes (machine-prefixed)
│
▼
Reviewer sees AI-extracted fields + flags in admin-dashboard inline view
Forgery indicators the LLM is asked to flag (not to determine — to flag for human review):
- Inconsistent fonts within official-document fields (cut-and-paste artefacts).
- Mismatched issue date vs document version known for that authority.
- Photoshop/edit metadata in image documents (jpegtran/exiftool).
- Watermark or seal absent where expected for the given authority.
- OCR confidence < 0.6 on critical fields.
Output schema:
{
"version": "1.0",
"model": "qwen2.5-7b-instruct-awq",
"extractedFields": {
"licenceNumber": "BL-2025-04829",
"issuingAuthority": "Afghanistan Investment Support Agency",
"issuedTo": "Da Afghanistan Bank",
"expiryDate": "2027-03-15",
"ocrConfidence": 0.94
},
"anomalies": [],
"forgeryIndicators": [
{
"type": "FONT_INCONSISTENCY",
"severity": "MEDIUM",
"evidence": "Field 'expiryDate' uses Arial; surrounding fields use Times New Roman"
}
],
"reviewerHint": "Inspect the expiry-date field carefully — font mismatch may indicate edit."
}
HITL: Reviewer ALWAYS makes the final decision. AI output attached to kyc_documents.verification_notes with [AI-ASSIST] prefix. Reviewer can flag AI output as wrong (true/false positive) — feedback feeds the quarterly model evaluation cycle.
5. Use case 3 — Restricted-name fuzzy matching
Why: Regex-based RestrictedPattern catches BANK* but not B4NK, 8ANK, BAЛK (Cyrillic homoglyph), B-A-N-K. These are common impersonation attempts.
How:
- At submission time, compute embedding of
value(BGE-M3). - Cosine similarity against pre-computed embeddings of every active
RestrictedPattern.categoryrepresentative anchor (e.g. anchor forBANK= embedding of "BANK"; anchor forGOV= embedding of "GOVERNMENT"). - If similarity ≥ 0.82 to any restricted anchor, treat the submission as if it matched the restricted pattern — escalate to
requiredVerificationLevel = NOTARISED+ regulator letter. - Flag submission with
restrictedFuzzyMatch: { anchor, score }so reviewer sees both the regex outcome and the embedding outcome.
False-positive guard: If embedding triggers but regex does not, reviewer can override after manual inspection. Override is audited and feeds the threshold-tuning loop.
6. Prompt template — KYC OCR validation
System:
You are an SMS gateway compliance assistant. Given OCR-extracted text from a KYC
document, return a JSON object with the following keys:
- extractedFields: a map of canonical field names to detected values
- anomalies: list of structural inconsistencies you detected
- forgeryIndicators: list of objects { type, severity (LOW|MEDIUM|HIGH), evidence }
- reviewerHint: a single concise sentence advising the human reviewer
Do NOT make final approval/rejection decisions. Your output is one input to a
human reviewer who will make the final call.
Document type: {{docType}}
Expected fields: {{expectedFields}}
User:
{{ocrText}}
Constraint-decoded to JSON schema. No free-text reasoning channel. The system prompt is fixed and stored in source control; tampering with the prompt would require a code change.
7. Moderation policy
- No KYC content sent to external services. Enforced by NetworkPolicy: the
sender-id-registry-serviceandsid-kyc-ocrpods cannot egress except tolocal-llmand platform-internal services. - Anonymisation before LLM. OCR text passes through a phone-number / email / national-ID redactor before being included in the LLM prompt. The redacted version is what the LLM sees; the unredacted version stays in the OCR sidecar memory and is never persisted beyond the verification note.
- Output sanitisation. LLM output is parsed against a Zod schema; non-conformant output triggers a
kyc_ocr_llm_invalid_output_totalmetric increment and is treated as "no AI signal" — the document goes to reviewer with no AI assist. - No fine-tuning on real KYC. Any future fine-tuning uses synthetic KYC documents only. Real customer KYC is never used as training data.
8. HITL flow
Submission → KYC upload
│
▼
[Async] sid-kyc-ocr → extract text
│
▼
[Async] local-llm → analyse + flag
│
▼
Persist AI-assist record (kyc_documents.verification_notes)
│
▼
Reviewer queue surfaces submission with:
- regex restricted-pattern match (deterministic)
- embedding similarity score (AI)
- OCR-extracted fields (AI)
- forgery indicators (AI)
- impersonation similarity to high-trust senders (AI)
│
▼
Reviewer (HUMAN) makes APPROVE / REJECT / REQUEST_INFO decision
- Decision audit row records: aiSignals[], reviewerOverride (yes/no)
│
▼
For NOTARISED level: dual-control second reviewer (UC-06)
The AI output is advisory only. Removing the AI layer would not block any registration (degrades reviewer experience but preserves correctness).
9. AIProvenance touch points
Every AI signal is captured in an AIProvenance record attached to the AuditEntry:
{
"model": "qwen2.5-7b-instruct-awq",
"modelVersion": "20260301",
"prompt": "kyc_ocr_validation_v1.2",
"promptHash": "sha256:...",
"executedAt": "2026-04-21T08:14:02Z",
"executedAtRegion": "kbl",
"inputHash": "sha256:..." ,
"outputHash": "sha256:...",
"latencyMs": 412,
"cached": false
}
This satisfies the platform-wide AIProvenance VO requirement so any AI-assisted decision can be reproduced and audited.
10. Capacity & latency budget
| Operation | Budget | Notes |
|---|---|---|
| Embedding (BGE-M3) | P95 ≤ 50 ms | Runs synchronously at submission |
| OCR (PaddleOCR + GPU) | P95 ≤ 5 s for ≤ 5 MB doc | Async — does not block submission |
| LLM KYC analysis | P95 ≤ 800 ms | Async |
| Cache hit rate (LLM responses) | ≥ 70% | Cached on sha256(redactedOcrText) |
GPU utilisation shared with compliance-engine; sender-ID workload is bursty (registration-triggered) not continuous.
11. Monitoring AI usage
| Metric | Target |
|---|---|
sid_ai_kyc_ocr_duration_seconds{quantile=0.95} | ≤ 5 s |
sid_ai_llm_kyc_validation_duration_seconds{quantile=0.95} | ≤ 800 ms |
sid_ai_impersonation_flag_total | tracked; correlate with reviewer override rate |
sid_ai_restricted_fuzzy_match_total | tracked; weekly false-positive review |
sid_ai_llm_invalid_output_total | ≤ 1% of LLM calls |
| `sid_ai_reviewer_override_total{ai_signal_type, agreed=true | false}` |
12. Quarterly accuracy audit
- Impersonation detection precision/recall measured against a labelled set of historical submissions curated by Trust & Safety.
- OCR field extraction accuracy measured against ground-truth-labelled KYC samples (synthetic + opted-in real).
- Forgery indicator true-positive / false-positive rate reviewed quarterly; threshold tuning fed back to system prompt revision.
- Restricted fuzzy-match threshold tuning — adjust the 0.82 cosine cutoff if false-positive rate exceeds 5%.
13. Future enhancements
| Enhancement | Rationale | Timeline |
|---|---|---|
| Fine-tuned KYC-domain classifier on synthetic Afghan-document corpus | Lower latency and higher accuracy on country-specific document formats | 2027 Q1 |
| Cross-tenant impersonation graph (sender-ID + registrant-org embedding clusters) | Detect coordinated impersonation campaigns across multiple submissions | 2027 Q2 |
| Active learning loop: reviewer disagreement = labelled training signal | Continuous quality improvement | 2027 |
| Document-language detection routing (Pashto/Dari/Arabic-specific OCR pipelines) | Improve OCR confidence on non-Latin documents | 2026 Q4 |