Summary
Let users import a model from Hugging Face into a Harbor project as an OCI
model-spec (CNAI) artifact, with optional scheduled re-sync. You give a HF repo
slug (plus optional revision, subfolder, and token); Harbor resolves the model,
converts its files into a model-spec artifact, and stores it in a target
repository — so Harbor can be one governed registry for both images and models.
Background
Harbor already understands OCI model artifacts via the CNAI/model-spec processor
(model card, files, license, distinct artifact type). What's missing is a
supported on-ramp: getting a model from Hugging Face — the de facto hub for open
models — into Harbor today means an out-of-band "download, convert, push" loop.
That friction hurts three groups who want Harbor in this path: teams
standardizing on OCI model artifacts, air-gapped/regulated orgs that must pull
public models into a governed internal registry, and platform teams who'd rather
run one registry than a separate model store. This proposal makes the import a
native Harbor operation.
Proposal
A project-scoped Model Import capability:
- Policy — a new project-scoped resource: HF repo ID, revision (default
main), optional subfolder, target repo/tag, optional token, and a trigger
that is manual or scheduled (cron).
- Import job — a new
MODEL_IMPORT jobservice job resolves the model via the
HF API, streams each file, and assembles a model-spec OCI artifact (config plus
per-file layers typed as weights/config/code/docs), pushes it, and tags it,
reporting progress via check-ins.
- Metadata & sync — captures model-card metadata (source URL, commit SHA,
license, etc.) into the config; records the last imported commit SHA so
repeated/scheduled runs are a no-op when upstream is unchanged.
- Tokens — user-supplied HF tokens (for private/gated models) are stored
encrypted at rest, used only by the job, and never returned by the API.
- REST API — endpoints under
/projects/{project_name}/model-import/… for
policy CRUD, executions/tasks/logs, and a validate preview (resolve a
repo/revision, preview file count and metadata) before importing. Authorized
against the existing repository RBAC resource/actions.
- Repository type (companion change) — a
type field (IMAGE/MODEL) on
the repository API and portal grid, derived from a repo's artifacts (any
CNAI/model artifact ⇒ MODEL).
- Portal UI — a guided "Import Model from Hugging Face" flow.
The source path (resolve → stream → convert → push) sits behind interfaces so
other sources can be added later, but Hugging Face is the only source here.
Non-Goals
- Model serving/inference, and training/fine-tuning — import and governance only.
- Sources other than Hugging Face (S3, MLflow, etc.) — the interfaces anticipate
them; none are implemented here.
- Exporting models back to Hugging Face — import is one-way.
Rationale
Why a dedicated subsystem instead of a Hugging Face replication adapter?
Replication moves existing OCI artifacts registry-to-registry; Hugging Face is a
Git-LFS model hub, not a registry. The core work here is converting a model's
files into a model-spec OCI artifact on the fly (typed layers + model-card
metadata) — a concept the adapter contract doesn't have and would be distorted
to add. A separate subsystem keeps model semantics explicit while reusing
Harbor's existing pieces (jobservice, scheduler, registry client, encryption,
repository RBAC) rather than adding parallel infrastructure.
Alternatives considered: a HF replication adapter (rejected — protocol mismatch
above); client-side/CLI tooling (rejected — leaves the governance gap that
motivates air-gapped/regulated users). Whether this should eventually converge
with replication is left as an Open Issue.
Compatibility
Additive only: a new model_import_policy table (forward migration), a new
MODEL_IMPORT vendor type, new endpoints, and a new optional repository type
field (defaults to IMAGE). Nothing existing changes. Imported artifacts are
standard model-spec artifacts handled by the existing CNAI processor, so
retention, quota, deletion, and display behave as usual. Requires jobservice
egress to Hugging Face (or a mirror in air-gapped setups), and builds on the
modelpack/model-spec libraries already used by CNAI.
Implementation
Implemented in an open PR against goharbor/harbor (backend under
pkg/modelimport, controller/modelimport, jobservice/job/impl/modelimport;
API/handlers; DB migration; portal UI; unit tests). I (@elliott-davis) will own
it through review and maintain it afterward. If smaller PRs are preferred, it can
split into: (1) import backend + API + migration, (2) scheduling/sync, (3) portal
UI, (4) repository type.
Open Issues
- Scanning/signing. Scanners like Trivy don't inspect model weights, and
provenance/signing for model artifacts is unsettled — what should Harbor
assert beyond the upstream commit SHA and per-file digests?
- Convergence with replication. Should model import eventually become a
replication source, and if so, what would the adapter contract need to grow?
Summary
Let users import a model from Hugging Face into a Harbor project as an OCI
model-spec (CNAI) artifact, with optional scheduled re-sync. You give a HF repo
slug (plus optional revision, subfolder, and token); Harbor resolves the model,
converts its files into a model-spec artifact, and stores it in a target
repository — so Harbor can be one governed registry for both images and models.
Background
Harbor already understands OCI model artifacts via the CNAI/model-spec processor
(model card, files, license, distinct artifact type). What's missing is a
supported on-ramp: getting a model from Hugging Face — the de facto hub for open
models — into Harbor today means an out-of-band "download, convert, push" loop.
That friction hurts three groups who want Harbor in this path: teams
standardizing on OCI model artifacts, air-gapped/regulated orgs that must pull
public models into a governed internal registry, and platform teams who'd rather
run one registry than a separate model store. This proposal makes the import a
native Harbor operation.
Proposal
A project-scoped Model Import capability:
main), optional subfolder, target repo/tag, optional token, and a triggerthat is manual or scheduled (cron).
MODEL_IMPORTjobservice job resolves the model via theHF API, streams each file, and assembles a model-spec OCI artifact (config plus
per-file layers typed as weights/config/code/docs), pushes it, and tags it,
reporting progress via check-ins.
license, etc.) into the config; records the last imported commit SHA so
repeated/scheduled runs are a no-op when upstream is unchanged.
encrypted at rest, used only by the job, and never returned by the API.
/projects/{project_name}/model-import/…forpolicy CRUD, executions/tasks/logs, and a
validatepreview (resolve arepo/revision, preview file count and metadata) before importing. Authorized
against the existing repository RBAC resource/actions.
typefield (IMAGE/MODEL) onthe repository API and portal grid, derived from a repo's artifacts (any
CNAI/model artifact ⇒
MODEL).The source path (resolve → stream → convert → push) sits behind interfaces so
other sources can be added later, but Hugging Face is the only source here.
Non-Goals
them; none are implemented here.
Rationale
Why a dedicated subsystem instead of a Hugging Face replication adapter?
Replication moves existing OCI artifacts registry-to-registry; Hugging Face is a
Git-LFS model hub, not a registry. The core work here is converting a model's
files into a model-spec OCI artifact on the fly (typed layers + model-card
metadata) — a concept the adapter contract doesn't have and would be distorted
to add. A separate subsystem keeps model semantics explicit while reusing
Harbor's existing pieces (jobservice, scheduler, registry client, encryption,
repository RBAC) rather than adding parallel infrastructure.
Alternatives considered: a HF replication adapter (rejected — protocol mismatch
above); client-side/CLI tooling (rejected — leaves the governance gap that
motivates air-gapped/regulated users). Whether this should eventually converge
with replication is left as an Open Issue.
Compatibility
Additive only: a new
model_import_policytable (forward migration), a newMODEL_IMPORTvendor type, new endpoints, and a new optional repositorytypefield (defaults to
IMAGE). Nothing existing changes. Imported artifacts arestandard model-spec artifacts handled by the existing CNAI processor, so
retention, quota, deletion, and display behave as usual. Requires jobservice
egress to Hugging Face (or a mirror in air-gapped setups), and builds on the
modelpack/model-spec libraries already used by CNAI.Implementation
Implemented in an open PR against
goharbor/harbor(backend underpkg/modelimport,controller/modelimport,jobservice/job/impl/modelimport;API/handlers; DB migration; portal UI; unit tests). I (@elliott-davis) will own
it through review and maintain it afterward. If smaller PRs are preferred, it can
split into: (1) import backend + API + migration, (2) scheduling/sync, (3) portal
UI, (4) repository
type.Open Issues
provenance/signing for model artifacts is unsettled — what should Harbor
assert beyond the upstream commit SHA and per-file digests?
replication source, and if so, what would the adapter contract need to grow?