Platform

Scanning that cannot reach your build host

TRUSTIVAN resolves images from the registry, not from a local runtime. That single decision removes the two worst failure modes a scanner can have.

How images are read

Remote pull, by design

The worker needs no container runtime and no Docker socket.

  • No socket to mount. Handing a runtime socket to the process that parses untrusted input is root on the host. TRUSTIVAN never asks for one.
  • No local image store to consult. If the scanner resolved references against a local cache, a caller-supplied reference could resolve to another tenant's image. Remote resolution makes that impossible.
  • The reference is untrusted input. Private and link-local registries, embedded credentials, URL schemes and traversal segments are refused at the boundary, with a message naming the rule that rejected them.
POST /api/v1/scans
$ curl -X POST $API/api/v1/scans \
    -H "Authorization: Bearer $TRUSTIVAN_KEY" \
    -H "Idempotency-Key: build-4821" \
    -d '{"image": "alpine:3.19"}'

202 Accepted
{
  "scan":  { "id": "…", "status": "queued" },
  "asset": { "id": "…", "identity": "alpine:3.19" }
}

The job

Accepted is not the same as done

Pulling and unpacking an image takes seconds to minutes, so a scan is a durable job rather than a long request.

Claimed exactly once

Workers claim queued scans with an atomic update, so exactly one wins. Adding a replica is how you scale — there is no leader to elect.

Queued, never dropped

Per-tenant concurrency is bounded. Work beyond the limit waits; it is not rejected, and it is not silently discarded.

Survives a restart

The API and the worker run as separate processes by default, so that this is a property you can verify rather than a claim.

Data freshness

A stale database fails the scan

A scanner running against out-of-date advisory data reports “no vulnerabilities” with exactly the same confidence as a correct one. Silence is the most dangerous output a security tool can produce.

Freshness is assessed before results are persisted. Past a warning threshold the age is surfaced on the scan; past a hard threshold the scan fails outright rather than allowing reconciliation to close findings by absence.

Every scan response carries the state of the data behind it, so a pipeline can decide for itself.

Current

Results persisted, findings reconciled.

Stale

Age reported on the scan so the caller can judge it.

Too old

The scan fails. Nothing is resolved by absence.

Boundaries

What this does not cover

Stated here rather than discovered during a proof of concept.

  • Infrastructure-as-code — no shipped engine parses a Terraform or Kubernetes manifest
  • Reachability analysis — whether vulnerable code is actually called
  • Virtual machines — in the scan contract, scannable by no shipped engine

Connecting a cloud account or a Kubernetes cluster is a different thing from scanning one, and it ships: TRUSTIVAN reads an AWS account read-only, inventories what runs in a cluster, and joins each running workload to the image it runs — which is what makes “is this vulnerable image actually running?” answerable. What it does not do is parse your manifests. See Cloud and Kubernetes for exactly what each collector reads and what it leaves undetermined.

Secret and misconfiguration detection are available but not on by default: a tenant turns them on per target kind with /api/v1/settings/scanners, and their findings are returned by the API rather than shown in the dashboard. Licence data needs nothing switched on — it is derived from the component inventory every scan already builds, and is read from /api/v1/licenses.