Skip to content

URL / Context Trust Gate

Pre-ingestion control point for URLs and external content destined for humans, browsers, endpoint agents, RASP-instrumented applications, and AI agents. Before any consumer follows a URL or ingests external content, the gate canonicalizes the destination, fetches it safely, scores it for phishing / hidden prompt injection / promptware / data-exfil / IOC signals, and applies a policy decision. Evidence is preserved for every non-cached decision.

Status: pilot-ready. Runs end-to-end. A 15-minute PoC installer (the cyberarmor-trust-gate-demo repo) brings up the full gate stack on any developer laptop — macOS, Windows, or Linux — from prebuilt images and submits four crafted attack pages — benign, display:none promptware, zero-width injection, credential-harvest — all producing live verdicts in under 120 ms. See docs/architecture/capability-status.md for the full capability status table.

Why a separate control point

Traditional URL filters answer "Is this site malicious for a human?". Enterprise AI security needs to answer a stronger question: "Is this site safe for a human, a browser, AND an AI agent to consume?"

The new attack surface is indirect prompt injection and promptware: malicious instructions hidden in web pages, documents, metadata, and email footers that are later ingested by an AI system. Existing Safe Browsing / SmartScreen / VirusTotal feeds are useful for the older phishing/malware question but do not detect AI-context attacks like CSS-hidden text, Unicode-tag-encoded instructions, or zero-width-space-encoded payloads that are invisible to humans but read verbatim by LLMs.

The gate combines URL reputation, safe crawl, headless-browser detonation, ML scoring, policy enforcement, and evidence into one trust boundary at external content before AI ingestion or agent action.

Pipeline

consumer ─► /evaluate
            │
            ├─ canonicalize URL + classify querystring sensitivity
            ├─ reputation cache + tenant allow/block list lookup
            ├─ safe crawl (SSRF-guarded, no creds)               [standard, deep]
            ├─ detonation sandbox (Playwright headless render)   [deep]
            ├─ extract signals + scrape IOCs
            ├─ fan out to detection service for ML scoring
            ├─ external feeds (Safe Browsing v4, SmartScreen, VirusTotal v3)
            ├─ policy decision via policy service
            ├─ evidence write to audit service
            └─ optional incident dispatch to response service

Decision actions

Action Meaning
allow Below thresholds.
warn Non-blocking interstitial / toast. Logged.
redact Strip suspicious instruction blocks before AI ingestion. URL still loads.
sandbox Send the user / agent to a remote browser isolation session.
block Hard block. Browser shows phishing interstitial; RASP raises URLBlockedByTrustGate.
isolate Block + post-incident: revoke / rotate session tokens that may have leaked.

Where the gate is called from

Consumer Hook Default depth
Browser extension webNavigation.onBeforeNavigate fast, async standard backfill
Endpoint agent Outbound DNS / HTTP advisory + loopback IPC daemon at 127.0.0.1:48515 fast
Proxy Pre-request L7 interceptor standard
RASP (Python) Patched requests / httpx / urllib3 fast
AI router Before tool-call URL retrieval deep
LangChain SDK wrap_tool / wrap_agent_tools / make_guarded_browser_tool deep
LlamaIndex SDK reader and node-parser hooks before fetch / index deep
Email / Office extensions Link rewrite / hover preview standard

Latency budgets

Depth Budget Notes
fast ~10ms Cache + canonicalisation. Browser-extension click-time.
standard <500ms Adds safe crawl. Default for endpoint agent / proxy / RASP.
deep seconds Adds Playwright detonation. Best-effort, used for unknown URLs.

The cache fingerprint is SHA-256(scheme, host, port, path, sorted(non-sensitive querystring keys)). URLs with rotating session tokens collapse to a single cache entry. Sensitive querystring values are redacted before logging or evidence write.

Production hardening

The gate makes outbound requests to attacker-controlled URLs only via the detonation worker. The worker is a separate service built on Microsoft's official Playwright image and runs on a dedicated detonation Docker network. The gate joins both the default backend network and detonation; the worker joins only detonation. A hostile page that escapes Chromium cannot reach policy, detection, audit, or any other internal service — those routes don't exist on its network namespace.

The gate also has Python-level guards on its own safe crawl path: SSRF address checks, redirect-hop re-validation, no-cookie / no-Authorization fetches, hard size / time / redirect caps. The network namespace is still the real boundary — the Python checks are belt-and-braces.

For Kubernetes deployments, a NetworkPolicy should allow ingress to the worker pod only from the gate, and forbid egress to internal CIDR ranges and the cloud-metadata IP. A dedicated node pool for browser workloads is recommended.

