Cloudflare starts auditing WhatsApp’s Key Transparency system

End-to-end encrypted (E2EE) messaging services like WhatsApp, Signal, and iMessage rely on a public-private key exchange to keep conversations private. But there’s a less-discussed point of trust in that model: the messaging app’s infrastructure must correctly distribute each user’s public key. If an attacker could insert a different key into the directory, messages meant for one person could be silently routed to another.

Most messaging apps address this with manual fingerprint verification, such as comparing QR codes in person. That’s impractical at scale. WhatsApp has moved toward a more automated approach with its Key Transparency system, and Cloudflare is now acting as an independent auditor, verifying WhatsApp’s audit proofs to confirm the key directory is built correctly and consistently.

Auditing the key directory

This follows Cloudflare’s earlier work on Code Verify, which checks that the code served to WhatsApp Web users hasn’t been tampered with. The Key Transparency audit applies a similar principle to the public key directory. Cloudflare’s role is to verify that the tree-shaped directory of keys is constructed properly and that its state remains consistent over time.

The technical foundation is the Auditable Key Directory (AKD), a binary tree where each parent node is a hash of its children. Leaf nodes hold hashed contact details and public keys. WhatsApp maintains the tree and cuts a new epoch for each batch of updates, such as a new user joining or an existing user rotating their key. Each epoch is identified by its root hash.

Two services, two guarantees

Cloudflare’s Auditor runs as two separate services on its edge, each handling a distinct part of the verification.

Timestamping service. The WhatsApp Log sends each new epoch — formatted as {counter}/{previous}/{current} with hexadecimal hashes — to Cloudflare, which signs it with a timestamp. Each epoch is handled by a Durable Object that guarantees global uniqueness, preventing replay or inconsistency if the Log experiences an outage or runs in multiple locations. Additional checks enforce that epochs are consecutive and digests are unique. The state is cleared after a month via Durable Object alarms. Cloudflare chose Rust for this service, matching the codebase of the facebook/akd library and the Workers Rust bindings.

Tree validation service. Timestamping proves that epochs exist and are sequential, but it doesn’t verify that the tree transitions are mathematically correct. That’s the job of the validation service, which runs verify_consecutive_append_only on each epoch. Since this is compute-intensive and not latency-sensitive, validation is delegated to a container running on Cloudflare. The Auditor retrieves the updates for an epoch, stores them in an R2 bucket, and marks the epoch as verified once the container finishes the computation.

The split architecture means global uniqueness is handled right away at signing time, while the more expensive validation can proceed asynchronously.

Verifying the proofs yourself

The audit proofs are public. Anyone can check them on Cloudflare’s Key Transparency dashboard or via the plexi command-line tool. With the client installed, you can validate an epoch by specifying its namespace (whatsapp.key-transparency.v1) and, for example, the epoch number at which the log began sharing data. One public key for the Plexi Auditor covers multiple Log namespaces.

Auditing beyond messaging

Cloudflare describes this as a first real-world deployment of infrastructure it expects to reuse. The system is designed to be general purpose — the same auditing approach could apply to code delivery or other E2EE systems. The goal, as with certificate transparency on the web, is that key transparency becomes a default layer in encrypted systems rather than something users think about manually.