CIS Harbor Registry Benchmark
Security configuration recommendations for Harbor container registry
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for Harbor container registry deployments. It covers admin credential hardening, OIDC authentication, vulnerability scanning with severity gates, content trust and image signing, replication policies, robot account management, TLS enforcement, audit logging, tag retention and immutability, version management, and storage optimization.
| Section | Area | Focus |
|---|---|---|
| 1 | Access Control | Admin hardening and OIDC authentication |
| 2 | Image Security | Auto-scan vulnerability gates and image signing |
| 3 | Project Management | Replication policies and robot account scoping |
| 4 | Transport & Audit | TLS enforcement and centralized audit logging |
| 5 | Tag Management | Retention policies and immutable tag rules |
| 6 | System Maintenance | Version management and database backups |
| 7 | Operations & Optimization | Proxy cache and garbage collection scheduling |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Harbor deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Access Control
▶1.1 Authentication
▶This recommendation verifies that default admin password is changed and additional accounts created on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Harbor admin account:
curl -s -k -u 'admin:Harbor12345' https://harbor.example.com/api/v2.0/users/current | python3 -m json.tool
# Verify default password changed (should fail with default):
curl -s -o /dev/null -w '%{http_code}' -k -u 'admin:Harbor12345' https://harbor.example.com/api/v2.0/systeminfo# Change admin password:
curl -k -u 'admin:Harbor12345' -X PUT \
https://harbor.example.com/api/v2.0/users/1/password \
-H 'Content-Type: application/json' \
-d '{"old_password":"Harbor12345","new_password":"<STRONG_PASSWORD>"}'
# Create non-admin user:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/users \
-H 'Content-Type: application/json' \
-d '{"username":"deployer","password":"<PASS>","realname":"Deploy User","email":"deploy@example.com"}'This recommendation verifies that OIDC authentication is configured with group mapping on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check OIDC authentication: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/configurations | python3 -m json.tool | grep -i 'auth_mode\|oidc'
# Configure OIDC authentication:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/configurations \
-H 'Content-Type: application/json' \
-d '{
"auth_mode":"oidc_auth",
"oidc_name":"Keycloak",
"oidc_endpoint":"https://keycloak.example.com/realms/harbor",
"oidc_client_id":"harbor",
"oidc_client_secret":"<SECRET>",
"oidc_scope":"openid,profile,email,groups",
"oidc_auto_onboard":true,
"oidc_groups_claim":"groups"
}'2 — Image Security
▶2.1 Scanning & Signing
▶This recommendation verifies that auto-scan on push with vulnerability severity gate is enabled on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check vulnerability scanning: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/projects | python3 -m json.tool | grep -i 'auto_scan\|severity' # Check scanner status: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/scanners | python3 -m json.tool
# Enable auto-scan on push:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/projects/1 \
-H 'Content-Type: application/json' \
-d '{"metadata":{"auto_scan":"true"}}'
# Set vulnerability severity gate:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/projects/1 \
-H 'Content-Type: application/json' \
-d '{"metadata":{"severity":"high","prevent_vul":"true"}}'This recommendation ensures that content trust with cosign image signing is enforced on the Harbor container registry. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the Harbor container registry may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check content trust (Notary): curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/projects | python3 -m json.tool | grep 'content_trust'
# Enable content trust:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/projects/1 \
-H 'Content-Type: application/json' \
-d '{"metadata":{"enable_content_trust":"true","enable_content_trust_cosign":"true"}}'
# Sign images with cosign:
cosign sign --key cosign.key harbor.example.com/project/image:tag
# Verify signatures:
cosign verify --key cosign.pub harbor.example.com/project/image:tag3 — Project Management
▶3.1 Replication & Access
▶This recommendation verifies that replication policies and storage quotas are configured on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check replication policies: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/replication/policies | python3 -m json.tool # Check storage quotas: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/quotas | python3 -m json.tool
# Create replication policy:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/replication/policies \
-H 'Content-Type: application/json' \
-d '{
"name":"prod-replication",
"src_registry":{"id":0},
"dest_registry":{"id":1},
"trigger":{"type":"event_based"},
"filters":[{"type":"name","value":"production/**"}],
"enabled":true
}'
# Set project storage quota:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/quotas/1 \
-H 'Content-Type: application/json' \
-d '{"hard":{"storage":10737418240}}'This recommendation verifies that robot accounts use project-scoped least-privilege permissions on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check robot accounts: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/robots | python3 -m json.tool # Check project membership: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/projects/1/members | python3 -m json.tool
# Create project-scoped robot account:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/robots \
-H 'Content-Type: application/json' \
-d '{
"name":"ci-pipeline",
"duration":90,
"level":"project",
"permissions":[{
"namespace":"production",
"kind":"project",
"access":[{"resource":"repository","action":"push"},{"resource":"repository","action":"pull"}]
}]
}'4 — Transport & Audit
▶4.1 TLS & Logging
▶This recommendation ensures that HTTPS is enforced with valid TLS certificates on the Harbor container registry. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the Harbor container registry may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check HTTPS configuration: curl -sv https://harbor.example.com 2>&1 | grep -E 'SSL|TLS|subject|issuer' # Verify certificate: openssl s_client -connect harbor.example.com:443 2>/dev/null | openssl x509 -noout -dates -subject
# Configure Harbor with TLS (harbor.yml): # hostname: harbor.example.com # https: # port: 443 # certificate: /data/cert/server.crt # private_key: /data/cert/server.key # Generate certificates: mkdir -p /data/cert openssl req -x509 -nodes -days 365 -newkey rsa:4096 \ -keyout /data/cert/server.key \ -out /data/cert/server.crt \ -subj '/CN=harbor.example.com' # Reinstall Harbor: ./install.sh --with-trivy --with-notary
This recommendation verifies that audit logs are forwarded to centralized SIEM on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check audit log settings: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/audit-logs?page_size=5 | python3 -m json.tool # Check log rotation: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/configurations | python3 -m json.tool | grep -i 'audit\|log'
# Enable audit log forwarding:
# In harbor.yml:
# log:
# level: info
# local:
# rotate_count: 50
# rotate_size: 200M
# location: /var/log/harbor
# external_endpoint:
# protocol: tcp
# host: siem.example.com
# port: 514
# Set audit log retention:
curl -k -u 'admin:$PASS' -X PUT \
https://harbor.example.com/api/v2.0/configurations \
-H 'Content-Type: application/json' \
-d '{"audit_log_forward_endpoint":"siem.example.com:514"}'5 — Tag Management
▶5.1 Retention & Immutability
▶This recommendation verifies that tag retention policies are configured to limit image sprawl on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check tag retention policies: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/retentions | python3 -m json.tool
# Create tag retention policy:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/retentions \
-H 'Content-Type: application/json' \
-d '{
"rules":[{
"template":"latestPushedK",
"params":{"latestPushedK":10},
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"matches","pattern":"**"}]}
}],
"trigger":{"kind":"Schedule","settings":{"cron":"0 0 * * 0"}},
"scope":{"level":"project","ref":1}
}'This recommendation verifies that immutable tag rules protect production image versions on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check immutable tag rules: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/projects/1/immutabletagrules | python3 -m json.tool
# Create immutable tag rule:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/projects/1/immutabletagrules \
-H 'Content-Type: application/json' \
-d '{
"tag_selectors":[{
"kind":"doublestar",
"decoration":"matches",
"pattern":"v*"
}],
"scope_selectors":{
"repository":[{
"kind":"doublestar",
"decoration":"matches",
"pattern":"production/**"
}]
}
}'6 — System Maintenance
▶6.1 Upgrades & Backup
▶This recommendation verifies that Harbor is running a current supported version on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Harbor version: curl -s -k https://harbor.example.com/api/v2.0/systeminfo | python3 -m json.tool | grep 'harbor_version' # Check component health: curl -s -k https://harbor.example.com/api/v2.0/health | python3 -m json.tool
# Upgrade Harbor: cd /opt/harbor ./prepare docker compose down docker compose up -d # Or full upgrade: wget https://github.com/goharbor/harbor/releases/download/v2.x.y/harbor-offline-installer-v2.x.y.tgz tar xzf harbor-offline-installer-v2.x.y.tgz cd harbor ./install.sh --with-trivy
This recommendation verifies that database and configuration backups are automated on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check database backup: docker exec harbor-db pg_dump -U postgres registry | head -5 # Check S3 storage backend: grep -A10 'storage_service' /opt/harbor/harbor.yml
# Configure database backup:
cat > /usr/local/bin/harbor-db-backup.sh << 'SCRIPT'
#!/bin/bash
BACKUP_DIR=/opt/harbor-backups
mkdir -p $BACKUP_DIR
DATE=$(date +%Y%m%d)
docker exec harbor-db pg_dump -U postgres registry > $BACKUP_DIR/harbor-db-${DATE}.sql
tar czf $BACKUP_DIR/harbor-config-${DATE}.tar.gz /opt/harbor/harbor.yml /data/cert/
find $BACKUP_DIR -mtime +30 -delete
SCRIPT
chmod +x /usr/local/bin/harbor-db-backup.sh
echo '0 2 * * * root /usr/local/bin/harbor-db-backup.sh' > /etc/cron.d/harbor-backup7 — Operations & Optimization
▶7.1 Proxy Cache & GC
▶This recommendation verifies that proxy cache is configured for upstream registries on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check proxy cache configuration: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/projects?type=proxy_cache | python3 -m json.tool
# Create proxy cache project for Docker Hub:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/registries \
-H 'Content-Type: application/json' \
-d '{"name":"dockerhub","type":"docker-hub","url":"https://hub.docker.com"}'
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/projects \
-H 'Content-Type: application/json' \
-d '{"project_name":"dockerhub-cache","registry_id":1,"metadata":{"auto_scan":"true"}}'This recommendation verifies that garbage collection is scheduled for storage optimization on the Harbor container registry. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Harbor container registry vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check garbage collection schedule: curl -s -k -u 'admin:$PASS' https://harbor.example.com/api/v2.0/system/gc/schedule | python3 -m json.tool
# Schedule garbage collection:
curl -k -u 'admin:$PASS' -X POST \
https://harbor.example.com/api/v2.0/system/gc/schedule \
-H 'Content-Type: application/json' \
-d '{"schedule":{"type":"Weekly","cron":"0 0 0 * * 0"},"parameters":{"delete_untagged":true}}'