What is the EndpointId in Iroh? Understanding Peer Identity in the Network
The EndpointId is a unique cryptographic identifier that represents an iroh endpoint, implemented as a type alias for the Ed25519 public key and used for authentication, routing, and TLS verification across the peer-to-peer network.
In the n0-computer/iroh peer-to-peer networking stack, every endpoint possesses a unique identity known as the EndpointId. This identifier serves as the fundamental addressing primitive, enabling secure authentication and routing between nodes without centralized coordination.
EndpointId Definition and Cryptographic Foundation
Type Alias for PublicKey
According to the iroh source code in iroh-base/src/key.rs (lines 58-70), the EndpointId is defined as a simple type alias:
pub type EndpointId = PublicKey;
The underlying PublicKey struct holds a compressed Ed25519 public key (specifically the compressed Y coordinate), providing 32 bytes of globally unique identity.
Generation During Endpoint Creation
When constructing an endpoint via Endpoint::builder(), the identity is established during the bind() operation. As implemented in iroh/src/endpoint.rs (lines 24-27), the builder either accepts a user-provided secret key or generates a fresh one using SecretKey::generate(). The corresponding public key—derived via SecretKey::public()—becomes the EndpointId. This process ensures that every endpoint has a cryptographically secure, unforgeable identity from inception.
How EndpointId is Used in the Iroh Network
Authentication and Connection Establishment
The EndpointId is required whenever establishing connections to remote peers. The Endpoint::id() method, defined in iroh/src/endpoint.rs (lines 66-72), returns the endpoint's own identifier, while Endpoint::connect() requires the remote peer's EndpointId wrapped in an EndpointAddr. As structured in iroh-base/src/endpoint_addr.rs (lines 42-46), the EndpointAddr type always contains an EndpointId alongside optional relay or direct IP addresses.
DNS Encoding for TLS Verification
Iroh embeds the EndpointId into TLS certificates for encrypted authentication. The iroh::tls::name module encodes the identifier as a DNS name, allowing endpoints to verify peer identities during the handshake process without requiring a traditional certificate authority.
Working with EndpointId in Code
The following example demonstrates creating an endpoint and accessing its EndpointId:
use iroh::{Endpoint, endpoint::presets};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build a default endpoint (generates a fresh secret key)
let ep = Endpoint::builder(presets::N0).bind().await?;
// Retrieve the Endpoint Id (public key)
let id = ep.id();
println!("My Endpoint Id: {}", id); // hex encoding of the public key
// Use the id to connect to a remote peer (requires the remote's EndpointId)
// let remote_id: iroh_base::EndpointId = …;
// let remote_addr = iroh_base::EndpointAddr::from_parts(remote_id, vec![]);
// let conn = ep.connect(remote_addr, b"my-alpn").await?;
Ok(())
}
In this example, ep.id() returns the EndpointId (public key), which implements Display for hex output. The same identifier can construct an EndpointAddr for dialing peers.
Summary
- Cryptographic Identity: The EndpointId is defined in
iroh-base/src/key.rsas a type alias forPublicKey, representing an Ed25519 public key. - Automatic Generation: When using
Builder::bindiniroh/src/endpoint.rs, the endpoint generates or accepts a secret key and derives the EndpointId from its public component. - Network Addressing: The
EndpointAddrstruct iniroh-base/src/endpoint_addr.rsembeds the EndpointId for routing, whileEndpoint::id()exposes the local identity. - Security Integration: The identifier supports TLS authentication via DNS encoding, enabling encrypted peer-to-peer connections without centralized trust.
Frequently Asked Questions
Is EndpointId the same as a PublicKey?
Yes. According to the source code in iroh-base/src/key.rs, EndpointId is literally defined as pub type EndpointId = PublicKey;. It represents the Ed25519 public key corresponding to the endpoint's secret key.
How is the EndpointId generated if I don't provide a secret key?
When calling Endpoint::builder().bind().await without specifying a secret key, the builder automatically generates a new one using SecretKey::generate(). The public key derived from this secret via SecretKey::public() becomes the EndpointId, as implemented in iroh/src/endpoint.rs (lines 24-27).
Can I reuse an EndpointId across restarts?
Yes, but only if you persist and reuse the same secret key. The EndpointId is deterministically derived from the secret key. To maintain a stable identity across application restarts, generate a secret key once, store it securely, and provide it to the builder using Endpoint::builder().secret_key(key).
How do I share my EndpointId with other peers?
You can obtain your EndpointId by calling endpoint.id() and sharing the resulting string representation. Other peers need this identifier to construct an EndpointAddr and initiate connections via endpoint.connect(). The ID can be encoded as a hex string or transmitted in any format that preserves the 32-byte public key.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →