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
| Method | Path | Description |
|---|---|---|
| GET | /health | Health check |
| GET | /auth/whoami | Current caller's identity (local API key or OIDC token) — same path/shape as hoziron-api's /auth/whoami |
| GET | /signing-key | The registry's public signing key (clients need it to verify provenance) |
| POST/GET | /keys, DELETE/POST /keys/{id}, /keys/{id}/rotate | API 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 | /search | Full-text package search |
| GET | /taxonomy | Valid taxonomy category paths |
| GET | /taxonomy/version | Taxonomy schema version |
| GET | /regions | Valid ISO 3166-1 alpha-2 region codes |
| GET | /packages/{name} | Package metadata |
| GET | /packages/{name}/versions | Version list |
| GET | /packages/{name}/{version} | Specific version's metadata |
| GET | /packages/{name}/{version}/download | Download the .hpkg archive |
| POST | /packages | Publish a package |
| GET | /packages/{name}/history | Provenance/lineage history (distinct from /versions — used by hoziron-cli catalog provenance) |
| POST | /packages/{name}/{version}/yank | Deprecate a published version |
| GET/POST | /collections | List / 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:
| Field | Effect |
|---|---|
mode | disabled (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_auth | When true, GET /packages/{name}/{version}/download always requires a real identity, independent of mode — even when mode = "disabled" |
read_requires_auth | When 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_auth | Explicit 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:
- catalog.md — the client-facing daemon proxy (
/catalog/...) most consumers should use instead - ../../guides/catalog/private-registries.md — client-side registry configuration
- ../../guides/catalog/publishing-packages.md — the publish pipeline this API backs
- ../cli/package.md, ../cli/catalog.md — CLI commands that call this API