docs/harbor.md
This guide explains how to integrate Kubescape with Harbor, the open-source container registry. The integration uses the harbor-scanner-kubescape adapter, which implements the Harbor Pluggable Scanner API v1.2 and allows Harbor to use Kubescape as an alternative scanner to Trivy and Clair.
⚠️ Community / Experimental Integration
The harbor-scanner-kubescape adapter is a community project that is pending donation to the
goharbororganization. The Helm chart is currently published under a personal namespace (onyx2406), and no stable release has been tagged yet. This means the adapter pod may fail to start until the donation lands and an official image is published.This guide is provided for evaluation purposes only and is not officially supported by the Kubescape project. Once the adapter is accepted into
goharborand a tagged release is available, this guide will be updated with pinned versions.
kubevuln componentkubectl configured to access your clusterThe adapter bridges Harbor's scanning workflow with Kubescape's kubevuln component for image vulnerability analysis.
Harbor → harbor-scanner-kubescape → kubevuln (Kubescape)
↓
Grype + Syft
↓
VulnerabilityManifest CRD
When Harbor triggers a scan:
POST /api/v1/scan request to the adapter with the image details.kubevuln, which scans the image using Grype and Syft.GET /api/v1/scan/{id}/report until results are ready.If the Kubescape operator is not already running in your cluster, install it via Helm:
helm repo add kubescape https://kubescape.github.io/helm-charts/
helm repo update
helm upgrade --install kubescape kubescape/kubescape-operator \
--namespace kubescape \
--create-namespace
Verify the kubevuln component is running:
kubectl get pods -n kubescape | grep kubevuln
Deploy the adapter into the same namespace as Harbor:
helm install harbor-scanner-kubescape \
oci://ghcr.io/onyx2406/harbor-scanner-kubescape/charts/harbor-scanner-kubescape \
--namespace harbor \
--set scanner.kubevulnURL=http://kubevuln.kubescape.svc.cluster.local:8080
Verify the adapter pod is running:
kubectl get pods -n harbor | grep harbor-scanner-kubescape
Kubescapehttp://harbor-scanner-kubescape.harbor.svc.cluster.local:8080To set Kubescape as the default scanner for all projects, click the ⋮ menu next to the scanner and select Set as Default.
Once the adapter is registered, Harbor will use Kubescape to scan images automatically on push (if scan-on-push is enabled) or on demand.
Scan results appear in the Vulnerabilities column of the repository view.
The adapter is configured via environment variables. When deploying with Helm, pass values using --set:
| Variable | Default | Description |
|---|---|---|
SCANNER_API_ADDR | :8080 | Address the adapter HTTP server listens on |
KUBEVULN_URL | http://kubevuln:8080 | Base URL of the kubevuln service |
KUBEVULN_NAMESPACE | kubescape | Kubernetes namespace for Kubescape components |
SCAN_REUSE_TTL | 24h | How long an existing scan result is reused before triggering a fresh scan. Set to 0 to always scan fresh. |
PERSISTENCE_BACKEND | memory | Storage backend for scan jobs. Use redis for production multi-replica deployments. |
By default the adapter serves plain HTTP and expects TLS termination at the cluster edge. To serve HTTPS directly:
kubectl create secret tls harbor-scanner-kubescape-tls \
--cert=path/to/tls.crt \
--key=path/to/tls.key \
-n harbor
helm install harbor-scanner-kubescape \
oci://ghcr.io/onyx2406/harbor-scanner-kubescape/charts/harbor-scanner-kubescape \
--namespace harbor \
--set tls.enabled=true \
--set tls.secretName=harbor-scanner-kubescape-tls \
--set service.port=8443
Update the scanner endpoint in Harbor to use https:// and port 8443.
For production deployments with multiple replicas, use the Redis persistence backend so scan state is shared across pods:
kubectl create secret generic harbor-scanner-redis \
--from-literal=url=redis://:[email protected]:6379/0 \
-n harbor
helm install harbor-scanner-kubescape \
oci://ghcr.io/onyx2406/harbor-scanner-kubescape/charts/harbor-scanner-kubescape \
--namespace harbor \
--set persistence.backend=redis \
--set persistence.redis.secretName=harbor-scanner-redis \
--set replicaCount=2
kubectl get pods -n harbor | grep harbor-scanner-kubescapekubectl logs -n harbor deployment/harbor-scanner-kubescapehttps://.kubevuln pod is running: kubectl get pods -n kubescape | grep kubevulnKUBEVULN_URL value matches the actual service address.kubectl logs -n kubescape deployment/kubevulnThe adapter reuses existing VulnerabilityManifest CRDs for up to 24 hours by default. To force a fresh scan, set SCAN_REUSE_TTL=0 in the Helm values, or trigger a manual scan from the Harbor UI.
With the default memory persistence backend, scan state is lost on pod restart. Ongoing scans return an error to Harbor. For production use, switch to the redis backend so state survives restarts.