The nest registry
A nest is a content-addressed bundle (nest bundle). The registry gives that bundle a home to be
published to and pulled from by name or by identity - with private nests behind auth, backed by a plain directory or
any S3-compatible bucket.
Decoupled, and never mandatory. The registry is not part of the nuthatch binary and is never required. A self-built bundle and
nest load <file|dir>work forever with no registry in the loop. nuthatch pulls; it never becomes the registry, and it never requires one. This is a convenience for sharing - think crates.io or an OCI registry - not a dependency.
Publish and pull
1. Bundle a nest into one portable, content-addressed file, my-nest-<hash>.bundle.
nuthatch nest bundle ./my-nest
2. Publish it to a registry under a name and version.
nuthatch nest publish my-nest-<hash>.bundle --registry <path|s3://bucket/prefix> --as horizon@1.2.0
3. Pull and run it anywhere - resolved by name, fetched, and hash-verified on install (a pull is exactly as safe as a hash-pinned file load).
nuthatch nest load horizon@1.2.0 --registry <path|s3://bucket/prefix>
Address a nest by its identity
Every published bundle is also indexed by its NID, the identity its data is stored under
(nuthatch nest nid --dir <nest> prints it, and nest publish prints it too). A NID is all a host needs:
nuthatch nest load 9f2c… --registry <path|s3://bucket/prefix>
A name and a version are labels someone chose and can move; a NID is computed from the nest itself. So the registry’s NID index is checked rather than trusted: the pulled bundle’s own manifest must compute to the NID asked for, or it is refused, naming both. For the same reason a nest name shaped like a NID (64 hex characters) is refused at publish, so a reference is never ambiguous.
A runtime started with --registry uses exactly this. A live mount naming a NID the runtime does not
hold fetches it by NID, verifies it and installs it at data/<nid>/ before mounting, and a refused mount
removes it again. See Host nests for others.
nuthatch dev --dir my-runtime --registry s3://nests/prod
Layout, beside the name index:
<root>/nids/<nid> # the hash of the bundle that computes to this NID
Backends
Filesystem (default). A directory is a registry - zero extra dependencies, the self-hosted-first default:
<root>/blobs/<hash>.bundle # immutable, content-addressed
<root>/index/<name>/<version> # name@version → hash
<root>/index/<name>/latest # the one movable pointer
S3 / object store. Any S3-compatible bucket (MinIO, S3, R2) - the fleet path. The released binary
and image carry it (the object-store feature is on by default); configure via the standard AWS_*
env (including AWS_ENDPOINT for self-hosted MinIO):
nuthatch nest publish my.bundle --registry s3://nests/prod --as horizon@1.2.0
Private nests
A private namespace is access-controlled by the store itself (bucket policy on S3, filesystem permissions locally). nuthatch carries a configured credential and fails loudly and early - a rejected or missing credential gives a clear “this nest is private, or your registry credential was rejected”, never a silent empty result, and never mistaken for “not found”.
Two kinds of credential - don’t conflate them. Registry auth fetches a private bundle. Nest runtime secrets - a private RPC URL, an enricher’s API key - are a different thing: they belong outside the bundle, passed at run time. Bundling does not strip them for you:
nuthatch.tomlgoes into the bundle verbatim, sonest bundlerefuses one that visibly holds a credential (see security). Keep credentials out of the file before you bundle.
See also
- Upgrading a nest - how a new version of a published nest is rolled out
- Run a runtime - mounting nests from a registry across a fleet
Checked against Nuthatch 5.8.2. Verify a release-specific command with the CLI reference before running it in production.