# What is the EndpointId in Iroh? Understanding Peer Identity in the Network

> Discover the EndpointId in Iroh, the unique cryptographic identifier for peer identity. Learn how it enables authentication, routing, and TLS verification on the p2p network.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: deep-dive
- Published: 2026-06-18

---

**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`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) (lines 58-70), the EndpointId is defined as a simple type alias:

```rust
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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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:

```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, `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.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) as a type alias for `PublicKey`, representing an Ed25519 public key.
- **Automatic Generation**: When using `Builder::bind` in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the endpoint generates or accepts a secret key and derives the EndpointId from its public component.
- **Network Addressing**: The `EndpointAddr` struct in [`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs) embeds the EndpointId for routing, while `Endpoint::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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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.