Skip to content

Bring-your-own-scanner (BYOS)

Upwarden ships with a built-in scanner (similarity-search over package embeddings). BYOS — bring-your-own-scanner — is the integration path for customers who already run a different scanning stack (commercial vendor, in-house tool, etc.) and want Upwarden to call into it instead of (or in addition to) the built-in one.

  • Enterprises with an existing AppSec scanner they’re contractually required to use.
  • Customers running a proprietary detection model they don’t want to expose to Upwarden’s built-in pipeline.
  • Anyone who wants to layer a second opinion on top of Upwarden’s built-in verdicts.

If you don’t have an existing scanner, the built-in one is fine — BYOS is opt-in.

BYOS works via a callback API. Upwarden exposes a POST endpoint your scanner calls to deliver a verdict for a specific package version. The endpoint is authenticated with your project’s vk_ key.

POST /api/v1/scan/callback
Authorization: Bearer vk_…
Content-Type: application/json
{
"ecosystem": "npm",
"packageName": "leftpad",
"version": "1.0.0",
"verdict": "BLOCKED",
"decisionReason": {
"scanner": "your-scanner-name",
"scannerVersion": "1.2.3",
"findings": [
{
"rule": "obfuscated-code",
"severity": "high",
"message": "Heavily obfuscated install script with network access"
}
]
},
"verdictSource": "byos:your-scanner-name"
}

Upwarden validates the envelope, stamps it into audit_log with a verdictSource that names your scanner, and caches the verdict for the package-version. Subsequent installs of that version get the cached verdict without re-running your scanner.

The callback flow is asynchronous. The typical shape:

  1. Developer runs npm install foo@1.0.0.
  2. Upwarden sees a never-before-seen version. It posts the artefact metadata to your scanner’s intake endpoint (configured per-tenant) and QUARANTINES the request, returning 403 [UPWARDEN] Package 'foo@1.0.0' is currently QUARANTINED. Analysis in progress.
  3. Your scanner runs, produces a verdict.
  4. Your scanner posts the verdict back to /api/v1/scan/callback.
  5. The developer retries (or their CI’s retry policy kicks in). The cached verdict is now there; the install proceeds (or 403s with the real reason).

The QUARANTINE window is FAST_PASS_TIMEOUT_MS long (default 3s). If your scanner is faster than that, the request gets the verdict synchronously and there’s no QUARANTINE → retry round-trip.

BYOS is configured on a per-tenant basis (different customers may use different scanners). The operator wires:

  • Intake URL — where Upwarden POSTs the artefact metadata to trigger your scanner.
  • Intake auth — a shared secret or mTLS pair Upwarden uses to authenticate to your scanner.
  • Callback policy — whether your scanner’s verdict replaces or augments the built-in one (e.g. “block if either says BLOCK” vs. “trust BYOS entirely”).

Today this wiring is provisioned operator-side rather than through a self-serve endpoint (managed customers set it up with Upwarden); a self-serve admin-API path and a dashboard surface for it are both on the roadmap.

Every verdict your scanner produces lands as a row in audit_log with verdictSource: byos:<your-scanner-name>. That’s the discriminator your SIEM can pivot on — WHERE verdictSource LIKE 'byos:%' gives you every BYOS verdict, distinct from the built-in scanner’s proxy:* and scanner:* sources.