iroh-services
Rust client SDK connecting iroh peer-to-peer endpoints to iroh-services for centralized metrics, naming, and network diagnostics.
Repository Health
Technical Analysis
iroh-services is the client-side Rust crate for services.iroh.computer, the hosted dashboard that gives visibility into a running iroh peer-to-peer network. An application that already holds an iroh Endpoint attaches this crate’s Client to it, authenticates with either a project API secret or an SSH key, and the client begins pushing endpoint metrics on a configurable interval, with no separate agent or sidecar process required.
Beyond metrics, the crate handles endpoint naming and grouping, arbitrary key-value attributes for filtering endpoints in the dashboard, capability-based authorization for granting scoped access to a remote endpoint, and on-demand network diagnostics (relay latency, UDP connectivity, NAT/port-mapping probes) that can be uploaded for remote troubleshooting.
What You Get
- Actor-managed client -
Client::builder(\&endpoint).build()spawns a background task that owns the connection lifecycle, re-dialing and re-authenticating transparently after a disconnect. - Configurable metrics push - registers the endpoint’s existing metrics (plus any custom
MetricsGroups) and exports them to iroh-services on a timer, or on demand viapush_metrics(). - Capability-scoped auth -
rcan-signed tokens derived from an API secret or SSH key authorize each connection under the object-capability model, andgrant_capability()issues scoped tokens to remote peers. - Endpoint naming, grouping and attributes -
set_name,set_group, andset_attributeslabel an endpoint cloud-side for filtering and identification in the dashboard. - Network diagnostics -
net_diagnostics()collects relay latency, UDP connectivity, and UPnP/PCP/NAT-PMP port-mapping probes, with an optional upload to iroh-services for remote troubleshooting. - Graceful shutdown -
shutdown()drains any in-flight request and pushes one final metrics update before the client actor stops.
Common Use Cases
- Fleet monitoring - a company running many iroh-based peers (sync clients, relays, edge nodes) forwards metrics from each into one iroh-services project dashboard.
- Remote connectivity triage - support engineers request a
net_diagnostics()report from a user’s endpoint to debug why two peers can’t establish a direct connection. - Per-customer or per-region segmentation - attaching
groupandattributes(e.g.region=us-west) lets operators slice dashboard metrics by deployment. - Short-lived scoped access - an endpoint uses
grant_capability()to hand a time-limited, capability-restricted token to another peer rather than sharing its own credentials. - Environment-differentiated auth - staging clusters authenticate with an SSH-key-derived capability (broad
Cap::All) while production endpoints use narrower per-project API secrets.
Under The Hood
Architecture
The crate centers on an actor: Client::builder(&endpoint).build() spawns a ClientActor task and returns a cheap, cloneable Client handle whose public async methods (name, set_attributes, ping, push_metrics, grant_capability, net_diagnostics, shutdown) send messages over an mpsc channel and await a oneshot reply. The actor owns the single authenticated RpcClient connection, re-dialing and re-authenticating on the next request whenever the remote closes the connection or an RPC fails; caps.rs supplies the rcan-signed capability token that authenticates every connection under an object-capability model, sourced either from a shared-secret ApiSecret ticket (api_secret.rs) or an OpenSSH ed25519 key (openssh.rs). protocol.rs defines the wire messages via irpc’s rpc_requests macro, generating a ServicesMessage enum consumed over a QUIC connection dialed through the caller’s own iroh Endpoint, so the crate adds no transport of its own. A parallel client_host.rs/ClientHostProtocol handles the reverse direction, letting the cloud service dial back into a client for on-demand diagnostics. Since every public method funnels through the actor’s single connection, a change to that connection-management core would ripple through the entire public API.
Tech Stack
Built on iroh 1.0 for the underlying QUIC peer-to-peer transport, with irpc/irpc-iroh layering typed request/response RPC on top and postcard doing the binary encoding; rcan (backed by ed25519-dalek) issues and verifies the signed capability tokens, and iroh-tickets provides the Ticket trait used to encode/decode the ApiSecret. Metrics collection goes through iroh-metrics’ Registry/Encoder. tokio is used only for its sync primitives (channels, not a full runtime) and tokio-util for CancellationToken, while n0-future supplies runtime-agnostic async helpers that also work under wasm32-unknown-unknown. build.rs uses the built crate to embed the compiled iroh dependency version at build time, and cfg_aliases to define a wasm_browser cfg that swaps native-only dependencies (portmapper for UPnP/PCP/NAT-PMP probing, SSH key file loading) for the getrandom crate’s wasm_js feature. Errors use thiserror; strum derives string conversions for capability enums.
Code Quality
Every module (client.rs, protocol.rs, caps.rs, net_diagnostics.rs) carries an inline #[cfg(test)] suite, plus a separate tests/integration.rs. The client tests build an in-process TestServer that mirrors the real backend’s session rules (Auth-must-be-first, one metrics decoder per connection) to exercise reconnect-and-schema-resend behavior, graceful shutdown with an in-flight request draining, and shutdown that does not wait on a stalled dial, using seeded ChaCha8Rng and temp_env_vars for deterministic, isolated tests. Errors are modeled as explicit #[non_exhaustive] enums (BuildError, Error, RemoteError, ValidateNameError) with thiserror and explicit From conversions rather than stringly-typed failures, and the wire protocol’s versioning contract (postcard’s index-based enum encoding) is documented in detail with a dedicated compatibility test pinning variant indices. CI runs across several dedicated GitHub Actions workflows covering standard tests, WASM builds, a beta-toolchain run, flaky-test detection, docs generation, and zizmor security linting of the workflows themselves, an unusually thorough setup for a crate of this size.
API Design
The builder pattern chains validated setters (name, group, attributes) that fail fast with a typed error before any network round-trip, and convenience constructors like api_secret_from_env cut the common case down to a few lines, as shown in the README’s quickstart. The client reuses a caller-supplied iroh Endpoint rather than owning its own transport, keeping the crate a thin layer over an application’s existing networking. The tradeoff is conceptual: capability tokens, session IDs, and the rcan/Caps model add more surface area to learn than a typical REST-style SDK, though the crate’s doc comments consistently explain why each piece exists.