Registry API (direct HTTP surface)

The package registry's own direct HTTP API — served by the registry surface (default port 4210, crates/surfaces/hoziron-registry). This is a different surface from catalog.md's /catalog/... routes, which are a client-facing daemon proxy in front of one or more configured registries. If you're operating a registry (your own, or catalog.hoziron.com), this page is the one that documents its native routes; if you're a CLI/API consumer installing packages, catalog.md is almost always the right page instead.

Endpoints

MethodPathDescription
GET/healthHealth check
GET/auth/whoamiCurrent caller's identity (local API key or OIDC token) — same path/shape as hoziron-api's /auth/whoami
GET/signing-keyThe registry's public signing key (clients need it to verify provenance)
POST/GET/keys, DELETE/POST /keys/{id}, /keys/{id}/rotateAPI key management (standalone bootstrap — shared hoziron-http key-management routes)
GET/POST/PUT/DELETE/admin/issuers, /admin/issuers/{id}Dynamic OIDC issuer registration (multi-tenant) — see below
GET/searchFull-text package search
GET/taxonomyValid taxonomy category paths
GET/taxonomy/versionTaxonomy schema version
GET/regionsValid ISO 3166-1 alpha-2 region codes
GET/packages/{name}Package metadata
GET/packages/{name}/versionsVersion list
GET/packages/{name}/{version}Specific version's metadata
GET/packages/{name}/{version}/downloadDownload the .hpkg archive
POST/packagesPublish a package
GET/packages/{name}/historyProvenance/lineage history (distinct from /versions — used by hoziron-cli catalog provenance)
POST/packages/{name}/{version}/yankDeprecate a published version
GET/POST/collectionsList / publish collections
GET/PUT/DELETE/collections/{name}Collection detail / update / delete

Dynamic OIDC issuer registration

POST /admin/issuers (plus GET/PUT/DELETE) lets an operator register, update, or remove a trusted OIDC issuer at runtime — no config file edit or restart. This is the mechanism catalog.hoziron.com uses to onboard a customer's own identity provider (Microsoft Entra, Google Workspace, etc.) without a deploy. All five endpoints require registry:admin permission.

POST /admin/issuers
{
  "issuer": "https://login.microsoftonline.com/{tenant}/v2.0",
  "audience": "hoziron-registry",
  "jwks_uri": "",
  "role_claim": "roles",
  "allowed_algorithms": ["RS256"],
  "role_mapping": {"RegistryAdmin": "admin", "RegistryPublisher": "operator"},
  "jwks_cache_ttl_secs": 3600
}

jwks_uri auto-discovers from issuer if left empty. Registration hot-reloads the registry's OIDC validators — no restart needed.

Registry-side auth posture (distinct from client-side auth_token_env)

private-registries.md documents the client-side auth_token_env/context token configuration. The registry itself has independent, deployment-side posture knobs in its own [auth] config section:

FieldEffect
modedisabled (default, local-dev convenience — refused at boot on a network-reachable bind), local (API keys from the registry's own KeyStore), or oidc
download_requires_authWhen true, GET /packages/{name}/{version}/download always requires a real identity, independent of mode — even when mode = "disabled"
read_requires_authWhen true, metadata reads (search, package info, collections) also require a real identity — for registries where the catalog itself is sensitive, not just the archive downloads
allow_insecure_no_authExplicit opt-out of the boot-time posture gate, for intentionally-open dev/test registries bound to a network-reachable address

These are structural, per-route gates (Issue #667) — download_requires_auth/read_requires_auth don't change any other route's requirement, and they apply even when the registry's overall mode would otherwise allow anonymous access.

S3-compatible storage backend

By default, package archives are stored on the local filesystem at storage_path (also always used as the database directory, regardless of archive storage backend). Setting [s3] switches archive storage to an S3-compatible backend — AWS S3, Cloudflare R2, or MinIO:

[s3]
bucket = "hoziron-packages-prod"
endpoint = "https://s3.eu-west-2.amazonaws.com"   # R2: https://<account-id>.r2.cloudflarestorage.com; MinIO: http://localhost:9000
region = "eu-west-2"                                # "auto" for R2
access_key_id = "..."      # or AWS_ACCESS_KEY_ID env var
secret_access_key = "..."  # or AWS_SECRET_ACCESS_KEY env var
prefix = "packages/"       # optional key prefix
path_style = false          # true required for MinIO, optional for AWS

access_key_id/secret_access_key can be set via the standard AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY env vars instead of inline in config.

CORS

[cors] configures cross-origin browser access to the registry's HTTP API directly — independent of the [server.cors] config on the API/dashboard surfaces (see config-toml.md).


Related: