Skip to main content

KYC Validation

Agent-TS includes multi-layer KYC document validation with OCR extraction, OpenAI Vision verification, and fraud detection for Sierra Leone National ID cards.

Validation Pipeline

OCR Service

The OCR service uses Tesseract.js to extract text and compute confidence scores.

Extracted Fields

For Sierra Leone National ID cards:
FieldExample
Personal ID Number (NIN)NIN: 1234567890
SurnameKAMARA
First NameIBRAHIM
Middle NameMOHAMED
Date of Birth15/03/1990
GenderMALE
Height1.75m
Date of Expiry15/03/2030

Usage

import { ocrService } from './ocr-service';

const result = await ocrService.extractTextFromImage(base64Image);

console.log('Extracted NIN:', result.extractedData.nin);
console.log('Full Name:', result.extractedData.fullName);
console.log('Confidence:', result.confidence);
console.log('Raw Text:', result.rawText);

OCR Result Interface

interface OCRResult {
  success: boolean;
  rawText: string;
  confidence: number;  // 0-100
  extractedData: {
    nin?: string;
    surname?: string;
    firstName?: string;
    middleName?: string;
    fullName?: string;
    dateOfBirth?: string;
    gender?: string;
    height?: string;
    expiryDate?: string;
  };
  fraudIndicators: string[];
}

Vision API Validation

The ID Card Validator uses OpenAI’s Vision API for document authenticity checks.

Validation Checks

Document Type

Verifies the image is a valid Sierra Leone National ID

Photo Presence

Confirms a clear photo is visible on the document

Official Appearance

Checks for official government styling and elements

Text Readability

Ensures text is legible and not obscured

Usage

import { idCardValidator } from './id-card-validator';

// Validate single side
const result = await idCardValidator.validateIDCard(base64Image, 'front');

if (result.fraudDetected) {
  console.log('Fraud indicators:', result.fraudIndicators);
}

// Validate both sides with cross-checking
const validation = await idCardValidator.validateBothSides(frontImage, backImage);

if (!validation.crossValidation.consistent) {
  console.log('Issues:', validation.crossValidation.issues);
}

Fraud Detection

Fraud Indicators

The system detects multiple fraud patterns:
IndicatorDescription
LOW_OCR_CONFIDENCEOCR confidence below 60%
MISSING_OFFICIAL_HEADER”REPUBLIC OF SIERRA LEONE” not found
MISSING_ID_HEADER”NATIONAL IDENTITY CARD” not found
SUSPICIOUS_TEXT_PATTERNContains “photoshop”, “edited”, “sample”, etc.
REPEATING_ID_PATTERNID number like “11111111” or “12341234”
FRONT_BACK_MISMATCHName/ID differs between sides
MISSING_CRITICAL_DATARequired fields not extracted
CONFIDENCE_MISMATCHLarge difference between front/back confidence

Suspicious Text Patterns

const SUSPICIOUS_PATTERNS = [
  'photoshop',
  'edited',
  'sample',
  'template',
  'test',
  'demo',
  'fake',
  'copy'
];

Cross-Validation

When both sides are provided, the system performs cross-validation:
interface CrossValidation {
  consistent: boolean;
  issues: string[];
  frontConfidence: number;
  backConfidence: number;
  nameMatch: boolean;
  idMatch: boolean;
}

Complete Validation Flow

Single Image Upload

KYC Upgrade (Both Sides)

Configuration

OCR Settings

// ocr-service.ts
const ocrConfig = {
  lang: 'eng',
  oem: 1,  // LSTM only
  psm: 3,  // Fully automatic page segmentation
};

Confidence Thresholds

ThresholdValuePurpose
Minimum OCR confidence60%Below this triggers fraud flag
Warning OCR confidence75%Below this shows warning
Cross-validation mismatch20%Difference between front/back

Image Requirements

For best results, KYC images should:
  • Minimum resolution: 800x600 pixels
  • Clear, in-focus image
  • Good lighting without glare
  • No blur or motion artifacts
  • ID card fills 70-80% of frame
  • All edges visible
  • No fingers covering text
  • Flat surface (no curves)
  • JPEG or PNG format
  • Maximum file size: 10MB
  • Base64 encoded with data URI prefix

Error Handling

// Handle validation errors gracefully
try {
  const result = await idCardValidator.validateIDCard(image, 'front');
  
  if (!result.success) {
    return {
      success: false,
      userMessage: 'Could not validate your ID. Please try again.'
    };
  }
  
  if (result.fraudDetected) {
    return {
      success: false,
      userMessage: `Document issues: ${result.fraudIndicators.join(', ')}`,
      requiresResubmission: true
    };
  }
  
  // Proceed with upload
} catch (error) {
  logger.error('KYC validation failed', { error });
  return {
    success: false,
    userMessage: 'Validation failed. Please try again later.'
  };
}

S3 Storage

Validated documents are stored in S3:
// s3-uploader.ts
const uploadResult = await s3Uploader.uploadKYCDocument({
  userId: context.userId,
  side: 'front',
  image: base64Image,
  extractedData: ocrResult.extractedData
});

// Returns: s3://olive-kyc-documents/kyc/user123/front_2024-01-15.jpg

Pre-signed URLs

For admin access to KYC documents:
const url = await s3Uploader.getPresignedUrl(s3Uri, 3600); // 1 hour

Next Steps