agentdata.networkSource

TaintCheck: operators

What a supplier needs to serve taint-check.

Service ID
taint-check
Required version
taint-check >= 1.1
Image
ghcr.io/thefeloniousmonk/taint-check:1.1.1
Minimum RAM
2 GB
Minimum disk
5 GB
RPC types
REST (expected)

Backend

The taint-check container (Node 22, no third-party dependencies; built from github.com/TheFeloniousMonk/portal-services, taint-check/backend) behind the HA RelayMiner with the rest backend pointed at it. No auth toward the backend; callers cannot send headers. On a schedule it mirrors the OSV.dev per-ecosystem all.zip archives (gs://osv-vulnerabilities, which already include the OpenSSF Malicious Packages MAL- records), builds an in-memory index, and mirrors it to a JSON snapshot on disk that is reloaded on restart; scans are served from that index, with the OSV querybatch API as an optional live backstop. Needs outbound access to storage.googleapis.com for the mirror sync, to the allowed code hosts for lockfile.url, and to the ecosystem registries for optional heuristics. CPU is light; RAM is dominated by the index, which is rebuilt off to the side during a sync. Tunable with TC_* environment variables.

REST

Backend: taint-check container on :8080; mount at /

Only POST /v1/scan, GET /v1/version, GET /healthz, GET /v1/capabilities, and GET /v1/openapi.json are expected. Every response is a JSON object, including errors (which carry an 'error' field); no field carries non-JSON content.

Notes

Every request is a POST JSON body to /v1/scan; scans finish in under a second, and fetching a lockfile.url adds up to 8 s. No rate limits to disable. SAGE operators: type generic (its name for passthrough), rpc_types ["rest"], relay_timeout at least 15s; see sage-service.yaml in the service repository.

Health checks

TypeRequestExpectWhy
RESTGET /v1/version$.service matches ^taint-check$Identity probe: pins the backend to this service so a wrong backend cannot be staked under this id.
RESTGET /healthz$.status matches ^ok$Readiness probe: 200 only once an OSV snapshot is loaded, so a supplier serving stale-empty data does not pass.
RESTPOST /v1/scan
{"components":[{"ecosystem":"npm","name":"minimist","version":"1.2.0"}],"options":{"heuristics":false}}
$.findings[0].verdict matches ^vulnerable$Functional probe: minimist 1.2.0 is permanently affected by a published prototype-pollution advisory, so the verdict is stable and deterministic. Cheap; a single indexed lookup.

Running it

Build the backend from backend/, or pull the published image:

docker pull ghcr.io/thefeloniousmonk/taint-check:1.1.1

Images are tagged with the version the backend reports at GET /v1/version. Keep up with the required version above; an older backend can reject requests that newer callers send.

The service's deploy/ folder has:

The service's docs cover its settings and anything a supplier must provide.