Data Classifier
The data classifier provides LLM-assisted classification of API response bodies into sensitivity tiers. It is advisory only -- classifications are proposals that the user must review before they are promoted to service definition patterns.
Design principle: propose only, never enforce.
Module: src/main/services/data-classifier.ts
Exported functions
buildClassificationPrompt(body, serviceId, contentType)
Builds the LLM prompt for classifying a response body.
- body (
string) -- The raw response body to classify. - serviceId (
string) -- The service ID (e.g."github"). - contentType (
string) -- The Content-Type header value (e.g."application/json"). - Returns
string-- The full prompt text.
Key behavior:
- Truncates the body at 4000 characters to stay within token limits.
- Appended excerpt is wrapped in a fenced code block.
- Prompt instructs the LLM to respond with a JSON object containing
suggestedTier,confidence,patterns, andreasoning.
parseClassificationResponse(response)
Parses and validates the LLM's JSON response.
- response (
string) -- Raw LLM output (expected to be JSON). - Returns
DataClassification | null-- Parsed classification, ornullif invalid.
Validation rules:
- Must be valid JSON.
suggestedTiermust be one of:public,internal,confidential,restricted.confidencemust be a number (clamped to 0-1).patternsdefaults to[]if not an array.reasoningis coerced to string.
Returns null for any validation failure -- never throws.
DataClassifier class
class DataClassifier {
constructor(apiKey: string | null)
classify(body: string, serviceId: string, contentType: string): Promise<DataClassification | null>
}
- Requires an OpenAI API key; returns
nullif no key is set. - Uses
gpt-4o-miniwithtemperature: 0.1andresponse_format: { type: 'json_object' }. - 15-second request timeout via
AbortSignal.timeout. - All errors are caught and return
null-- never throws.
Types (src/types/index.ts)
DataTier
type DataTier = 'public' | 'internal' | 'confidential' | 'restricted'
DataClassification
interface DataClassification {
suggestedTier: DataTier
confidence: number // 0-1
patterns: string[] // detected patterns that drove classification
reasoning: string // LLM explanation
}
IPC handler
latch:data-classify
- Payload:
{ body: string; service: string; contentType: string } - Response:
{ ok: boolean; classification?: DataClassification; error?: string } - Registered in
src/main/index.ts, exposed via preload aswindow.latch.classifyData().
The DataClassifier singleton is initialized in app.whenReady() with the OpenAI API key from settings:
const openaiKey = settingsStore?.get('openai-api-key')
dataClassifier = new DataClassifier(openaiKey?.value ?? null)
Testing
src/main/services/data-classifier.test.ts (5 tests)
Run: npx vitest run src/main/services/data-classifier.test.ts
Covers:
buildClassificationPromptincludes body excerpt and service IDbuildClassificationPrompttruncates bodies longer than 4000 chars (prompt stays under 6000 chars)parseClassificationResponseextracts tier, confidence, and patterns from valid JSONparseClassificationResponsereturns null for invalid JSONparseClassificationResponserejects tiers not in the valid set
Integration with the proxy pipeline
The data classifier sits outside the hot path. It is invoked on-demand (via IPC) rather than on every proxied response. Typical usage:
- User inspects a proxied response in the Enclave panel.
- User clicks "Classify" to invoke
window.latch.classifyData(). - The LLM analyzes the response body and returns a suggested tier.
- The user reviews the suggestion and optionally updates the service definition's
dataTier.defaultTieror redaction patterns.
This keeps the proxy fast (no LLM latency in the request path) while still providing intelligent classification assistance.
Custom Service Builder (src/renderer/components/modals/ServiceEditor.tsx)
The ServiceEditor modal provides a UI for creating custom services. The data tier
selection in the service editor can be informed by classification results. Users
can classify sample data and use the suggested tier when configuring a new service's
dataTier.defaultTier.