# Iroh Node Security Features: Cryptographic Authentication and TLS 1.3 Encryption

> Discover iroh node security features including Ed25519 cryptographic authentication and TLS 1.3 encryption for secure, efficient data transmission.

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

---

**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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs) constructs client and server configurations through `make_client_config` and `make_server_config`, while [`iroh/src/tls/verifier.rs`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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

```rust
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

```rust
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

```rust
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`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs), where the server validates the `CLIENT_AUTH_HEADER` before accepting the connection.

### Verifying Peer Identity

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