Private Registries
What you'll accomplish: Add private registries, configure auth tokens, and use scoped packages to prevent name collisions.
Multi-registry configuration
[catalog]
verify_signatures = true
default_publish_registry = "internal"
[[catalog.registries]]
name = "internal"
url = "https://packages.internal.company.com"
priority = 1
auth_token_env = "INTERNAL_REGISTRY_TOKEN"
enabled = true
require_signatures = true # default: true (fail closed) — set false only for a
# registry explicitly known not to sign packages
[[catalog.registries]]
name = "hoziron"
url = "https://catalog.hoziron.com"
priority = 100
enabled = true
The built-in hoziron registry entry (https://catalog.hoziron.com, priority 100) is the config default — it's always present unless you explicitly remove it.
Resolution order
Non-scoped packages are queried in priority order (lowest number first). First registry with the package wins.
Scoped packages
@scope/name syntax pins a package to a specific registry:
# Only queries the "internal" registry
hoziron-cli catalog install @internal/proprietary-claims-tool
Configure scope mappings
[catalog.scopes]
internal = "https://packages.internal.company.com"
hoziron = "https://catalog.hoziron.com"
Scope rules:
- Scope names: lowercase alphanumeric + hyphens
- Must be mapped in
[catalog.scopes]— error if unknown scope - Bypasses priority-order resolution entirely
- Prevents name collisions between registries
Auth tokens
Store registry auth tokens as environment variables:
export INTERNAL_REGISTRY_TOKEN="your-token-here"
Reference in config:
auth_token_env = "INTERNAL_REGISTRY_TOKEN"
Testing registries
# Test all configured registries
hoziron-cli catalog registry test
# Test a specific registry
hoziron-cli catalog registry test internal
# List configured registries
hoziron-cli catalog registry list
Registry management lives under hoziron-cli catalog registry <subcommand> — add, list, update, remove, test, bootstrap. add/update/remove/bootstrap require catalog:manage (Admin/Operator); list/test require only catalog:read.
Bootstrapping a fresh private registry
A brand-new registry has no API keys, so its own POST /keys endpoint allows exactly one unauthenticated request — the first key. hoziron-cli catalog registry bootstrap wraps this for a registry already added to your config:
hoziron-cli catalog registry add internal --name internal --url https://packages.internal.company.com --priority 1
hoziron-cli catalog registry bootstrap internal --key-name admin --role admin
This calls the registry's POST /keys directly (bypassing the main daemon) and prints the key once — save it and reference it via auth_token_env. Every subsequent key on that registry requires an authenticated admin key.
Registry-side auth posture (operating a registry, not just consuming one)
Everything above is the client side — how a consumer authenticates against a registry someone else runs. If you're the one operating the registry, it has its own independent [auth] config controlling what it requires:
[auth]
mode = "local" # disabled | local | oidc
download_requires_auth = true # requires auth on downloads even if mode = "disabled"
read_requires_auth = false # requires auth on search/package-info reads too
allow_insecure_no_auth = false # explicit opt-out for intentionally-open dev registries
mode = "disabled" is refused at boot if the registry is bound to a network-reachable address, unless allow_insecure_no_auth is set — this is a deliberate posture gate, not an oversight. download_requires_auth/read_requires_auth are structural per-route gates (Issue #667): they apply independent of mode, so you can require auth on downloads specifically even on an otherwise-open registry. See reference/api/registry.md for the full field reference, and reference/api/registry.md#s3-compatible-storage-backend if you're storing package archives in S3/R2/MinIO instead of the local filesystem.
Publishing to a private registry
# Explicit target
hoziron-cli package publish ./my-package/ --registry internal
# Or use default_publish_registry
hoziron-cli package publish ./my-package/
Next steps
Related: