# What is an EndpointId in Iroh? A Developer's Guide to Peer Identity

> Understand what an EndpointId is in Iroh. Learn how this unique identifier represents an iroh endpoint's Ed25519 public key for secure peer connections.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: getting-started
- Published: 2026-07-07

---

**The EndpointId is the unique cryptographic identifier of an iroh endpoint, represented as a type-alias for the endpoint's Ed25519 public key.**

Iroh is a peer-to-peer networking library that uses cryptographic identities to authenticate and route connections between nodes. The EndpointId serves as the fundamental identity mechanism in the Iroh ecosystem, acting as both a public identifier and the foundation for secure communication. Understanding how this identifier is generated and used is essential for building applications with the n0-computer/iroh framework.

## What is an EndpointId in Iroh?

The EndpointId is the canonical identifier for an iroh endpoint. Internally, it is nothing more than a type alias for the endpoint's public key, but this simplicity masks its critical role in the network's security architecture.

### Defining the EndpointId

In the Iroh codebase, the EndpointId is defined as a direct alias for the PublicKey type. According to the source code in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), the type definition is straightforward:

```rust
pub type EndpointId = PublicKey;

```

This definition appears at lines 58-70 in [`key.rs`](https://github.com/n0-computer/iroh/blob/main/key.rs), where `PublicKey` represents a compressed Ed25519 public key (specifically the compressed Y coordinate). By using a type alias, Iroh creates a semantic distinction between generic public keys and those specifically used to identify endpoints, while maintaining the same underlying cryptographic properties.

### How EndpointId is Generated

When you create an endpoint using the builder pattern, the EndpointId is derived from the secret key. In [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) at lines 24-27, the `Builder::bind` method handles key generation:

1. If no secret key is provided by the user, the builder generates a fresh one using `SecretKey::generate()`.
2. The public key is derived from this secret key via `SecretKey::public()`.
3. This public key becomes the EndpointId for the lifetime of the endpoint.

This generation process ensures that every EndpointId is globally unique and cryptographically secure, as it is backed by a randomly generated Ed25519 key pair.

## How EndpointId is Used in Iroh

The EndpointId serves multiple critical functions within the Iroh networking stack, from basic identification to complex TLS verification.

### Endpoint Identification

Each `Endpoint` instance exposes its identity through the `id()` method. As implemented in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) at lines 66-72, calling `ep.id()` returns the EndpointId:

```rust
// Returns the EndpointId (which is the PublicKey)
pub fn id(&self) -> EndpointId {
    self.endpoint_id
}

```

This method allows applications to display their own network identity or share it with other peers that need to establish connections.

### Connection Establishment

To connect to a remote peer, you must know its EndpointId. The identifier is embedded within `EndpointAddr`, which combines the EndpointId with network addressing information. As defined in [`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs) at lines 42-46, the `EndpointAddr` struct always contains an EndpointId:

```rust
pub struct EndpointAddr {
    pub id: EndpointId,
    pub addrs: Vec<SocketAddr>,
    pub relay_url: Option<RelayUrl>,
}

```

When calling `Endpoint::connect`, you provide an `EndpointAddr` that includes the target peer's EndpointId. This identifier is used to authenticate the remote peer during the cryptographic handshake, ensuring you are connecting to the intended node and not an intermediary or attacker.

### TLS Verification

Beyond routing, the EndpointId plays a crucial role in transport layer security. The Iroh team implements TLS certificate verification using the EndpointId as the subject name. In [`iroh/src/tls/name.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls/name.rs), the EndpointId is encoded as a DNS name using `iroh::tls::name::encode`, allowing the TLS layer to verify that the certificate presented by a remote peer matches their claimed EndpointId.

This approach eliminates the need for centralized certificate authorities, instead using the self-authenticating properties of Ed25519 public keys.

## Code Example: Working with EndpointId

Below is a practical example demonstrating how to create an endpoint, retrieve its EndpointId, and prepare to connect to a remote peer:

```rust
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, `Endpoint::builder(presets::N0).bind().await?` creates an endpoint with a newly generated secret key, automatically deriving the EndpointId. The `ep.id()` call returns the `EndpointId` (which is a `PublicKey`), which implements `Display` for convenient hex output. To dial another peer, you would construct an `EndpointAddr` using their EndpointId, ensuring cryptographically authenticated connections.

## Summary

- **EndpointId is a type alias**: Defined as `pub type EndpointId = PublicKey;` in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), representing the Ed25519 public key.
- **Cryptographic generation**: Created when `Builder::bind` executes, either from a user-supplied secret key or a freshly generated one via `SecretKey::generate()`.
- **Self-authenticating identity**: Used in `EndpointAddr` for routing and embedded in TLS certificates for verification without centralized authorities.
- **Retrieval**: Accessed via the `Endpoint::id()` method, which returns the public key identifier assigned during endpoint construction.

## Frequently Asked Questions

### Is the EndpointId in Iroh the same as a public key?

Yes, the EndpointId is technically a type alias for `PublicKey`. According to the source code in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), the definition `pub type EndpointId = PublicKey;` means they are identical types, but the alias provides semantic clarity that this specific public key represents an endpoint's identity.

### How do I get the EndpointId of my local endpoint?

Call the `id()` method on your `Endpoint` instance. As implemented in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) at lines 66-72, `ep.id()` returns the `EndpointId` that was generated during the binding process. This returns the public key corresponding to the secret key held by your endpoint.

### Can I reuse an EndpointId across different sessions?

Yes, if you reuse the same secret key. The EndpointId is derived from the secret key's public component, so if you provide an existing secret key to `Endpoint::builder` instead of generating a new one, you will obtain the same EndpointId. However, if you let the builder generate a random key (the default behavior), you will get a unique EndpointId every time.

### Why does Iroh use EndpointId instead of IP addresses for peer identification?

IP addresses can change, are subject to NAT, and provide no authentication. The EndpointId provides a stable, globally unique, and self-authenticating identifier that remains constant regardless of network topology changes. This enables secure peer-to-peer connections where the cryptographic key proves identity, rather than relying on network location or centralized certificate authorities.