# Understanding the Role of SecretKey in Iroh Endpoint Authentication

> Discover how iroh SecretKey is the core credential for endpoint authentication, deriving the public EndpointId for secure TLS handshakes and peer-to-peer connections.

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

---

**The `SecretKey` serves as the core cryptographic credential that authenticates an iroh endpoint, deriving the public `EndpointId` used to verify identity during TLS handshakes and establish mutually authenticated peer-to-peer connections.**

In the n0-computer/iroh repository, the `SecretKey` is the foundational security primitive that enables decentralized endpoint authentication. Every endpoint derives its unique identity from this key, which remains private to the holder while its corresponding public key acts as the verifiable endpoint identifier. Understanding how this key flows through the builder, TLS configuration, and connection handshake is essential for implementing secure applications with iroh.

## How SecretKey Establishes Endpoint Identity

The `SecretKey` is defined in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) and represents the private half of an asymmetric key pair. When you construct an endpoint using `Endpoint::builder()`, you may provide a specific key via `Builder::secret_key()`, or let the system generate a cryptographically secure random key automatically.

The public component derived from this secret—accessed via `SecretKey::public()`—becomes the endpoint's **`EndpointId`**. This identifier is not merely a label; it is the cryptographic public key that peers use to verify your endpoint's authenticity during connection establishment. As implemented in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 516-525), the builder stores this key and uses it to derive the node's public identity.

## TLS Configuration and Handshake Authentication

Once the endpoint is constructed, the `SecretKey` is embedded within the **TLS configuration** (`tls::TlsConfig`) as shown in [`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs) (lines 44-48). This configuration is critical for securing peer-to-peer communications through the following mechanisms:

- **Server and Client Config Construction**: The `make_server_config` and `make_client_config` functions use the secret key to generate TLS certificates that cryptographically bind the endpoint's identity to the connection.
- **Handshake Signing**: During the TLS handshake, the secret key signs the handshake data, allowing remote peers to verify that the connecting party possesses the private key corresponding to the claimed `EndpointId`.
- **Mutual Authentication**: The remote peer validates the presented certificate against the known public key. If verification succeeds, the connection is authenticated and encrypted.

The socket initialization code in [`iroh/src/socket.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket.rs) (lines 66-70) passes these TLS configurations into the transport layer, ensuring that authentication happens transparently at the connection level.

## Automatic Key Generation vs. Explicit Configuration

You have two options when configuring **iroh endpoint authentication**:

1. **Explicit Key Provision**: Supply your own `SecretKey` using `builder.secret_key(my_secret)`. This is essential when you need persistent identity across restarts or want to use a pre-distributed key.
2. **Automatic Generation**: Omit the `secret_key` call, and the builder automatically generates a fresh random key. This creates a temporary identity suitable for ephemeral connections.

Both approaches result in the same authentication flow—the secret key signs the TLS handshake, and peers verify against the derived public key.

## Practical Implementation Example

The following Rust code demonstrates how to generate a `SecretKey`, bind it to an endpoint, and use the resulting identity for authenticated connections:

```rust
use iroh::{Endpoint, endpoint::presets};
use iroh_base::SecretKey;

// Generate a new cryptographic identity
let my_secret = SecretKey::generate();

// Build endpoint with explicit secret key
let ep = Endpoint::builder(presets::N0)
    .secret_key(my_secret.clone())
    .bind()
    .await?;

// Retrieve the public endpoint ID derived from the secret key
let id = ep.id();  // Equivalent to my_secret.public()
println!("My endpoint ID: {}", id.fmt_short());

// Connect to remote peer—authentication happens automatically via TLS
let remote_id = /* known remote EndpointId */;
let conn = ep.connect(remote_id).await?;

```

In this example, `ep.id()` returns the public key derived from `my_secret`, which remote peers use to verify your endpoint's authenticity during the connection handshake.

## Summary

- The `SecretKey` is the fundamental cryptographic credential for **iroh endpoint authentication**, defined in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs).
- It derives the public **EndpointId** that serves as your endpoint's verifiable identity in the network.
- The key is embedded in **TLS configurations** ([`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs)) via `make_server_config` and `make_client_config`, where it signs the TLS handshake.
- Remote peers validate the handshake signature against your public key, establishing **mutually authenticated** connections without centralized authorities.
- You can provide a persistent key via `Builder::secret_key()` or let the system generate an ephemeral one automatically.

## Frequently Asked Questions

### What happens if I don't provide a SecretKey when building an endpoint?

If you omit the `secret_key()` method call, the `Endpoint::builder` automatically generates a fresh random `SecretKey` using cryptographically secure randomness. This creates an ephemeral identity that changes every time the endpoint restarts, which is suitable for temporary connections but unsuitable for persistent addressing.

### How does the SecretKey relate to the EndpointId?

The `EndpointId` is cryptographically derived from the `SecretKey` via `SecretKey::public()`. While the secret key remains private to your endpoint, the `EndpointId` (public key) is shared with other peers. During connection establishment, peers verify that TLS handshake signatures from your endpoint match this public identifier, proving possession of the corresponding secret key.

### Is the SecretKey transmitted during the connection handshake?

No, the `SecretKey` itself is never transmitted over the network. Only the public key (`EndpointId`) is shared, and the secret key is used locally to sign TLS handshake messages. Remote peers verify these signatures against your public key to confirm your identity, following standard public-key cryptography principles implemented in [`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs).

### Where is the SecretKey stored once the endpoint is created?

The `SecretKey` is stored within the endpoint's internal **TLS configuration** structure (`TlsConfig` in [`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs)) and referenced by the socket layer ([`iroh/src/socket.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket.rs)). It remains in memory for the duration of the endpoint's lifecycle and is used to sign handshakes and authenticate outgoing connections, but it is never persisted to disk by the standard library code.