PS Product SecurityKnowledge Base

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

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 Services or 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

  1. make projects private by default;
  2. split robot accounts by purpose and project;
  3. enable scanner coverage and scheduled scan-all;
  4. add immutable tags for release lines;
  5. add retention and GC discipline;
  6. enforce Cosign or Notation for the highest-trust projects;
  7. refine replication and promotion flows.