# What Are the Security Implications of Using Iroh?

> Explore Iroh's security implications. Learn how QUIC and TLS 1.3 ensure confidentiality and authenticity while understanding risks like replay attacks, traffic analysis, and key compromise.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: security
- Published: 2026-06-23

---

**Iroh provides strong confidentiality and authenticity through QUIC and TLS 1.3 with Raw Public Key authentication, but exposes replay attack vectors via 0-RTT, traffic analysis risks through relays, and identity compromise if SecretKey material leaks.**

The iroh library from n0-computer/iroh is a peer-to-peer networking stack built on QUIC and TLS 1.3. Understanding the security implications of using iroh is critical for developers building decentralized applications, as the library's design places significant responsibility on users to protect cryptographic keys and handle transport edge cases properly.

## Cryptographic Foundation and Endpoint Authentication

Iroh authenticates every node using a **SecretKey** that generates a public **EndpointId**. In [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs), the library establishes that each endpoint owns a cryptographic identity derived from this randomly-generated key, providing the foundation for all subsequent security guarantees.

The implementation in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) handles `SecretKey` generation through `SecretKey::generate()`, creating a fresh identity by default. This key material drives the TLS 1.3 handshake, ensuring that all traffic is encrypted end-to-end and that relays only forward opaque ciphertext.

### Raw Public Key Infrastructure

Instead of traditional X.509 certificates, iroh uses **Raw Public Keys** (RFC 7250) as implemented in [`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs). The `TlsConfig` structure constructs a custom TLS configuration that authenticates peers directly via their public keys, eliminating the complexity of certificate chains while maintaining cryptographic assurance.

This design simplifies key management but requires rigorous protection of the private key material. The `DEFAULT_MAX_TLS_TICKETS` constant limits the TLS session cache size to prevent unbounded memory consumption, addressing a potential resource exhaustion vector.

## 0-RTT Performance and Replay Attack Vectors

Iroh enables **0-RTT** (zero round-trip time) by default to reduce connection latency, but this optimization introduces significant security considerations. The `Connecting::into_0rtt` method in [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs) allows clients to resume previous TLS sessions and transmit data before handshake completion, making it vulnerable to replay attacks.

Applications must treat 0-RTT data as **idempotent** only. A malicious actor could intercept and replay 0-RTT packets, potentially causing duplicate actions such as double payments if the application logic does not implement additional safeguards. The library returns a `ZeroRttRejected` error when servers refuse early data, requiring clients to handle fallback to full handshakes.

```rust
use iroh::{Endpoint, endpoint::presets};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let ep = Endpoint::bind(presets::N0).await?;
    let conn = ep.connect(remote_addr, b"my-alpn").await?;
    // Convert to 0-RTT; only safe for idempotent actions
    match conn.into_0rtt()?.handshake_completed().await? {
        iroh::endpoint::ZeroRttStatus::Accepted(conn) => {
            // 0-RTT data was accepted – proceed carefully
        }
        iroh::endpoint::ZeroRttStatus::Rejected(conn) => {
            // Server rejected early data – fall back to normal flow
        }
    }
    Ok(())
}

```

## Relay Server Privacy and Metadata Exposure

Iroh uses **relay servers** to facilitate connectivity when direct peer-to-peer connections are impossible. According to [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) and the relay implementation in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs), relays forward encrypted traffic based on the `EndpointId` without accessing plaintext content. However, relays observe metadata including when specific endpoints are online and traffic patterns between peers.

This exposure creates risks for **traffic analysis attacks**, where an adversary controlling or monitoring relays could infer communication relationships and timing. While payload confidentiality remains intact through end-to-end encryption, the visibility of connection metadata represents a privacy limitation that developers must consider when choosing relay operators.

## Key Management and Address Lookup Integrity

The security of iroh depends entirely on **SecretKey** confidentiality. By default, [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) generates a fresh key via `SecretKey::generate()`, but developers can supply persistent keys through the `secret_key` builder method. Exposing raw key bytes through logs or unencrypted storage permanently compromises the node's identity and enables impersonation.

```rust
use iroh::{Endpoint, endpoint::presets};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Generates a fresh secret key internally
    let ep = Endpoint::bind(presets::N0).await?;
    Ok(())
}

