Skip to content

Sensor Architecture

A HarborGuard sensor is a small agent that runs inside your network, polls the API for scan jobs assigned to a specific registry, executes the scanners locally, and ships the results back. Image bytes never traverse the public internet.

When you want a sensor

  • Air-gapped or restricted-egress networks. The registry is reachable from inside your VPC but not from the public internet.
  • Data sovereignty. Image bytes must not leave a specific region or jurisdiction.
  • Private registry credentials you do not want to give a third party. Sensors authenticate to your registry locally.
  • Latency / cost. Skip uploading multi-GB images to a remote scanner.

How a sensor talks to HarborGuard

sensor                                        HarborGuard API
  |                                                |
  |-- POST /api/agent/register ------------------->|   identifies itself, capabilities,
  |<------ { agentId } ----------------------------|   bound registry
  |                                                |
  |-- POST /api/agent/heartbeat (every ~30s) ----->|   keeps status = online
  |                                                |
  |-- GET  /api/agent/jobs?agentId=... ----------->|
  |<------ { jobs: [{ id, scan: {...} }] } --------|   atomic claim of a PENDING scan
  |                                                |
  | run trivy/grype/syft/dockle/osv/dive locally   |
  |                                                |
  |-- POST /api/scans/upload ---------------------->|  sends a result envelope
  |                                                |   (vulns, packages, layers, logs)
  |<------ { ok: true } ---------------------------|

All sensor endpoints use API-key auth (x-api-key or Authorization: Bearer ...). The key is scoped to the org and to the sensor's bound registry.

Atomic job claim

Multiple sensor replicas can poll the same registry safely. Job assignment uses an atomic database claim inside a single transaction, so each PENDING scan is claimed by exactly one sensor. The sensor that wins the row updates status to IN_PROGRESS and gets the job details in the response. No coordination service is needed.

The default batch size is 1 - sensors poll again after each job completes. This naturally distributes work across replicas based on availability.

Bound registry

Each sensor is bound to exactly one registry. Only PENDING scans for tags in that registry will be handed to it. To cover multiple registries, run one sensor per registry (or one sensor with multiple replicas per registry).

If a sensor's registry is set to scanning.method = "sensor", the scheduler will create PENDING scans there and the sensor will pick them up. If method = "cloud", the platform handles the scan instead and the sensor stays idle.

Capabilities

A sensor advertises capabilities at registration. The two currently observed are:

  • scan - run vulnerability scans (always present).
  • patch - execute patch operations (rebuild and push fixed images).

Sensors with patch capability also receive patch jobs from the same poll endpoint, with claim ordering randomized so neither workload starves the other.

Health and status

StatusMeaning
onlineHeartbeat received within the last 2 minutes.
scanningCurrently executing a job.
offlineNo heartbeat for >2 minutes. The bound registry is marked ERROR.

See Sensor Health for details.

Where to deploy

On this page