Harbor Registry Hardening
Intro: Harbor is not just an image bucket. It is part of the software supply chain control plane. Hardening Harbor means hardening who can push, what can be pulled, what gets scanned, what expires, and which signatures are trusted.
What this page includes
- a practical Harbor hardening baseline;
- project, robot-account, scanning, retention, and signing guidance;
- UI paths and API examples;
- older-versus-current notes where Harbor or adjacent tooling evolved.
Where Harbor fits in the trust model
Harbor typically sits between:
- CI systems that push artifacts;
- scanners that assess images and other OCI artifacts;
- platform workloads that pull images into clusters or VM estates;
- promotion workflows that copy or replicate images across trust tiers.
If Harbor is weak, a team can still have strong source scanning and weak release trust.
Security goals
A hardened Harbor deployment should make these outcomes easy:
- separate dev, integration, release, and production mirror trust tiers;
- narrow push rights using robot accounts and project scope;
- scan artifacts on push or on schedule;
- prevent pull of unsigned or untrusted artifacts where policy requires it;
- keep tag sprawl under control with immutable tags and retention;
- retain useful audit data for push, delete, policy, and membership changes.
Quick-start hardening checklist
| Control area | Minimum good state |
|---|---|
| TLS | valid certificates, no plaintext registry access |
| Admin access | SSO where possible, MFA at the IdP, no shared admin users |
| Robot accounts | short-lived, least privilege, project-scoped by default |
| Projects | private by default unless there is a real distribution need |
| Scanning | Trivy or supported external scanner enabled, scan-on-push or scan-all scheduled |
| Tag control | immutable tags for release lines |
| Retention | explicit retention rules and garbage collection |
| Signing | enforce Cosign or Notation in high-trust projects |
| Replication | one-way promotion patterns, not free-form cross-push |
| Auditability | central log collection and periodic access review |
Recommended project layout
A simple structure that scales well:
sandbox/*โ developer or feature-branch images;integration/*โ candidate images after first scan;release/*โ signed images approved for promotion;prod-mirror/*โ pull-only mirror for production clusters.
UI hardening steps
1. Make projects private by default
UI path
Administration -> Configuration -> System Settings- set project creation defaults conservatively.
Project-level check
Projects -> <project> -> Configuration- verify the project is not public unless distribution requirements justify it.
2. Use project-scoped robot accounts first
UI path
Projects -> <project> -> Robot Accounts- create a robot with only the repository actions it needs.
Use system robot accounts only when automation truly crosses many projects.
3. Configure robot token expiry
UI path
Administration -> Configuration -> System Settings- review
Robot Token Expiration (Days).
Recommended stance:
- shorter expiry for CI push accounts;
- do not use never-expiring tokens unless there is a very clear compensating control.
4. Enable vulnerability scanning
UI path
Administration -> Interrogation Servicesor scanner configuration section, depending on version;Projects -> <project> -> Scanner- select the project scanner if you use more than one.
5. Enable deployment security for signed images
UI path
Projects -> <project> -> Configuration- enable Cosign and/or Notation enforcement where appropriate.
6. Enforce immutable tags for release repos
UI path
Projects -> <project> -> Tag Immutability- create rules for release tags such as
^v[0-9]+\.[0-9]+\.[0-9]+$or^release-.*$.
7. Configure retention and garbage collection
UI path
Projects -> <project> -> Tag Retention- define rules to keep the right amount of rollback history.
Administration -> Garbage Collection- run GC after validating retention and deletion workflows.
Example harbor.yml baseline fragment
hostname: harbor.example.com
https:
port: 443
certificate: /data/cert/server.crt
private_key: /data/cert/server.key
harbor_admin_password: change-me-immediately
external_url: https://harbor.example.com
trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
jobservice:
max_job_workers: 10
log:
level: info
rotate_count: 30
rotate_size: 200M
location: /var/log/harbor
What to review in this fragment
- rotate the bootstrap admin password immediately;
- confirm certificate lifecycle and renewal ownership;
- keep Trivy updates healthy unless the environment is explicitly offline;
- retain enough job and system logs for operational review.
Robot account patterns
Preferred pattern
- one robot account per automation purpose;
- one project scope where possible;
- short expiration;
- secret stored in the CI credential store, not in repo variables or plaintext files;
- refresh and replace on schedule.
Docker/OCI login example
docker login harbor.example.com \
--username 'robot$ci-release' \
--password "$HARBOR_ROBOT_TOKEN"
API examples
Create a project
curl -sS -u admin:"$HARBOR_ADMIN_PASSWORD" \
-H 'Content-Type: application/json' \
-X POST https://harbor.example.com/api/v2.0/projects \
-d '{"project_name":"release-platform","metadata":{"public":"false"}}'
Create an immutable tag rule
curl -sS -u admin:"$HARBOR_ADMIN_PASSWORD" \
-H 'Content-Type: application/json' \
-X POST https://harbor.example.com/api/v2.0/projects/release-platform/immutabletagrules \
-d '{
"disabled": false,
"tag_selectors": [{"kind":"doublestar","decoration":"matches","pattern":"v*"}],
"repo_selectors": [{"kind":"doublestar","decoration":"matches","pattern":"**"}]
}'
Trigger a scan for a specific artifact
curl -sS -u admin:"$HARBOR_ADMIN_PASSWORD" \
-X POST \
https://harbor.example.com/api/v2.0/projects/release-platform/repositories/invoice-api/artifacts/sha256:REPLACE_ME/scan
Signing and verification flow
Older pattern you may still encounter
- Docker Content Trust / Notary v1-centric discussions;
- tag-based trust language with loose verification discipline.
Current pattern
- Cosign and/or Notation signatures tied to digest-based promotion workflows;
- Harbor project policy enforcing signature verification for pull in higher-trust projects.
Example Cosign signing flow
export COSIGN_EXPERIMENTAL=1
IMAGE=harbor.example.com/release-platform/invoice-api@sha256:REPLACE_ME
cosign sign --key cosign.key "$IMAGE"
cosign verify --key cosign.pub "$IMAGE"
Example Notation-style verification flow
notation verify harbor.example.com/release-platform/invoice-api@sha256:REPLACE_ME
Common Harbor weaknesses and fixes
| Weakness | Why it matters | Better approach |
|---|---|---|
| public projects by default | broad read scope and accidental disclosure | private by default |
| shared admin credentials | poor accountability | named admin accounts and SSO |
| global robot reuse | huge blast radius | project-scoped robot accounts |
| mutable release tags | silent supply chain confusion | immutable release tags |
| scan only when convenient | stale findings | scan on push or scheduled scan-all |
| no retention plan | tag sprawl and rollback confusion | explicit retention rules |
| no signature enforcement | anyone can pull unsigned release images | enable Cosign/Notation policy |
| direct push into production repo | bypassed promotion evidence | staged promotion model |
| no external logs | weak investigations | central log collection |
| old scanner assumptions | version drift and false certainty | review scanner coverage and DB freshness |
Review questions for a Harbor assessment
- who can push into the release-tier projects?
- which projects enforce signature verification today?
- how are robot secrets rotated and who owns them?
- what is the retention policy and how often is garbage collection run?
- which artifacts are scanned on push versus by schedule?
- are there any public projects that exist only for convenience?
- can a CI pipeline write directly into a repo pulled by production?
Practical rollout order
- make projects private by default;
- split robot accounts by purpose and project;
- enable scanner coverage and scheduled scan-all;
- add immutable tags for release lines;
- add retention and GC discipline;
- enforce Cosign or Notation for the highest-trust projects;
- refine replication and promotion flows.