Evidence

Every gate decision (other than depth=fast cache hits) writes an evidence record to the audit service via POST /events. Writes use retry with exponential back-off (3 attempts, 0.25 s / 0.5 s / 1.0 s). On final failure the full payload is emitted as a structured evidence_write_dead_letter log entry so log aggregation pipelines (Splunk, CloudWatch, Elastic, etc.) can recover it independently. A failed write never delays or changes the gate verdict; callers increment the evidence_write_errors_total Prometheus counter so the gap is visible in dashboards.

Each record carries:

  • request_id, tenant_id, source, consumer identity (user / app / agent)
  • canonical_url (redacted), url_fingerprint, redirect_chain
  • content_hash (post-fetch), screenshot_hash (post-detonation)
  • scores (full vector), iocs[], decision
  • crawled / detonated flags

Tenant SOC analysts can mark false positives / false negatives via POST /feedback. CyberArmor.AI's proprietary ML classifiers (input-safety and output-safety) improve over time as the gate accumulates evidence across decisions. The input-safety classifier is validated on English: ordinary text in many other languages is misread as injection. A multilingual retrain, and a rule that reports writing systems the model was never validated on as not checked instead of scoring them, are built and not deployed (see the status page).

Service map

Endpoint Purpose
POST /evaluate Main entry point. Returns a TrustGateResponse with the action.
POST /feedback SOC analyst FP/FN feedback. Feeds the training-data flywheel.
GET /health Liveness.
GET /ready Readiness.
GET /metrics Prometheus exposition (counters + latency histograms).
GET /pki/public-key Standard service identity.

Auth: x-api-key: $URL_TRUST_GATE_API_SECRET.

Configuration

Variable Default Purpose
URL_TRUST_GATE_API_SECRET change-me-url-trust-gate Inbound API key.
DETECTION_SERVICE_URL http://detection-service:8002
POLICY_SERVICE_URL http://policy-service:8001
RESPONSE_SERVICE_URL http://response-service:8003
AUDIT_SERVICE_URL http://audit-service:8004
SAFE_BROWSING_API_KEY (empty) Optional Google Safe Browsing v4 key. Gate works without it.
SMARTSCREEN_TENANT_ID (empty) Azure AD tenant ID for Microsoft SmartScreen / Defender Threat Intelligence feed.
SMARTSCREEN_CLIENT_ID (empty) App registration client ID for SmartScreen feed.
SMARTSCREEN_CLIENT_SECRET (empty) App registration client secret for SmartScreen feed.
VIRUSTOTAL_API_KEY (empty) VirusTotal v3 API key. Results cached in-process for VIRUSTOTAL_CACHE_TTL_S seconds.
VIRUSTOTAL_CACHE_TTL_S 3600 In-process TTL for VirusTotal results.
URL_TRUST_GATE_DETONATION_DEFAULT off Set to on to run detonation by default for depth=deep.
URL_TRUST_GATE_CRAWLER_TIMEOUT_S 4.0 Per-request crawler timeout.
URL_TRUST_GATE_CRAWLER_MAX_BYTES 1048576 Hard cap on fetched body size.
URL_TRUST_GATE_CRAWLER_MAX_REDIRECTS 5 Each hop re-validated against SSRF rules.
URL_TRUST_GATE_CACHE_TTL_S 900 Reputation cache TTL.

Files in the repo

  • services/url-trust-gate/ — service (FastAPI + Playwright + safe crawler + reputation cache + Prometheus metrics + tests).
  • extensions/chromium-shared/url_trust_gate.js — browser extension hook.
  • agents/endpoint-agent/monitors/url_trust_gate.py — endpoint agent gate client + loopback IPC daemon + network_monitor advisory.
  • rasp/python/cyberarmor_rasp_url_trust_gate.py — RASP outbound HTTP hook.
  • sdks/python/cyberarmor/frameworks/langchain_url_trust_gate.py — LangChain tool wrapper.
  • sdks/python/cyberarmor/frameworks/llamaindex.py — LlamaIndex reader and node-parser hook.
  • scripts/poc/ — 15-minute PoC installer, demo script, four crafted attack pages, and README.
  • docs/architecture/url-trust-gate.md — deep-dive architecture doc with production traps mapped to code-level guards.
  • docs/architecture/capability-status.md — internal capability status table (Working / Configurable / Pilot / Roadmap).
  • cyberarmor.ai/status — public buyer-facing status page with four states: Production-deployed, Pilot-ready, PoC/demo, Roadmap.