Skip to content

How Benchy Validates Untrusted 3D Files

Inside Benchy's upload pipeline: quarantined files, bounded Rust parsers, server-side policy checks, and the open-source benchy-mesh validation engine.

An orange 3D-printed boat moving through transparent file inspection and mesh scanning stages

A file uploaded as an STL cannot be trusted on its name alone. It may be a valid model, a malformed GLB, an archive designed to expand beyond its limits, or hundreds of megabytes of unusable data. A publishing platform has to identify the actual format, bound the work required to inspect it, and keep unverified bytes away from public storage.

Benchy accepts the upload into a quarantined ingest bucket and validates it with benchy-mesh, an open-source Rust engine dual-licensed under MIT or Apache-2.0. The same checks support local inspection, edge validation, and the server-side evidence required before a model can be published or sold.

Open source where decisions are made

benchy-mesh is six crates: core (versioned checks and policy decisions), formats (content-based detection and bounded parsing for STL, OBJ, GLB/glTF, and 3MF), geom (geometry and topology evidence), print (prerequisite-based print-readiness assessment), cli (a benchy-mesh validate --json binary), and wasm (bindings for Workers and browsers).

The validator treats every file as untrusted input. Filename extensions and declared media types provide hints; content-based detection supplies the evidence. Every parser runs under explicit limits for bytes, geometry counts, allocations, textures, archive entries, and expanded archive size. The 3MF path checks package relationships, internal paths, and expansion constraints before model parsing. Validation results use stable issue codes, severity levels, check ids, and typed parameters so integrations can consume structured results.

The validator is open source because decisions such as File checks passed and marketplace eligibility should be inspectable. Anyone can run the structural profile locally. Benchy's publishing decision separately records the marketplace profile and server-enforced execution context.

Benchy also publishes agent-consumable skill documents for connecting to the MCP server, creating tokens, building a bio, operating a shop, and uploading and validating models. The skills are versioned in the repositories alongside the code they describe. Repository-level AGENTS.md contracts document the same operational boundaries for engineering agents.

Owning the full stack

The hosted services connect that validator to identity, storage, publishing, and commerce.

Benchy is a hub and spokes. The hub (benchy.studio) owns identity, credits, the canvas, and the family MCP server. The spokes — benchy.bio for maker profiles, benchy.shop for commerce, benchy.world for models — each run their own Convex deployment with their own schema and their own blast radius. The hub mints RS256 JWTs that live for 120 seconds; spokes verify them against the hub's JWKS and never share a database. When an agent calls a tool with a personal access token, the token is exchanged for one of those two-minute JWTs on every call. Nothing long-lived crosses a boundary.

The edge layer is intentionally stateless. Uploads pass through a Cloudflare Worker that verifies an HMAC-signed grant and writes only to a pending ingest bucket; clients cannot address public buckets directly. Paid Shop downloads use a separate Worker that verifies a ten-minute HMAC token and streams bytes without calling a database. Convex remains the authority for ownership, purchases, and recorded policy decisions, while the Workers verify signatures and move bytes.

Files up to 24 MiB are inspected inside the Worker with the Rust crates compiled to WASM. Files up to 256 MiB run in a Cloudflare Container using the native benchy-mesh CLI, with internet access disabled and a three-minute sleep timer. The report declares schemaVersion: 2, policy 2026.07.10.3, its validation profile, and its execution mode. Publishing also requires a completed marketplace/server allow, every required evidence check, no error issues, finite geometry and topology observations, known units, and an exact binding to the model's current hash, byte length, format, and unit context.

Worker inspection
24 MiB
Rust compiled to WASM
Container inspection
256 MiB
Native CLI, network disabled
Spoke JWT
120 sec
Exchanged for every call
World file token
15 min
Protected model delivery
Each limit belongs to a specific execution boundary.

Uploading, checking, and eligibility are separate states. Bytes are stored before the queue picks them up, and a failed or inconclusive decision does not delete the creator's file. deny becomes Needs attention; inconclusive becomes Checks incomplete with no publishing decision. Shop eligibility requires current, file-bound server evidence plus confirmed ownership of a listed Shop product. Historical v1 rows remain readable during migration but cannot authorize publishing or purchase.

  • allow
    File checks passedCurrent evidence satisfies every marketplace requirement.
  • deny
    Needs attentionThe protected file remains unavailable while the creator addresses a blocking issue.
  • inconclusive
    Checks incompletePublishing waits for a complete set of required evidence.
The policy result maps directly to the state a creator sees.

Benchy exposes the same permissioned product operations to agents through the MCP server at mcp.benchy.studio. It supports OAuth for hosted connectors, scoped tokens for scripts, and an audit log that records each call without storing arguments. The available tools depend on account access, credential scope, and deployment safety gates. Benchy's own in-product agent uses that same surface with the user's credentials and has no privileged internal API.

Built on infrastructure we can reason about

Benchy keeps its infrastructure boundaries explicit. The applications deploy on Vercel, the upload, download, validation queue, and container services run on Cloudflare, and the data layer runs on Convex. Those providers may process or replicate data across regions according to the configured services and plans.

Each layer has a named owner, a documented boundary, and an explicit failure mode. Regional claims use the precision each provider exposes, and placement hints carry no country-level residency guarantee. The same principle applies to the validator: trust claims should be supported by inspectable behavior.

  1. GrantSigned permission
  2. PUTPending bucket
  3. PromoteFile binding
  4. QueueDurable work
  5. ValidateBounded parser
  6. ApplyRecorded policy
The upload path keeps storage, validation, and policy application as separate stages.

The Worker implementation for this pipeline remains roughly two thousand lines while the platforms handle the underlying operational work.

What Benchy actually is

Benchy lets makers use an agent to build a profile, list models, and set up a shop. The underlying system is designed for tools operated by agents and constrained by open, inspectable trust boundaries.

The validation layer is open-source Rust. Agent skills are published as open documents. Access is scoped, short-lived, and logged. Bio, Shop, World, Canvas, and the hosted agent expose their permitted operations through one MCP endpoint.

That combination keeps file validation inspectable while the hosted services enforce identity, authorization, and publishing policy.