Iroh Node Security Features: Cryptographic Authentication and TLS 1.3 Encryption

An iroh node provides cryptographic identity verification through Ed25519 key pairs, TLS 1.3 encryption with raw public keys (RFC 7250), optional zero-RTT data transmission, and relay authentication tokens, eliminating traditional PKI dependencies.

The n0-computer/iroh repository implements a peer-to-peer networking stack where iroh node security features center on cryptographic authentication rather than certificate authorities. Each node generates a permanent secret key that serves as its sole identity, with all transport-layer security derived from this Ed25519 key pair. This design eliminates PKI attack vectors while providing standard TLS 1.3 encryption guarantees.

Cryptographic Identity and Endpoint Authentication

Every iroh node begins with a SecretKey generated during endpoint construction. In iroh/src/endpoint.rs, the Builder struct maintains a secret_key: Option<SecretKey> field that either creates a new key or accepts an existing one. The corresponding public key becomes the node's EndpointId, which the TLS layer embeds into the QUIC server name for verification.

During the handshake, the ServerCertificateVerifier extracts this public key from the server name and validates it against the TLS certificate. This mechanism ensures that connecting to a specific EndpointId cryptographically guarantees you are communicating with the holder of the corresponding secret key.

TLS 1.3 with Raw Public Key Certificates

Instead of traditional X.509 certificate chains, iroh implements RFC 7250 raw-public-key extensions using rustls. The TlsConfig struct in iroh/src/tls.rs constructs client and server configurations through make_client_config and make_server_config, while iroh/src/tls/verifier.rs contains the ServerCertificateVerifier and ClientCertificateVerifier implementations.

These verifiers explicitly reject any certificate intermediates via the intermediates.is_empty() check and return true from requires_raw_public_keys(). The code only accepts raw Ed25519 public keys, completely bypassing external CA trust anchors and removing the attack surface associated with certificate chain validation.

Optional Zero-RTT Support

Iroh nodes support 0-RTT (early data) for reduced latency connections, though the implementation acknowledges this weakens security guarantees. In TlsConfig::make_client_config and make_server_config, the code sets crypto.enable_early_data = true when enabled.

The types OutgoingZeroRtt and IncomingZeroRtt document these security trade-offs explicitly. Applications must explicitly opt-in to this behavior through the builder API, allowing developers to balance performance against replay attack risks.

Relay Authentication and Access Control

When traversing NATs via relay servers, iroh supports authentication tokens for additional access control. The RelayConfig::with_auth_token method in the relay configuration stores an opaque token that the HTTP transport sends via the CLIENT_AUTH_HEADER.

In iroh-relay/src/server/http_server.rs, the server extracts and validates this token against its access-control policy before permitting connections. This layer operates independently from the TLS authentication, providing defense-in-depth for relay infrastructure.

Packet-Level Cryptographic Guarantees

Below the TLS layer, all QUIC packets carry cryptographic signatures derived from the endpoint's secret key. The iroh/src/endpoint/quic.rs file constructs HeaderKey, PacketKey, and HandshakeTokenKey instances from the node's secret key material.

Specifically, crypto::HandshakeTokenKey (implemented in iroh/src/tls/misc.rs) ensures that every packet's integrity and authenticity are verified upon receipt. This provides protection against tampering even before the TLS handshake completes.

Strict Cipher Suite Selection

The security configuration mandates TLS 1.3 with AES-128-GCM-SHA256, the cipher suite required for QUIC initial packets. If the underlying crypto provider lacks this suite, TlsConfig returns TlsConfigError::CryptoProviderNoInitialCipherSuite and panics.

This strict selection prevents downgrade attacks and ensures uniform cryptographic strength across all iroh deployments, regardless of the host system's rustls configuration.

Implementation Examples

Creating an Endpoint with Cryptographic Identity

use iroh::endpoint::{Builder, Preset};

let endpoint = Builder::new(Preset::default())
    .keylog(true)                 // enable SSLKEYLOGFILE (debug only)
    .build()
    .await?;                      // TLS config derives automatically from secret key

