# How to Generate an Iroh SecretKey: Complete Guide with Code Examples

> Generate an Iroh SecretKey using SecretKey::generate() from the iroh-base crate. Securely create your node identity with this complete guide.

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

---

**Call `SecretKey::generate()` from the `iroh-base` crate to create a cryptographically secure 32-byte X25519 private key that serves as your node's unique identity.**

The `SecretKey` is the fundamental cryptographic primitive in the [n0-computer/iroh](https://github.com/n0-computer/iroh) repository that gives every Iroh endpoint its unique identity. This 32-byte X25519 private key, defined in the `iroh-base` crate, enables authentication and encryption across the network. Understanding how to generate an Iroh SecretKey is essential for building applications with persistent node identities.

## What is an Iroh SecretKey?

The `SecretKey` struct represents a 32-byte X25519 private key that forms the core identity of an Iroh node. 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 struct stores raw bytes internally:

```rust
pub struct SecretKey {
    key: [u8; 32]
}

```

The corresponding **PublicKey**, derived lazily from these bytes, serves as the endpoint's identifier for TLS handshakes and PKARR DNS-based discovery. The private key never transmits over the network; it remains local to secure connections and decrypt traffic.

## Generating a SecretKey

### The generate() Method Implementation

In [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), the `generate()` constructor pulls 32 cryptographically-secure random bytes from the system's RNG via the `rand_core` crate:

```rust
impl SecretKey {
    /// Creates a new random secret key.
    pub fn generate() -> Self {
        let mut rng = rand_core::OsRng;
        let mut bytes = [0u8; 32];
        rng.fill_bytes(&mut bytes);
        Self { key: bytes }
    }
}

```

This method requires no external input and produces a unique key suitable for production use.

### Basic Generation Example

Generate a fresh key and display its public identifier:

```rust
use iroh_base::SecretKey;

// Generate a brand-new secret key
let my_key = SecretKey::generate();
println!("Public id: {}", my_key.public());

```

## Using SecretKey with an Endpoint

Pass the generated key to the `Endpoint` builder to assign a persistent identity to your node. The `secret_key` method in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) accepts the key struct:

```rust
pub fn secret_key(mut self, secret_key: SecretKey) -> Self {
    self.secret_key = Some(secret_key);
    self
}

```

Complete example demonstrating endpoint creation:

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

#[tokio::main]
async fn main() -> Result<()> {
    // Generate a new identity
    let secret = SecretKey::generate();

    // Build the endpoint using the key
    let ep = Endpoint::builder()
        .secret_key(secret)          // Inject our custom key
        .bind().await?;             // Bind to local port

    println!("Endpoint ID: {}", ep.id());
    Ok(())
}

```

## Persisting and Reloading Secret Keys

To maintain identity across restarts, serialize the key using `to_bytes()` and later reconstruct it with `from_bytes()`:

```rust
use iroh_base::SecretKey;
use std::fs;

// Save to disk
let key = SecretKey::generate();
fs::write("my_secret.key", key.to_bytes())?;

// Load later
let bytes = fs::read("my_secret.key")?;
let key = SecretKey::from_bytes(&bytes)?;

```

Storing the same `SecretKey` across restarts allows your node to retain its identity and resume previously advertised resources in the Iroh network.

## Summary

- **Generate** a new key by calling `SecretKey::generate()` from the `iroh-base` crate, which uses `rand_core::OsRng` for cryptographically secure randomness.
- **Implement** the identity in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) as a 32-byte X25519 private key wrapped in the `SecretKey` struct.
- **Inject** the key into your node via `Endpoint::builder().secret_key(...)` as defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).
- **Persist** identities using `to_bytes()` and `from_bytes()` to maintain continuity across application restarts.

## Frequently Asked Questions

### How is the Iroh SecretKey generated cryptographically?

The `SecretKey::generate()` method in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) uses `rand_core::OsRng` to fill a 32-byte array with entropy from the operating system's cryptographically secure random number generator. This produces an X25519 private key suitable for high-security networking without requiring external seed input.

### Can I reuse the same SecretKey across application restarts?

Yes. Serialize the key to bytes using `key.to_bytes()` and store it securely. When your application restarts, reconstruct the key using `SecretKey::from_bytes(&bytes)`. Reusing the same key preserves your node's identity and allows it to resume advertised resources on the Iroh network.

### What is the relationship between SecretKey and PublicKey in Iroh?

The `SecretKey` stores the 32-byte X25519 private key, while the `PublicKey` represents the derived public component. As implemented in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), calling `secret_key.public()` lazily derives the public key. The public key serves as the endpoint's identifier for authentication and PKARR discovery, while the secret key remains local for decryption and connection signing.

### Where does the Endpoint consume the SecretKey?

The `Endpoint` builder in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) provides the `secret_key(mut self, secret_key: SecretKey)` method, which stores the key in the builder's configuration. When the endpoint binds, this key becomes the node's cryptographic identity, powering TLS handshakes and 0-RTT encryption for control traffic.