```

For persistent identity across sessions, load pre-existing key material while ensuring file system permissions restrict access:

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

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Load or generate a long-term key (never log the raw bytes!)
    let my_key = SecretKey::from_bytes(&std::fs::read("my_secret.key")?)?;
    let ep = Endpoint::builder(presets::N0)
        .secret_key(my_key)
        .bind()
        .await?;
    Ok(())
}

```

Iroh supports **PKARR** (Public Key Addressable Resource Records) for decentralized address resolution. The implementation in [`iroh/src/address_lookup/pkarr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/pkarr.rs) signs DNS records using the same `SecretKey` that authenticates the endpoint. An attacker who exfiltrates this key can forge DNS records, redirecting peers to malicious addresses under the compromised identity.

```rust
use iroh_address_lookup::pkarr::PkarrPublisher;
use iroh_base::SecretKey;
use rustls::ClientConfig;

// Build a publisher with a secret key and TLS config
let secret = SecretKey::generate();
let tls_cfg = rustls::ClientConfig::builder()
    .with_safe_defaults()
    .with_custom_certificate_verifier(...); // omitted for brevity

let publisher = PkarrPublisher::builder()
    .build(secret, tls_cfg);
// publisher.publish() signs the DNS record with the secret key

```

## Denial-of-Service Mitigation

While iroh implements non-blocking I/O and caps the TLS ticket cache through `DEFAULT_MAX_TLS_TICKETS`, the library does not automatically enforce limits on concurrent connections or streams. As noted in [`iroh/src/runtime.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/runtime.rs), a malicious peer could open numerous connections to exhaust endpoint resources.

Developers must configure explicit quotas using the `Endpoint` builder to prevent resource exhaustion. Without these limits, endpoints remain vulnerable to denial-of-service attacks from untrusted peers in open networks.

## Summary

- **Strong cryptography**: Iroh provides end-to-end encryption via QUIC and TLS 1.3 with Raw Public Key authentication, ensuring confidentiality when keys remain secret.
- **Replay vulnerabilities**: 0-RTT optimization enables performance gains but requires idempotent application logic to prevent replay attacks.
- **Metadata exposure**: Relays encrypt payloads but expose traffic patterns and online status, requiring careful selection of trusted operators.
- **Key compromise risks**: SecretKey exposure in logs, storage, or PKARR implementations enables complete identity theft and address hijacking.
- **Resource limits**: Endpoints require explicit configuration of connection and stream quotas to prevent denial-of-service exhaustion.

## Frequently Asked Questions

### How does iroh handle authentication without certificates?

Iroh uses **Raw Public Keys** (RFC 7250) rather than traditional X.509 certificates. Each endpoint generates a `SecretKey` that produces a public `EndpointId`, which authenticates the TLS 1.3 handshake directly. This approach eliminates certificate chain validation while maintaining cryptographic identity verification as implemented in [`iroh/src/tls.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls.rs).

### What are the risks of using 0-RTT in iroh applications?

0-RTT data is vulnerable to **replay attacks** where an adversary can retransmit captured packets to duplicate operations. According to [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs), applications must restrict 0-RTT to idempotent operations only, or disable the feature entirely for sensitive transactions, as the protocol does not provide built-in replay protection for early data.

### Can relay servers read my encrypted traffic?

No. Relays forward opaque ciphertext based on the `EndpointId` and cannot decrypt payload content. However, as documented in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs), relays can observe metadata including connection timing, duration, and endpoint presence online, creating potential for traffic analysis that could deanonymize communication patterns.

### How should I store the SecretKey for an iroh endpoint?

Store the `SecretKey` in secure, encrypted storage with minimal access permissions, and never log or transmit the raw bytes. The key can be loaded via `SecretKey::from_bytes()` as shown in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), but must remain confidential to prevent identity theft and PKARR DNS record forgery.