The builder internally calls TlsConfig::new and registers the ServerCertificateVerifier that validates raw public keys against the endpoint ID.

Enabling Zero-RTT for Performance

use iroh::endpoint::{Builder, Preset};

let endpoint = Builder::new(Preset::default())
    .allow_0rtt(true)            // sets max_early_data_size = u32::MAX
    .build()
    .await?;

This toggles the crypto.enable_early_data flag in the TLS configuration, enabling early data transmission with documented security trade-offs.

Authenticating with Relay Tokens

use iroh::endpoint::{Builder, Preset, RelayConfig};

let relay_cfg = RelayConfig::default()
    .with_auth_token("my-secret-token".to_string());

let endpoint = Builder::new(Preset::default())
    .relay(relay_cfg)            // attaches authentication token
    .build()
    .await?;

The token propagates to iroh-relay/src/server/http_server.rs, where the server validates the CLIENT_AUTH_HEADER before accepting the connection.

Verifying Peer Identity

match conn.handshake().await {
    Ok(handshake) => {
        // Derived from the TLS raw public key via ServerCertificateVerifier
        println!("Connected to {}", handshake.peer_id());
    }
    Err(e) => eprintln!("Handshake failed: {e:?}"),
}

The verify_server_cert method in iroh/src/tls/verifier.rs automatically extracts and validates the Ed25519 public key from the server name, ensuring the peer ID matches the cryptographic identity presented in the TLS certificate.

Summary

  • Cryptographic Identity: Each node uses a permanent Ed25519 SecretKey where the public component serves as the EndpointId for all authentication decisions.
  • Raw Public Key TLS: Implementation of RFC 7250 in iroh/src/tls/verifier.rs eliminates X.509 dependencies and CA trust requirements.
  • Configurable 0-RTT: Optional early data support available via allow_0rtt, with explicit security trade-off documentation.
  • Relay Token Authentication: RelayConfig::with_auth_token enables access control for relay servers through CLIENT_AUTH_HEADER validation.
  • Strict Cryptography: Mandatory TLS 1.3 with AES-128-GCM-SHA256 and packet-level signature verification via HeaderKey and PacketKey.

Frequently Asked Questions

How does an iroh node authenticate peers without certificate authorities?

An iroh node uses the EndpointId, which is the Ed25519 public key derived from the node's permanent SecretKey. During the TLS handshake, the ServerCertificateVerifier extracts this raw public key from the QUIC server name and verifies it against the TLS certificate, bypassing traditional PKI infrastructure entirely. This approach is implemented in iroh/src/tls/verifier.rs with the requires_raw_public_keys() method ensuring no intermediate certificates are accepted.

What TLS version and cipher suites does iroh require?

Iroh requires TLS 1.3 with the AES-128-GCM-SHA256 cipher suite, which is mandatory for QUIC initial packets. The TlsConfig constructor in iroh/src/tls.rs validates that the crypto provider supports this suite and returns TlsConfigError::CryptoProviderNoInitialCipherSuite if unavailable. This strict requirement prevents cryptographic downgrade attacks.

Is zero-RTT data transmission secure in iroh?

Zero-RTT (early data) is available but explicitly flagged as having weakened security in the iroh implementation. When enabled via allow_0rtt(true), the node sets crypto.enable_early_data = true in both client and server configurations. While this reduces latency by allowing data transmission before handshake completion, it introduces potential replay attack vectors that applications must consider against performance requirements.

How does relay authentication work in iroh nodes?

Relay authentication utilizes opaque tokens configured via RelayConfig::with_auth_token. These tokens are transmitted in the CLIENT_AUTH_HEADER HTTP header when connecting to relay servers. The relay server, implemented in iroh-relay/src/server/http_server.rs, extracts and validates this token against its access-control policy before permitting NAT traversal assistance, adding an additional security layer beyond the peer-to-peer cryptographic authentication.

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 →