# Security Implications of 0-RTT Connections in iroh: Risks and Mitigations

> Explore the security implications of 0-RTT connections in iroh. Understand weakened security, replay attacks, and mitigation strategies to enhance your iroh deployment.

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

---

**0-RTT connections in iroh allow clients to transmit application data before the cryptographic handshake completes, enabling minimal latency at the explicit cost of weakened security guarantees including lack of forward secrecy and vulnerability to replay attacks.**

iroh’s networking stack is built on QUIC, which supports **0-RTT (Zero-Round-Trip-Time)** data transmission for returning clients. While this feature dramatically reduces connection latency, the **security implications of 0-RTT connections in iroh** require careful consideration, as early data bypasses the full authentication and key agreement phases that protect standard 1-RTT connections.

## How 0-RTT Works in iroh

In a standard QUIC handshake, the client and server must complete a full cryptographic exchange before application data flows. With 0-RTT, the client utilizes cached session tickets from a previous connection to encrypt and send data immediately using `Connecting::into_0rtt()`.

According to the implementation in [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs), this conversion is documented as accepting data "**at the cost of weakened security**" (line 492). The server receives this early data through `Accepting::into_0rtt`, potentially processing requests before cryptographic verification completes.

## Critical Security Risks

### Lack of Full Authentication

When operating in 0-RTT mode, the server cannot verify the client’s identity until the handshake finishes. The connection proceeds without the server confirming that the client possesses valid credentials, leaving early data potentially unauthenticated. Applications must treat 0-RTT payloads as untrusted until the handshake validation completes, or implement additional verification via `ProtocolHandler::on_accepting` hooks.

### No Forward Secrecy

Data transmitted during the 0-RTT phase does **not enjoy forward secrecy**. If an attacker compromises the server’s long-term keys at any point in the future, they can retroactively decrypt captured 0-RTT packets. This represents a fundamental cryptographic weakness compared to standard QUIC connections, where ephemeral key agreement ensures past communications remain secure even if long-term keys leak.

### Replay Attack Vulnerability

The early data sent via 0-RTT can be **captured and replayed** by network attackers. Because the server accepts and processes data before handshake completion, it may execute duplicate requests from malicious actors retransmitting legitimate client packets. The iroh codebase explicitly warns that applications must implement idempotency or include anti-replay mechanisms (such as nonces or timestamps) to mitigate this risk.

## Mitigation and Configuration Strategies

### Explicit Opt-Out via CLI

iroh provides an escape hatch for security-sensitive deployments. The official example at [`iroh/examples/0rtt.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/0rtt.rs) demonstrates a `--disable-0rtt` flag that forces full handshakes on every connection, eliminating the weakened guarantees entirely when latency is less critical than security.

### Custom Protocol Handlers

Developers can implement granular 0-RTT policies using the `ProtocolHandler` trait. As documented in [`iroh/src/protocol.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/protocol.rs) (lines 39-44), the `on_accepting` hook allows custom logic to decide whether to accept early data, reject the connection, or require additional verification before processing 0-RTT payloads.

### Idempotent Operation Design

Because replay attacks remain possible, iroh recommends using 0-RTT only for **non-critical, idempotent, or replay-tolerant traffic**. After the handshake completes, the server can still validate the client and choose to reject the connection, causing any early data to be discarded.

## Implementing 0-RTT in iroh

The following patterns demonstrate the client-side activation and server-side handling of 0-RTT connections:

```rust
// Client-side: Initiating a 0-RTT connection
use iroh::endpoint::{Endpoint, Connecting};

let client = Endpoint::builder().bind(([0, 0, 0, 0], 0))?.finish()?;
let connecting = client.connect(server_addr);

// Convert to 0-RTT to send data immediately (weakened security)
let zrtt_conn = connecting.into_0rtt()?;

// Send early payload before handshake completion
let (mut send, recv) = zrtt_conn.open_stream().await?;
send.write_all(b"early payload").await?;
assert!(recv.is_0rtt()); // Verify stream operates in 0-RTT mode

```

```rust
// Server-side: Accepting with 0-RTT awareness
use iroh::endpoint::{Endpoint, Accepting};

let server = Endpoint::builder()
    .bind(([0, 0, 0, 0], 12345))?
    .finish()?;

while let Ok(accepting) = server.accept().await {
    // Option 1: Accept 0-RTT (allows early data, security trade-offs)
    let conn = accepting.into_0rtt();
    
    // Option 2: Force full handshake for maximum security
    // let conn = accepting.await?;
}

```

## Summary

- **Weakened cryptographic guarantees**: 0-RTT data lacks forward secrecy and is vulnerable to future key compromise according to [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs).
- **Authentication gaps**: Server identity verification completes only after early data transmission, requiring application-level validation.
- **Replay exposure**: attackers can retransmit captured 0-RTT packets, necessitating idempotent API design or explicit anti-replay logic.
- **Optional and controllable**: The `--disable-0rtt` flag and `ProtocolHandler::on_accepting` hooks provide mechanisms to mitigate or eliminate these risks.

## Frequently Asked Questions

### What are the main security risks of enabling 0-RTT in iroh?

The primary risks include **lack of forward secrecy** for early data, meaning a future key compromise exposes 0-RTT payloads; **deferred authentication**, where the server processes data before verifying client identity; and **vulnerability to replay attacks**, where attackers can retransmit captured packets to execute duplicate operations.

### How can I disable 0-RTT connections in iroh?

You can disable 0-RTT by avoiding the `into_0rtt()` conversion and instead awaiting the full handshake with `accepting.await` or `connecting.await`. The reference implementation in [`iroh/examples/0rtt.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/0rtt.rs) provides a `--disable-0rtt` CLI flag demonstrating this pattern.

### Is data sent via 0-RTT encrypted?

Yes, 0-RTT data is encrypted using keys derived from cached session tickets, but it uses **static rather than ephemeral key material**. This means it lacks forward secrecy—if the server’s long-term keys are compromised later, an attacker can decrypt historical 0-RTT traffic.

### How does iroh handle potential replay attacks with 0-RTT?

iroh does not provide automatic replay protection for 0-RTT data at the protocol level. Applications must handle this risk by designing **idempotent operations** that safely tolerate duplicate requests, or by implementing custom validation logic in the `ProtocolHandler::on_accepting` hook to filter suspicious early data.