Discovery and registry
Aster includes a decentralised service registry built on iroh's data primitives. There is no central server, no Consul, no etcd. Registry state replicates across participants using the same peer-to-peer infrastructure that carries RPC traffic.
Three iroh primitives
The registry is built on three independent iroh subsystems, each suited to a different data pattern:
iroh-docs -- replicated key-value store for mutable state. iroh-docs provides a CRDT-based document model where multiple authors can write entries concurrently. Entries are signed by their author's keypair, providing cryptographic proof of authorship. The registry uses iroh-docs for endpoint leases, service aliases, channel pointers, access control lists, and configuration.
iroh-blobs -- content-addressed storage for immutable artifacts. iroh-blobs stores data identified by its BLAKE3 hash. Data is transferred directly between peers, verified on receipt, and cacheable indefinitely (the hash guarantees integrity). The registry uses iroh-blobs for contract bundles -- the immutable collections containing canonical service definitions and type definitions.
iroh-gossip -- pub-sub for real-time notifications. iroh-gossip provides topic-based message broadcast across the mesh. The registry uses gossip for real-time events: CONTRACT_PUBLISHED when a new contract is available, LeaseUpdate when an endpoint comes online or goes offline, and other operational notifications.
Registry namespace structure
The registry organizes data in an iroh-docs namespace with the following key structure:
{namespace}/
_aster/
acl/
writers -- list of authorized AuthorIds
readers -- list of authorized AuthorIds
admins -- list of authorized AuthorIds
policy -- registry policy configuration
config/
gossip_topic -- TopicId for change notifications
lease_duration_s -- default: 45 seconds
lease_refresh_interval_s -- default: 15 seconds
contracts/
{contract_id} -- ArtifactRef (pointer to blob collection)
services/
{service_name}/
versions/
v{version} -- contract_id
channels/
stable -- contract_id
canary -- contract_id
dev -- contract_id
tags/
{label} -- contract_id
meta -- service metadata
contracts/
{contract_id}/
endpoints/
{endpoint_id} -- EndpointLease
endpoints/
{endpoint_id}/
meta -- optional static endpoint metadata
tags -- optional discovery tags
compatibility/
{contract_id}/
{other_contract_id} -- compatibility report
All entries are signed by their author's keypair. The AuthorId on each entry provides cryptographic proof of who wrote it.
ArtifactRef: linking docs to blobs
The registry separates mutable pointers (in iroh-docs) from immutable data (in iroh-blobs). The link between them is an ArtifactRef -- a small JSON document stored as a docs entry that points to an iroh blob collection:
ArtifactRef {
contract_id -- BLAKE3 hash of the ServiceContract
collection_hash -- BLAKE3 root hash of the iroh blob collection
provider_endpoint_id -- optional: endpoint serving the blobs
relay_url -- optional: relay for the provider
ticket -- optional: bearer blob ticket for direct fetch
published_by -- AuthorId of the publisher
published_at_epoch_ms -- publication timestamp
}
This indirection keeps the docs layer lightweight. Docs entries are small pointers; the actual contract artifacts (which may include type definitions, documentation, and compatibility reports) are stored as content-addressed blobs and transferred efficiently via iroh-blobs.
Endpoint leases
An endpoint that serves a particular contract advertises itself by writing an EndpointLease to the registry. Leases are time-bounded: they have a duration (default 45 seconds) and must be refreshed periodically (default every 15 seconds).
If an endpoint stops refreshing its lease -- because it crashed, lost connectivity, or shut down -- the lease expires and consumers stop routing to it. There is no heartbeat protocol; the lease mechanism in iroh-docs is the health signal.
Leases carry the endpoint's NodeAddr (public key, relay URL, direct addresses), so consumers have everything they need to establish a connection without additional discovery steps.
Service resolution
The flow from "I need this service" to "I have a connection" is:
- The consumer knows a
contract_id(from its compiled client stub or configuration). - The consumer looks up
contracts/{contract_id}in the registry docs namespace. - The entry contains an
ArtifactRefwith acollection_hash. - The consumer fetches the blob collection (if not already cached) and verifies
blake3(contract.xlang) == contract_id. - The consumer looks up
services/{name}/contracts/{contract_id}/endpoints/for active leases. - The consumer selects an endpoint and dials it using the
NodeAddrfrom the lease.
All of this happens over the same iroh infrastructure. The registry lookup uses iroh-docs sync, the artifact fetch uses iroh-blobs transfer, and the RPC call uses iroh QUIC. No separate discovery infrastructure is needed.
Channels and versions
Services can organize their contracts into channels and versions:
- Versions (
v1,v2, ...) map to specificcontract_idvalues. A version is immutable once published. - Channels (
stable,canary,dev) are mutable pointers to acontract_id. Promoting a canary to stable is a single docs write that updates thestablechannel pointer. - Tags are arbitrary labels that point to a
contract_id, useful for custom workflows.
This model supports gradual rollout, blue-green deployment, and experimentation without any infrastructure beyond the registry itself.
Gossip notifications
Changes to the registry are broadcast via iroh-gossip so that participants learn about new contracts, endpoint changes, and configuration updates in real time rather than polling.
Key gossip events:
- CONTRACT_PUBLISHED -- a new contract has been published; consumers can fetch it.
- LeaseUpdate -- an endpoint has come online, gone offline, or updated its metadata.
- ChannelUpdate -- a channel pointer has changed (e.g., a new version promoted to stable).
Gossip is a hint mechanism, not a source of truth. If a gossip message is missed, the consumer will still see the change the next time it syncs the docs namespace. Gossip accelerates propagation; docs provides durability.
No central server
The registry has no central server, no leader election, and no single point of failure. Every participant holds a replica of the docs namespace and syncs with peers. Writes are concurrent and conflict-free (iroh-docs uses CRDTs). Blob collections are immutable and content-addressed, so any peer that has the data can serve it.
This means the registry works in the same environments as Aster itself: behind NATs, across organizational boundaries, without centralized infrastructure. The registry is part of the mesh, not a dependency external to it.