Docs / Surface / overview
Surface
Surface is a file and payload scanning service that detects malware, exploits, prompt injections, sensitive data exposure, and other threats in real-time before content reaches your systems.
Surface runs as a first-class service on the Tendrl platform, using the same account and auth infrastructure as Contact and Strand.
How you can use it#
- REST API: scan files and payloads from any language or framework
- Scanner Binary: run the full engine pipeline locally in your infrastructure, CI pipelines, or developer workstations (docs)
- MCP Server: give any AI agent native scanning through the Model Context Protocol (docs)
- Strand Connector: use the
surface.platformnode in Strand workflows (docs) - Webhooks: receive signed scan results at your endpoint when scans complete (docs)
What Surface scans#
- Files: executables, archives, documents, images, and more
- Payloads: raw text, JSON, base64 content (API data, LLM inputs/outputs, IoT sensor strings)
Threat detection engines#
File engines#
| Engine | What it catches |
|---|---|
| Signatures & Threat Feeds | Known malware by hash, malicious URLs/IPs/domains, and thousands of YARA pattern rules |
| ML Classifier | Purpose-built models for executables, Office documents, PDFs, and scripts; catches new and modified threats that signatures miss |
| Document & Script Analysis | Macro-based threats, embedded objects, obfuscated content, and suspicious script behavior |
| Executable Analysis | Packed or protected binaries, suspicious capabilities, and hidden strings |
| IOC Extraction | URLs, IPs, domains, and hashes found inside the file, cross-referenced against threat feeds |
| Fuzzy Matching | Detects repacked or modified variants of known threats even when the exact hash has changed |
| Archive Scanning | Unpacks and individually scans each entry in ZIP, RAR, 7-Zip, and tar archives |
| CVE Enrichment | Links detected threats to CVE records where available, with severity scores |
Payload engines (agentic security)#
Payload scans run four additional engines for AI and agentic workflows:
| Engine | What it detects |
|---|---|
| Prompt Injection | Adversarial instructions embedded in text |
| Sensitive Data | Exposed API keys, credentials, and PII |
| Code Extraction | Embedded shell commands and scripts hidden in text payloads |
| Tool Call Analysis | Suspicious function call patterns |
Safety scores#
Every scan returns a score from 0 to 100. Higher is safer.
| Score range | Threat level | Recommended action |
|---|---|---|
| 86–100 | Clean | Allow |
| 71–85 | Informational | Allow |
| 31–70 | Suspicious | Review |
| 0–30 | Malicious | Block |
Informational means minor or low-severity signals were noted but the content is still treated as safe to allow, which is useful for surfacing context without blocking.
How much a verdict is worth#
Formats are not all analyzed to the same depth, so every scan also reports coverage: full for Windows and Linux executables, which have dedicated ML models behind them; partial for scripts, documents and archives; minimal for formats with no ML model at all — Java bytecode, JARs, APKs and Mach-O binaries.
A minimal scan never returns Clean. The most it reports is Informational, because "we looked and found nothing" is a weaker claim than "this is clean" when the format is one Surface cannot analyze deeply. Informational still means Allow, so this changes what Surface claims rather than what it blocks. See Detection coverage.
Scores combine signals from all engines. Content flagged by multiple independent engines scores lower than content flagged by a single check.
Result shape (Strand connector)#
When you use the surface.platform connector in Strand workflows, the platform normalizes the response into this shape:
{
"score": 95,
"threat_level": "Clean",
"primary_threat": "No threats detected",
"recommended_action": "Allow",
"coverage": "full",
"iocs": [],
"safe": true,
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
| Field | Description |
|---|---|
score |
0–100 safety score (higher = safer) |
threat_level |
Clean, Informational, Suspicious, or Malicious — plus Rejected and Error, which mean nothing was scanned (see the API reference) |
primary_threat |
Top matched threat label |
recommended_action |
Allow, Review, or Block |
coverage |
full, partial, or minimal — how far analysis reaches for this format |
iocs |
Indicators of compromise (URLs, IPs, domains, hashes) |
safe |
true only when Surface scored the file and threat_level is not in the node's reject_on list. Never true for Rejected or Error |
request_id |
Correlation ID for this scan |
Field names use snake_case because the platform normalizes them from the Surface API's camelCase response.
Privacy#
Files and payloads are loaded into memory for scanning and discarded immediately after. Surface stores scan results, metadata, content hashes, and the short redacted excerpts that evidence a finding, never the file or payload itself. When using the scanner binary, content never leaves your machine at all.
Get started#
- Quick start: create your account, run your first scan
- API Reference: interactive Swagger docs
- Detection coverage: what Surface catches and what it doesn't
- Scanner Binary: run scanning locally in your infrastructure
- MCP Server: add scanning as a native AI agent tool
- Webhooks: receive signed results at your endpoint
- Async scanning: deferred mode for large files and high-throughput workflows
- Contact integration: scan payloads inside Contact flows
- Strand integration:
surface.platformconnector for workflows
Tendrl