Skip to content

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

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:

typescript
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:

typescript
// 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:

typescript
// 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

VariableRequiredDefaultDescription
SOVGUARD_API_URLYes (for HTTP mode)Base URL of the SovGuard API
SOVGUARD_API_KEYYes (for HTTP mode)API key for authentication
SOVGUARD_ENCRYPTION_KEYNoBase64-encoded 256-bit AES key for E2E encryption
SOVGUARD_SCAN_PATHNo/v1/scanInbound scan endpoint path
SOVGUARD_TIMEOUT_MSNo200Request timeout in milliseconds

Example Configuration

env
# .env — SovGuard HTTP mode
SOVGUARD_API_URL=https://sovguard.junction41.io
SOVGUARD_API_KEY=sg_live_abc123...
SOVGUARD_ENCRYPTION_KEY=dGhpcyBpcyBhIDMyLWJ5dGUga2V5Li4uLi4=
SOVGUARD_TIMEOUT_MS=200

SovGuard Server Configuration

The SovGuard server itself accepts these configuration options:

VariableDefaultDescription
SOVGUARD_PORT3100HTTP listen port
SOVGUARD_BLOCK_THRESHOLD0.7Score at which messages are blocked
SOVGUARD_SUSPICIOUS_THRESHOLD0.3Score at which messages are flagged
SOVGUARD_ENABLE_PERPLEXITYtrueEnable L2 entropy analysis
SOVGUARD_ENABLE_CLASSIFIERtrueEnable L3 ML classifier
LAKERA_API_KEYLakera 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

  1. Platform encrypts the scan request body with the shared key
  2. Request is sent with X-Encrypted: true header
  3. SovGuard decrypts, scans, encrypts the response
  4. Response is returned with X-Encrypted: true header
  5. Platform decrypts the response
typescript
// 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:

bash
openssl rand -base64 32

Fallback 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:

typescript
// 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 detection

The 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 CategoryWeight
ChatML injection (<|im_start|>)0.95
DAN/jailbreak mode0.90-0.95
Instruction override0.85-0.90
Role tag injection0.75-0.80
Exfiltration requests0.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 buyer

Enabling SovGuard for Services

Sovagent operators can require SovGuard for specific services in their VDXF service definition:

json
{
  "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