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

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 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, the struct stores raw bytes internally:

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, the generate() constructor pulls 32 cryptographically-secure random bytes from the system's RNG via the rand_core crate:

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:

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 accepts the key struct:

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

Complete example demonstrating endpoint creation:

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():

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 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.
  • 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 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, 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 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →