← News
/PLAYBOOK · 2026-08-26

Harbor Image Registry Security Hardening: Image Scanning and Access Control

Complete Harbor hardening for teams managing container images: HTTPS, least-privilege RBAC, Trivy scanning, image signing, and Robot-account pulls. Prevents image supply-chain poisoning and unauthorized access.

Scope

This guide is for enterprise teams using Harbor to manage Docker and Kubernetes images. A registry exposed to the internet, shared admin accounts, no vuln scan after push, or K8s pulling with personal accounts all create image supply-chain poisoning, unauthorized access, and malicious-image ingest risk. Hardening below applies to Harbor 2.x and later.

Prerequisites

How It Works

Harbor security is four layers: transport (HTTPS against traffic sniffing), auth (RBAC roles and least-privilege Robot accounts), detection (built-in Trivy scanning and CVE allowlist), integrity (cosign/Notation signature verification). Typical supply-chain path: attacker cracks a weak-password registry → uploads a backdoored image → cluster pulls and runs it. Forced scanning blocks malicious ingest, signature verification stops tampering, Robot accounts isolate pull credentials. Together they systematically shrink the risk.

Procedure

Step 1: Enable HTTPS

Edit `harbor.yml`. Configure certificate and private key:

hostname: harbor.example.com
https:
  port: 443
  certificate: /data/cert/harbor.crt
  private_key: /data/cert/harbor.key
http:
  port: 80
  # Disable HTTP when used only on the intranet
  # enabled: false

Run `./install.sh` to apply. Production certs should use Lets Encrypt or an enterprise CA to avoid client trust issues.

Step 2: Enable Trivy Scanning and Block Policy

In Harbor UI: Project → Configuration → Security. Check:

Step 3: Configure Robot Accounts for K8s Pulls

Do not use personal accounts in the cluster. Create a Robot account per namespace. Grant pull only on the matching project:

# In Harbor UI: Project → Robot Accounts → New Robot Account
# Check only push / pull permissions; copy the generated token after saving

# Create the pull-credential Secret on the cluster
kubectl create secret docker-registry harbor-pull \
  --docker-server=harbor.example.com \
  --docker-username='robot$prod' \
  --docker-password='' \
  --namespace=prod

# Reference it in the Deployment
kubectl patch deployment app -n prod -p '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"harbor-pull"}]}}}}'

Step 4: Enable Image Signature Verification

Sign images with cosign. Enable signature verification in the Harbor project config:

# Generate a key pair and sign
cosign generate-key-pair
cosign sign --key cosign.key harbor.example.com/prod/app:1.0.0

# Project → Configuration → Security → Enable 'Verify image signatures with cosign/Notation'
# Unsigned images cannot be pulled and deployed

Step 5: Configure Retention Policy and Audit

Purge unused images. Keep audit logs:

# Project → Configuration → Retention Policy
# Example rule: retain images from the last 30 days and the most recent 10 tags; clean up the rest

# Audit: check unauthorized access attempts
grep -i "401\|unauthorized" /var/log/harbor/core/*.log | tail -50

Verification

# 1. Verify HTTPS access
curl -k -u admin: https://harbor.example.com/api/v2.0/projects

# 2. Verify scan blocking: pushing an image with high-risk vulnerabilities should be rejected or flagged
docker push harbor.example.com/prod/bad-image:1.0

# 3. Verify Robot account: pull-only permission, push should return 403
docker login harbor.example.com -u 'robot$prod' -p ''
docker push harbor.example.com/prod/app:test  # expected 403

FAQ

Q1: Scan found a high/critical vulnerability but the business must ship. What then?

Temporarily allow it in the project CVE allowlist. Record approver, reason, and time. Fix and re-push after the business window. Allowlisting must leave an audit trail. Close the loop with a ticket system.

Q2: Robot accounts vs personal accounts?

Robot accounts can only access a specified project, permissions down to push/pull, cannot log into the Web UI, tokens can be rotated anytime, small blast radius. Personal accounts have broad privileges and are bound to people. They must not appear in cluster Secrets.

Q3: Air-gapped intranet cannot update the Trivy vuln DB?

Pre-download the offline vuln-DB pack on a connected host. Update via `trivy image --offline-scan` or Harbor's vuln-DB import. Or configure an internal proxy to the official vuln-DB mirror.

Summary

Harbor hardening core: HTTPS transport + least-privilege RBAC + mandatory vuln scanning + image signing. Put the image registry in the supply-chain security program. Run scan and sign in CI/CD at build time so malicious images never reach production. That builds a complete container-image trust chain.