Harbor Registry Extractor avatar

Harbor Registry Extractor

Pricing

from $0.35 / 1,000 records

Go to Apify Store
Harbor Registry Extractor

Harbor Registry Extractor

Point at any self-hosted Harbor container registry and extract its public projects, repositories, image artifacts (with vulnerability-scan severity) and instance fingerprint via the open /api/v2.0 REST API. One actor, any Harbor — no per-host scraper.

Pricing

from $0.35 / 1,000 records

Rating

0.0

(0)

Developer

Datamule

Datamule

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

A GENERIC "point at any Harbor container registry" Apify actor — the supply-chain / SBOM sibling of the netdata / grafana / gatus / uptime-kuma self-hosted-infra runners, over the container-registry population. Harbor (goharbor/harbor, a CNCF graduated project) is THE on-prem DockerHub / Quay alternative — it runs on Kubernetes clusters across enterprise, research and government. Public projects are anonymous-browsable by design and /systeminfo + /health are unauthenticated on every install — so ONE actor spans every reachable instance, no per-host scraper and no host enumeration.

Input

FieldModeMeaning
sources (required)allOne or more Harbor base URLs — https://registry.cern.ch, https://demo.goharbor.io, or any self-hosted install. The /api/v2.0/... path is appended for you.
modeprojects (default), repositories, artifacts, or discovery.
projectrepositories, artifactsThe Harbor project name to drill into (e.g. acc). Required for those two modes.
repositoryartifactsA single repo name relative to the project. Empty = walk every repo in the project.
qprojects, repositoriesHarbor-native fuzzy filter (?q=), e.g. name=~acc.
nameprojectsExact project-name filter (?name=).
page / pageSizeallHarbor-native paging (1-based page; page size 1–100).
maxRecordsallGlobal cap across every source (one row = one billable event).
bearerallOptional bearer token / robot account for a private instance (Authorization: Bearer ***). Never logged.
extraHeadersallOptional extra request headers (JSON).

Modes

  • projects (default) — paginated /api/v2.0/projects → one flat row per public project: projectId, name, ownerName, repoCount, public, autoScan, severity, creationTime, updateTime, plus a lossless _raw. An instance that gates the project list (private-only) but leaves /systeminfo open falls back to a single discovery fingerprint row instead of nothing.
  • repositories/projects/{project}/repositories → one row per repo: name, artifactCount, pullCount, creationTime, updateTime.
  • artifacts/projects/{project}/repositories/{repo}/artifacts → one row per image: digest, tags[], size, pushTime, pullTime, architecture/os, and the vulnerability-scan rollup (scanSeverity, scanTotal, scanFixable). Give a repository to walk one repo, or omit it to walk every repo in the project (bounded by maxRecords).
  • discovery/systeminfo + /health (+ /api/version) → one fingerprint row per instance: _harborVersion, apiVersion, authMode, selfRegistration, oidcProviderName, health, componentCount, unhealthyComponents. A cheap way to fingerprint many instances at once.

Behaviour

  • The parse is the moat. Harbor's project / repo / artifact shapes drift across v2.0 → v2.11 and installs populate different optional fields — harbor_version is documented but is not returned anonymously on many installs (CERN and the vendor demo both omit it); auto_sbom_generation appears on newer installs only. So every field is read by key presence (dict.get) and Harbor's nested metadata string-bools ("public": "true") are coerced to real booleans. A row missing an optional field yields null, never a crash. Every original object is preserved verbatim in _raw.
  • Many instances leave /systeminfo + /health open but gate the project list to logged-in users. In projects mode such a source still yields a discovery fallback row rather than being dropped.
  • A source that is auth-gated on everything, unreachable / DNS-failed, timing out, or returns a non-Harbor body is a clean skip-with-warning, and the batch continues. A run where every source was skipped fails fast (exit 91) so nothing broken ships. A single valid instance with 0 public projects yields 0 records and a clean exit 0.
  • Private instances are supported via an optional bearer token / robot account — never required for anonymous instances, never logged.

Output

One flat, fully-nullable row per record (project / repository / artifact / instance), plus a lossless _raw with the original object. Example (projects mode, registry.cern.ch):

{
"_type": "project",
"_source": "https://registry.cern.ch",
"_mode": "projects",
"_software": "harbor",
"projectId": 1009,
"name": "acc",
"ownerName": "kbenothm",
"repoCount": 987,
"public": true,
"autoScan": true,
"severity": "critical",
"creationTime": "2021-05-18T14:04:05.724Z",
"updateTime": "2021-05-18T14:04:05.724Z"
}

Pricing

Pay-per-event: one record charge per emitted row.

Example input

{
"sources": ["https://registry.cern.ch"],
"mode": "projects",
"maxRecords": 100
}