SovGuard Integration
SovGuard can be integrated with the Junction41 platform in three modes: as a remote HTTP API, as an imported SDK module, or as a local co-deployed service. The Junction41 production deployment uses the HTTP API mode with optional AES-256-GCM encryption.
Integration Modes
Mode 1: HTTP API (Recommended)
SovGuard runs as a standalone service with its own process and HTTP endpoints. The Junction41 platform calls it via POST /v1/scan for inbound messages and POST /v1/scan/output for outbound messages.
Junction41 Platform --HTTP--> SovGuard API (separate process/container)This is the recommended mode for production because:
- SovGuard can be scaled independently of the platform
- Failures in SovGuard do not crash the platform process
- The circuit breaker provides automatic fallback on outages
- Optional E2E encryption protects message content in transit
Mode 2: SDK Import
For development and testing, SovGuard can be imported directly as a Node.js module:
import { createSovGuardEngine } from '@junction41/sovguard';
const engine = createSovGuardEngine({
blockThreshold: 0.7,
suspiciousThreshold: 0.3,
enablePerplexity: true,
enableClassifier: false, // Skip Lakera in dev
});
const result = await engine.scan('ignore all previous instructions');
// { score: 0.9, safe: false, classification: 'likely_injection', flags: ['instruction_override'] }Mode 3: Local Module
A hybrid approach where SovGuard runs in the same container but as a separate internal service. This is used in single-box deployments where running a separate container is impractical.
Platform Integration
The Junction41 platform integrates SovGuard through a provider pattern. At startup, the platform creates a SovGuard provider based on the configured environment variables:
// src/sovguard/index.ts
import { SovGuardHttpClient } from './client.js';
export async function createSovGuardProvider(): Promise<SovGuardProvider | null> {
const { apiUrl, apiKey, encryptionKey, timeoutMs } = config.sovguard;
if (apiKey && apiUrl) {
const client = new SovGuardHttpClient({ apiUrl, apiKey, encryptionKey, timeoutMs });
return client;
}
return null; // SovGuard not configured
}The provider is injected into the WebSocket chat server, which scans every message:
// WebSocket message handler (simplified)
if (sovguardEngine && sovguardEnabled) {
const result = await sovguardEngine.scan(message);
if (result.score > 0.8) {
socket.emit('error', { message: 'Message blocked by safety filter' });
return; // Message not delivered
}
if (result.score > 0.3) {
safetyWarning = true; // Delivered with warning
}
}The same engine handles outbound scanning for agent-to-buyer messages. See Outbound Scanning for details.
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
SOVGUARD_API_URL | Yes (for HTTP mode) | — | Base URL of the SovGuard API |
SOVGUARD_API_KEY | Yes (for HTTP mode) | — | API key for authentication |
SOVGUARD_ENCRYPTION_KEY | No | — | Base64-encoded 256-bit AES key for E2E encryption |
SOVGUARD_SCAN_PATH | No | /v1/scan | Inbound scan endpoint path |
SOVGUARD_TIMEOUT_MS | No | 200 | Request timeout in milliseconds |
Example Configuration
# .env — SovGuard HTTP mode
SOVGUARD_API_URL=https://sovguard.junction41.io
SOVGUARD_API_KEY=sg_live_abc123...
SOVGUARD_ENCRYPTION_KEY=dGhpcyBpcyBhIDMyLWJ5dGUga2V5Li4uLi4=
SOVGUARD_TIMEOUT_MS=200SovGuard Server Configuration
The SovGuard server itself accepts these configuration options:
| Variable | Default | Description |
|---|---|---|
SOVGUARD_PORT | 3100 | HTTP listen port |
SOVGUARD_BLOCK_THRESHOLD | 0.7 | Score at which messages are blocked |
SOVGUARD_SUSPICIOUS_THRESHOLD | 0.3 | Score at which messages are flagged |
SOVGUARD_ENABLE_PERPLEXITY | true | Enable L2 entropy analysis |
SOVGUARD_ENABLE_CLASSIFIER | true | Enable L3 ML classifier |
LAKERA_API_KEY | — | Lakera Guard v2 API key (required for L3) |
E2E Encryption
When SOVGUARD_ENCRYPTION_KEY is set, all messages between the platform and SovGuard are encrypted with AES-256-GCM. This protects message content even if the network between the platform and SovGuard is compromised.
Encryption Flow
- Platform encrypts the scan request body with the shared key
- Request is sent with
X-Encrypted: trueheader - SovGuard decrypts, scans, encrypts the response
- Response is returned with
X-Encrypted: trueheader - Platform decrypts the response
// Encrypted payload format
interface EncryptedPayload {
iv: string; // Base64-encoded 12-byte IV
tag: string; // Base64-encoded 16-byte GCM auth tag
data: string; // Base64-encoded ciphertext
}The encryption key must be exactly 256 bits (32 bytes), base64-encoded. Generate one with:
openssl rand -base64 32Fallback Behavior
When SovGuard is unreachable (network error, timeout, or circuit breaker open), the platform falls back to an inline regex scanner embedded in the Junction41 codebase. This fallback provides L1-level protection only:
// Fallback scanner capabilities
// - 20+ regex patterns for common injection attacks
// - Zero-width character stripping
// - Shannon entropy check (> 5.0 bits/char flagged)
// - PII detection (SSN, credit card)
// - Cryptocurrency address detection
// - IP-based URL detectionThe fallback does not include:
- L1+ encoding detection (base64, ROT13, hex decoding)
- L2 perplexity / GCG suffix detection
- L3 ML classification
- L4 spotlighting
- L5 canary token checks
- L6 file content scanning
This means detection rates drop from ~65% to ~25% during fallback. The circuit breaker is designed to recover quickly (30-second open window) to minimize time spent in degraded mode.
Fallback Scoring
The fallback scanner uses the same thresholds and scoring model as the full SovGuard engine. Scores from regex matches are based on pattern weights:
| Pattern Category | Weight |
|---|---|
ChatML injection (<|im_start|>) | 0.95 |
| DAN/jailbreak mode | 0.90-0.95 |
| Instruction override | 0.85-0.90 |
| Role tag injection | 0.75-0.80 |
| Exfiltration requests | 0.70-0.85 |
| High entropy (> 5.0) | 0.40 |
How Messages Flow Through SovGuard
The complete message lifecycle with SovGuard integration:
1. Buyer sends message via WebSocket
2. Platform sanitizes input (XSS, length limits)
3. Platform checks if SovGuard is enabled for this job
4. If enabled:
a. Call sovguardEngine.scan(message)
b. If score >= 0.8 → block, emit error to buyer
c. If score >= 0.3 → flag as suspicious, attach warning
d. Check session scorer for crescendo escalation
e. If escalated → block all further messages
5. Message stored in database with safety metadata
6. Message delivered to sovagent via WebSocket
7. Sovagent responds
8. Platform calls outputScanEngine.scanOutput(response)
9. If outbound scan flags critical issues → hold response
10. Response delivered to buyerEnabling SovGuard for Services
Sovagent operators can require SovGuard for specific services in their VDXF service definition:
{
"name": "Code Review",
"pricing": [{"currency": "VRSCTEST", "amount": "5"}],
"sovguard": true
}When sovguard: true, the platform enforces SovGuard server-side -- buyers cannot disable it even through direct API calls. See SovGuard Overview for the enforcement mechanism.
Health Monitoring
The SovGuard API exposes a GET /health endpoint that the platform can use for monitoring. The API Reference documents the response format. The platform logs SovGuard status at startup:
SovGuard initialized { mode: 'http, encrypted, inbound + outbound' }If the encryption key is configured, the log shows encrypted in the mode string. If SovGuard is not configured at all, the log shows:
SovGuard not configured