Security & architecture

How it works, and why your file never leaves your machine.

The deep-dive for the technical evaluator. The homepage stays tight; this page is where the structure of the trust model lives.

The local-first model

PayloadGlass analyzes files where they already are. In a deployment, the engine runs on your own infrastructure. In the browser workbench, the same production analysis engine is compiled to WebAssembly and runs entirely in a Worker in your own tab — there is no analysis backend to send a file to. The page loads its own app assets, and it fetches a sample if you pick one, but your file's content, its name, and the derived report are never transmitted — file-content egress is zero. You can verify it: open your browser's network panel and confirm no request carries your file. Disconnect from the internet after the page loads and analysis keeps working.

What the engine actually does

The SIS engine parses a file's real structure rather than a flattened preview: the recursive object graph, embedded and nested objects, active content (scripts, macros, actions), and the parser-level tricks that text filters and LLM guardrails never see. Every finding is typed and carries an evidence span — the byte range or node that triggered it — plus the coverage of the parse and the policy that acted. Verdicts are explainable by construction, not a score you have to trust.

Threat assessment, and everything that qualifies it

A single "malicious / clean" label hides the fact that risk depends on what you are about to do with the content, and on how it reached you. We deliberately do not publish a fixed count of "axes" — the model is extensible, and freezing a number into marketing would be a promise we'd rather not make. What matters is the split:

Threat assessment — what drives the security verdict

  • Hostility — could this harm a system, user or agent by executing, exploiting, fetching, evading or chaining?
  • Deception — does it manipulate a person into an unsafe action? (QR lures, fake login, ClickFix, brand impersonation)
  • AI-ingestion — could it corrupt or manipulate a model, retrieval or agent workflow? (hidden prompts, retrieval-visible instructions, tool-use directives)

The security verdict (malicious / suspicious / benign) is the worst of those three. Nothing below changes it.

Decision context — what changes the answer without changing the verdict

  • Sensitivity — secrets, credentials, PII and confidential material found locally, evidence-safe and verdict-inert.
  • Custody — how it arrived: sender, origin, sharing scope, quarantine state, who handled it.
  • Consumer and action — a reader, a renderer, a retrieval indexer and an agent are exposed differently by the same capability.
  • Tool and data privileges — what the consumer is actually allowed to do with what it reads.
  • Integrity and authenticity — what is genuinely bound or verified, as distinct from what the file merely claims.
  • Lineage — what was derived from what, across a nested chain.
  • Intended destination — open locally, index, forward, or hand to a tool.

A note on vocabulary: we avoid the unqualified word "provenance", because it conflates at least three different things — custody, lineage, and integrity/authenticity. They have different evidence and different failure modes, so we name them separately. Where the engine emits contradiction findings across a nested chain, that is evidence about the file's own claims — not cryptographic proof.

Where this stands: the three verdict-driving assessments ship, and the secret/PII detection feeding sensitivity ships (evidence-safe, verdict-inert, local). Sensitivity is advisory and gates nothing today. Custody and consumer/action are being built as canonical contracts — today they are distributed across surfaces rather than unified, and a bare scan has no acquisition context at all. The enforcing, coverage-qualified decision above them is the current work.

The rules the system holds itself to

These are load-bearing invariants, not implementation trivia. They are what make a finding mean the same thing on the command line, in CI, in the browser and on the desktop.

  • Unknown is not clean. Unsupported, not run, not measured, incomplete, budget-exhausted and failed are distinct states, and they stay visible. Missing evidence is never silently projected as a pass.
  • Route is not identity. Several exact formats may share one analysis lane; the exact format and every accepted interpretation are retained rather than collapsed into one guess.
  • Evidence timing matters. Evidence shown beside a verdict is not presented as having influenced it unless it existed when that verdict was taken.
  • Projection is not authority. Browser, desktop, reports and gateways consume shared contracts; they never redefine what a finding means.
  • Nested lineage survives. A finding discovered several layers deep keeps its native identity and derivation when lifted into the parent investigation.
  • Operations are revision-bound. An action is requested against an exact subject and revision, so it cannot silently act on replaced bytes or stale authority.

What we support, and how well.

We publish support per root and capability — recognition, structure, parser, member enumeration, text channels, safe-text, sanitisation and sensitivity coverage — rather than a detector count that says nothing about whether your file is covered.

Native roots

PDFOffice OOXMLOLE compound filesRTFHTML / HTAMHT / MHTMLZIPISO / UDFPEELFLNKstandalone scripts

Partial and embedded surfaces

EmailOneNoteCSS / LESSadditional archivesimagesfontsrich media

And the states that are neither

Coverage is not one percentage or a traffic light. Anything unsupported, not run, not measured, incomplete, budget-exhausted or failed stays in its own state — never folded into a pass.

unsupported not run not measured incomplete budget exhausted failed

The container image, and exactly what its attestation covers

The sis CLI is also published as a multi-architecture OCI image at ghcr.io/payloadglass/sis. It is worth being precise about what that image is, because container supply-chain language is routinely oversold.

  • It is assembled, not rebuilt. The image repackages the Linux archives the release already published. There is no source, no toolchain and no compilation step in it — so publishing it exposes nothing the release does not.
  • The attestation names the assembly workflow as the builder. It attests that this image was assembled from those exact published bytes. It is not a cryptographic tie back to a source commit, and we will not present it as one. The runtime base is digest-pinned, the archives are checksum-verified before unpacking, and the assembly step is Sigstore-signed and recorded in a public transparency log.
  • The inputs are verified before they are trusted. Archives are checked against the published checksum manifest before unpacking, and the runtime base is pinned by digest — a floating base tag would let two runs of the same release produce different images with nothing recording the difference.
  • There is no rolling tag. Tags are release tags; there is no rolling tag. Pin by digest for reproducible runs. An image that silently changes under a stable name is not something you can attest about.
  • It runs unprivileged. Runs as a non-root user with no shell entrypoint, and works with a read-only root filesystem — mount the content you want analysed and nothing else.

The image runs the same engine as the CLI, so every local-first property above holds: analysis happens in your environment, and the example invocation drops the network entirely.

Transform: the safe-text derivative

Inspection is only half the job. Where policy calls for it, the engine emits a safe-text derivative — a model-safe version of the document with active content and hidden channels removed, paired with a log of exactly what was stripped, what was preserved, and what residual risk is still flagged. This ships today and is distinct from full content disarm & reconstruction (CDR), whose broad reconstruction guarantees are still hardening. The derivative never silently rewrites: every change is evidenced, which is what makes "prove what remains" a literal artefact rather than a slogan.

WASM & cross-origin isolation

The workbench runs the engine as WebAssembly, and where it relies on threads and SharedArrayBuffer for performance, the browser requires the page to be cross-origin isolated. That deploy therefore serves:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Content-Type: application/wasm   (for .wasm assets)

Those headers live on the separate workbench deploy (workbench.payloadglass.com), not on the marketing site — they would otherwise interfere with embeds and analytics here. It is also why the workbench is hosted on infrastructure we control (Netlify / Cloudflare Pages with a _headers file) rather than a host that can't set custom headers.

Sample files in the workbench

The bundled samples are crafted, controlled files that trigger detectors without being genuinely dangerous to the visitor, and they're labelled as such. The workbench never needs — and you should never feed it — a live, genuinely dangerous malware sample.

Want to see it rather than read about it?

Open the investigation workbench →