Identity-first transport
Aster’s transport layer is iroh: a networking library that provides QUIC connections identified by ed25519 public keys, with built-in NAT traversal and relay fallback.
For a worker moving from a customer LAN to another network, three things have separate roles: its key identifies the peer, address hints help find it, and a network path carries the connection. Preserve the secret key to preserve the identity. Refresh address information and test reachable paths when the network changes.
Transport authentication proves possession of the expected endpoint key. Your application’s trust policy decides whether that peer may use the service.
EndpointId: public key as address
Section titled “EndpointId: public key as address”Every iroh endpoint has an ed25519 keypair. The public key is called the EndpointId. It serves as the endpoint’s stable identity regardless of network location – the same endpoint keeps the same EndpointId whether it is on a home Wi-Fi network, a corporate LAN, a mobile cellular connection, or a cloud VM.
When you connect to a remote endpoint, you specify its EndpointId. The transport layer resolves that identity to a network path. Applications can supply direct IP addresses and relay hints when discovery alone is insufficient.
QUIC over UDP
Section titled “QUIC over UDP”iroh uses QUIC as its transport protocol. QUIC provides several properties that matter for distributed systems:
Stream independence. Each QUIC stream has independent flow control. Loss on one stream does not impose TCP-style delivery ordering on other streams. Streams still share connection flow control, congestion control, and network capacity.
Connection migration. QUIC connections are identified by a connection ID, not by the TCP 4-tuple (source IP, source port, destination IP, destination port). When an endpoint moves between networks – Wi-Fi to cellular, one access point to another – the connection can continue if a usable new path is available.
Built-in encryption. QUIC mandates TLS 1.3. In iroh, the TLS handshake authenticates both endpoints using their ed25519 keys. Every connection is end-to-end encrypted and mutually authenticated by construction.
Multiplexed streams. A single QUIC connection supports many concurrent streams. Ordinary Aster calls use one stream per RPC. Session-scoped services carry a session ID across call streams. Concurrent streams share connection resources.
NAT traversal
Section titled “NAT traversal”Iroh attempts to establish a direct path between endpoints, including endpoints behind NATs. Network and firewall policy determine which paths are available.
Hole-punching. When two endpoints want to connect, iroh coordinates a simultaneous connection attempt that allows both NATs to create the necessary mappings. Some NAT and firewall configurations prevent direct connectivity.
Relay fallback. When hole-punching fails – for example, behind symmetric NATs or restrictive corporate firewalls – iroh falls back to relay servers. Relay servers forward encrypted QUIC packets between endpoints. Relays forward end-to-end encrypted traffic; they do not receive the application plaintext. They can observe connection metadata.
Path upgrades. iroh continuously attempts to establish direct connections even when using a relay. If network conditions change and a direct path becomes available, iroh transparently migrates the connection. A path upgrade can preserve the existing connection.
Aster addresses: how to find an endpoint
Section titled “Aster addresses: how to find an endpoint”An EndpointId identifies who you want to reach. An aster address tells the transport how to find them. Aster uses a compact aster1... format that encodes the endpoint identity and available network hints:
aster14TudWqdmQLgjyczpq19BnP8f4FNF68bp8YBvGa51GFEqi5rnPWYAfhbTVA3SvNXfNeoaQJVTCThis single string encodes:
- The endpoint’s ed25519 public key (EndpointId)
- A relay server address (for NAT traversal)
- Direct IP addresses (for LAN connectivity)
The high-level Python server exposes the address for a client to use. This API fragment assumes the service and imports from the Python quickstart; copy the actual printed address into the consumer:
# Producerasync with AsterServer(services=[MyService()]) as srv: print(srv.address) # aster14TudW...
# Consumerasync with AsterClient(address="<actual printed aster1 address>") as client: ... # make calls while the connection is owned by this contextThe aster1 prefix is a human-readable marker. The rest is base58-encoded binary containing the endpoint identity and network hints. The address contains no secret key; its length depends on the included hints.
ALPN protocol negotiation
Section titled “ALPN protocol negotiation”QUIC connections use ALPN (Application-Layer Protocol Negotiation) to agree on which protocol to speak. iroh supports multiple ALPNs on a single endpoint:
aster/1– the Aster RPC protocol- Blob protocol (
aster::alpns::BLOBS) – content-addressed blob transfer - Document protocol (
aster::alpns::DOCS) – document replication used by the registry - Gossip protocol (
aster::alpns::GOSSIP) – pub-sub messaging aster.consumer_admission– consumer enrollment (direct credentials)
Use the SDK protocol constants when registering or dialing built-in data protocols; library names are not their literal ALPN bytes. A single iroh endpoint can serve the configured protocols simultaneously. ALPN selects a protocol for each QUIC connection. RPC, blob transfers, and gossip use protocol-specific connections to the same endpoint.
The listed admission protocols belong to the high-level Python enrollment
workflow. Python does not implement producer mesh admission and rejects
allow_all_producers=False. Rust and other bindings expose their own policy
integration; do not assume they perform the Python handshake.
In the Python workflow, aster.consumer_admission verifies consumer
credentials signed by the operator’s root key before RPC begins. Python does
not register or handle delegated admission (aster.admission); a token issued
by @aster cannot admit a consumer to a Python producer. Use direct
consumer-admission credentials instead. Registry publication and access records
do not install that missing protocol handler.
Unified node
Section titled “Unified node”Aster runs as a unified node: a single iroh endpoint that serves RPC, blobs, documents, and gossip. There is no separate “blob server” or “gossip server.” All capabilities share the same endpoint identity, protocol-specific QUIC connections, and the same NAT traversal infrastructure.
This means a service that needs to transfer large files can use iroh-blobs alongside its RPC methods. A service that needs real-time notifications can use iroh-gossip. A service that needs replicated state can use iroh-docs. All of these use the same EndpointId and protocol-specific connections.
Transport tuning
Section titled “Transport tuning”Most applications should leave the QUIC transport defaults alone. For high-throughput servers, Aster exposes a small set of endpoint-level knobs through EndpointConfig / AsterConfig: concurrent stream limits, stream and connection receive windows, send window, idle timeout, keep-alive interval, initial MTU, datagram buffers, send fairness, and segmentation offload.
These settings are process-local. A server daemon can set them before creating its iroh endpoint, and they take effect for that endpoint only. They do not change host networking policy.
Host-level tuning is separate:
- Linux UDP buffer ceilings, NIC offload policy, firewall rules, and file descriptor limits are outside the daemon unless it is explicitly granted privileges.
- macOS socket buffer ceilings and packet filter policy are host settings, not endpoint settings.
- Windows firewall, QoS, and adapter offload settings are host or administrator policy.
The practical split is: put portable QUIC behavior in AsterConfig, and manage privileged OS/network settings with deployment tooling such as systemd units, launchd profiles, container security settings, Group Policy, or infrastructure automation.
Connection model summary
Section titled “Connection model summary”The lifecycle of a connection:
- The caller knows the remote endpoint’s
EndpointId(and optionally a relay URL or direct addresses). - The caller dials the
EndpointIdwith an ALPN (e.g.,aster/1). - iroh resolves the
EndpointIdto a network path – direct if possible, relayed if not. - A QUIC handshake authenticates both endpoints using their ed25519 keys.
- The connection is established. Both sides can open streams.
- Each RPC call opens a new bidirectional QUIC stream on the existing connection.
- If the network path changes, QUIC can migrate to a reachable new path.
Address resolution may use configured discovery services. Endpoint authentication uses the expected public key; deployment authorization is a separate trust policy.
See configuration for endpoint and discovery settings.