Skill v1.0.1
currentAutomated scan100/100+7 new
name: securing-container-registry-with-harbor description: Harbor is an open-source container registry that provides security features including vulnerability scanning (integrated Trivy), image signing (Notary/Cosign), RBAC, content trust policies, replicatio domain: cybersecurity subdomain: container-security tags:
- containers
- kubernetes
- docker
- security
- registry
- harbor
version: '1.0' author: mahipal license: Apache-2.0 nist_csf:
- PR.PS-01
- PR.IR-01
- ID.AM-08
- DE.CM-01
mitre_attack:
- T1610
- T1611
- T1609
- T1525
- T1190
Securing Container Registry with Harbor
Overview
Harbor is an open-source container registry that provides security features including vulnerability scanning (integrated Trivy), image signing (Notary/Cosign), RBAC, content trust policies, replication, and audit logging. Securing Harbor involves configuring these features to enforce image provenance, prevent vulnerable image deployment, and maintain registry access control.
When to Use
- When deploying or configuring securing container registry with harbor capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- Harbor 2.10+ installed (Helm or Docker Compose)
- TLS certificates for HTTPS
- Trivy scanner integration
- OIDC/LDAP for authentication
- Kubernetes cluster (for deployment target)
Workflow
Step 1: Install Harbor with Security Configuration
# harbor-values.yaml for Helm deploymentexpose:type: ingresstls:enabled: truecertSource: secretsecret:secretName: harbor-tlsnotarySecretName: harbor-tlsingress:hosts:core: harbor.example.comnotary: notary.example.comexternalURL: https://harbor.example.compersistence:enabled: trueresourcePolicy: "keep"harborAdminPassword: "<strong-password>"trivy:enabled: truegitHubToken: "<github-token>"severity: "CRITICAL,HIGH,MEDIUM"autoScan: truenotary:enabled: truecore:secretKey: "<32-char-secret>"database:type: externalexternal:host: postgres.example.comport: "5432"username: harborpassword: "<db-password>"sslmode: require
helm repo add harbor https://helm.getharbor.iohelm install harbor harbor/harbor -f harbor-values.yaml -n harbor --create-namespace
Step 2: Configure Vulnerability Scanning Policies
# Enable auto-scan on push (via Harbor API)curl -k -X PUT "https://harbor.example.com/api/v2.0/projects/myproject" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"metadata": {"auto_scan": "true","severity": "critical","prevent_vul": "true","reuse_sys_cve_allowlist": "true"}}'
Step 3: Configure Content Trust
# Enable content trust at project levelcurl -k -X PUT "https://harbor.example.com/api/v2.0/projects/myproject" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"metadata": {"enable_content_trust": "true","enable_content_trust_cosign": "true"}}'# Sign image with Cosigncosign sign --key cosign.key harbor.example.com/myproject/myapp:v1.0.0# Verify signaturecosign verify --key cosign.pub harbor.example.com/myproject/myapp:v1.0.0
Step 4: Configure RBAC and Project Isolation
# Create project with private visibilitycurl -k -X POST "https://harbor.example.com/api/v2.0/projects" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"project_name": "production","metadata": {"public": "false","auto_scan": "true","prevent_vul": "true","severity": "high"}}'# Harbor roles: ProjectAdmin, Maintainer, Developer, Guest, LimitedGuest# Add member with specific rolecurl -k -X POST "https://harbor.example.com/api/v2.0/projects/production/members" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"role_id": 3,"member_user": {"username": "developer1"}}'
Step 5: Configure Immutable Tags and Retention
# Create tag immutability rule (prevent overwriting release tags)curl -k -X POST "https://harbor.example.com/api/v2.0/projects/production/immutabletagrules" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"tag_filter": "v*","scope_selectors": {"repository": [{"kind": "doublestar", "decoration": "repoMatches", "pattern": "**"}]}}'# Configure retention policy (keep last 10 tags, delete untagged after 7 days)curl -k -X POST "https://harbor.example.com/api/v2.0/retentions" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)" \-H "Content-Type: application/json" \-d '{"algorithm": "or","rules": [{"action": "retain","template": "latestPushedK","params": {"latestPushedK": 10},"tag_selectors": [{"kind": "doublestar", "decoration": "matches", "pattern": "**"}],"scope_selectors": {"repository": [{"kind": "doublestar", "decoration": "repoMatches", "pattern": "**"}]}}],"trigger": {"kind": "Schedule", "settings": {"cron": "0 0 * * *"}}}'
Step 6: OIDC Authentication Integration
# Harbor configuration for OIDCauth_mode: oidc_authoidc_name: "Okta"oidc_endpoint: "https://company.okta.com/oauth2/default"oidc_client_id: "harbor-client-id"oidc_client_secret: "harbor-client-secret"oidc_groups_claim: "groups"oidc_admin_group: "harbor-admins"oidc_scope: "openid,profile,email,groups"oidc_verify_cert: trueoidc_auto_onboard: true
Validation Commands
# Test vulnerability prevention (should block pull of vulnerable image)docker pull harbor.example.com/production/vulnerable-app:latest# Expected: Error - image blocked due to vulnerabilities# Verify content trust enforcementDOCKER_CONTENT_TRUST=0 docker push harbor.example.com/production/unsigned:latest# Expected: Push rejected due to content trust policy# Check scan results via APIcurl -k "https://harbor.example.com/api/v2.0/projects/production/repositories/myapp/artifacts/v1.0.0/additions/vulnerabilities" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"# Audit log checkcurl -k "https://harbor.example.com/api/v2.0/audit-logs?page=1&page_size=10" \-H "Authorization: Basic $(echo -n admin:Harbor12345 | base64)"