
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Wed, 15 Apr 2026 04:55:45 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Bringing more transparency to post-quantum usage, encrypted messaging, and routing security]]></title>
            <link>https://blog.cloudflare.com/radar-origin-pq-key-transparency-aspa/</link>
            <pubDate>Fri, 27 Feb 2026 06:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare Radar has added new tools for monitoring PQ adoption, KT logs for messaging, and ASPA routing records to track the Internet's migration toward more secure encryption and routing standards.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Cloudflare Radar already offers a wide array of <a href="https://radar.cloudflare.com/security/"><u>security insights</u></a> — from application and network layer attacks, to malicious email messages, to digital certificates and Internet routing.</p><p>And today we’re introducing even more. We are launching several new security-related data sets and tools on Radar: </p><ul><li><p>We are extending our post-quantum (PQ) monitoring beyond the client side to now include origin-facing connections. We have also released a new tool to help you check any website's post-quantum encryption compatibility. </p></li><li><p>A new Key Transparency section on Radar provides a public dashboard showing the real-time verification status of Key Transparency Logs for end-to-end encrypted messaging services like WhatsApp, showing when each log was last signed and verified by Cloudflare's Auditor. The page serves as a transparent interface where anyone can monitor the integrity of public key distribution and access the API to independently validate our Auditor’s proofs. </p></li><li><p>Routing Security insights continue to expand with the addition of global, country, and network-level information about the deployment of ASPA, an emerging standard that can help detect and prevent BGP route leaks. </p></li></ul>
    <div>
      <h2>Measuring origin post-quantum support</h2>
      <a href="#measuring-origin-post-quantum-support">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2gs0x3zMZTxios168jT9xW/179d8959b5e0939835cf6facef797457/1.png" />
          </figure><p>Since <a href="https://x.com/CloudflareRadar/status/1788277817362329983"><u>April 2024</u></a>, we have tracked the aggregate growth of client support for post-quantum encryption on Cloudflare Radar, chronicling its global growth from <a href="https://radar.cloudflare.com/adoption-and-usage?dateStart=2024-01-01&amp;dateEnd=2024-01-31#post-quantum-encryption-adoption"><u>under 3% at the start of 2024</u></a>, to <a href="https://radar.cloudflare.com/adoption-and-usage?dateStart=2026-02-01&amp;dateEnd=2026-02-28#post-quantum-encryption-adoption"><u>over 60% in February 2026</u></a>. And in October 2025, <a href="https://blog.cloudflare.com/pq-2025/#what-you-can-do-today-to-stay-safe-against-quantum-attacks"><u>we added the ability</u></a> for users to <a href="https://radar.cloudflare.com/adoption-and-usage#browser-support"><u>check</u></a> whether their browser supports <a href="https://developers.cloudflare.com/ssl/post-quantum-cryptography/pqc-support/#x25519mlkem768"><code><u>X25519MLKEM768</u></code></a> — a hybrid key exchange algorithm combining classical <a href="https://www.rfc-editor.org/rfc/rfc8410"><code><u>X25519</u></code></a> with <a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf"><u>ML-KEM</u></a>, a lattice-based post-quantum scheme standardized by NIST. This provides security against both classical and quantum attacks. </p><p>However, post-quantum encryption support on user-to-Cloudflare connections is only part of the story.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/67cvSmOaISIHjrKKRHKPzg/e0ccf032658904fd6beaa7de7340b561/2.png" />
          </figure><p>For content not in our CDN cache, or for uncacheable content, Cloudflare’s edge servers establish a separate connection with a customer’s origin servers to retrieve it. To accelerate the transition to quantum-resistant security for these origin-facing fetches, we <a href="https://blog.cloudflare.com/post-quantum-to-origins/"><u>previously introduced an API</u></a> allowing customers to opt in to preferring post-quantum connections. Today, we’re making post-quantum compatibility of origin servers visible on Radar.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6KvV2meYLEPbNIQyHP6yji/9477a134c8f5f6a7aaecd6257cd59981/3.png" />
          </figure><p>The new origin post-quantum support graph on Radar illustrates the share of customer origins supporting <code>X25519MLKEM768</code>. This data is derived from <a href="https://blog.cloudflare.com/automatically-secure/"><u>our automated TLS scanner,</u></a> which probes TLS 1.3-compatible origins and aggregates the results daily. It is important to note that our scanner tests for support rather than the origin server's specific preference. While an origin may support a post-quantum key exchange algorithm, its local TLS key exchange preference can ultimately dictate the encryption outcome.</p><p>While the headline graph focuses on post-quantum readiness, the scanner also evaluates support for classical key exchange algorithms. Within the Radar <a href="https://radar.cloudflare.com/explorer?dataSet=post_quantum.origin&amp;groupBy=key_agreement#result"><u>Data Explorer view</u></a>, you can also see the full distribution of these supported TLS key exchange methods.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5PBOoQSCcIAQrYezKp1pJU/d4218aba59deef6c21df53856a93040a/4.png" />
          </figure><p>As shown in the graphs above, approximately 10% of origins could benefit from a post-quantum-preferred key agreement today. This represents a significant jump from less than 1% at the start of 2025 — <a href="https://radar.cloudflare.com/explorer?dataSet=post_quantum.origin&amp;groupBy=key_agreement&amp;dt=2025-01-01_2025-12-31"><u>a 10x increase in just over a year</u></a>. We expect this number to grow steadily as the industry continues its migration. This upward trend likely accelerated in 2025 as many server-side TLS libraries, such as <a href="https://openssl-library.org/post/2025-04-08-openssl-35-final-release/"><u>OpenSSL 3.5.0+</u></a>,<a href="https://www.gnutls.org/"><u> GnuTLS 3.8.9+</u></a>, and <a href="https://go.dev/doc/go1.24#cryptotlspkgcryptotls"><u>Go 1.24+</u></a>, enabled hybrid post-quantum key exchange by default, allowing platforms and services to support post-quantum connections simply by upgrading their cryptographic library dependencies.</p><p>In addition to the Radar and Data Explorer graphs, the <a href="https://developers.cloudflare.com/api/resources/radar/subresources/post_quantum/subresources/origin/"><u>origin readiness data is available through the Radar API</u></a> as well.</p><p>As an additional part of our efforts to help the Internet transition to post-quantum cryptography, we are also launching <a href="https://radar.cloudflare.com/post-quantum#website-support"><u>a tool to test whether a specific hostname supports post-quantum encryption</u></a>. These tests can be run against any publicly accessible website, as long as they allow connections from Cloudflare’s <a href="https://www.cloudflare.com/ips/"><u>egress IP address ranges</u></a>. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5dgwK3i7IeLLSUt5xnk4lf/276e25dda3389f6e0ad83a26acd08fec/5.png" />
          </figure><p><sub><i>A screenshot of the tool in Radar to test whether a hostname supports post-quantum encryption.</i></sub></p><p>The tool presents a simple form where users can enter a hostname (such as <a href="https://radar.cloudflare.com/post-quantum?host=cloudflare.com%3A443"><code><u>cloudflare.com</u></code></a> or <a href="https://radar.cloudflare.com/post-quantum?host=www.wikipedia.org%3A443"><code><u>www.wikipedia.org</u></code></a>) and optionally specify a custom port (the default is <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=443"><u>443, the standard HTTPS port</u></a>). After clicking "Test", the result displays a tag indicating PQ support status alongside the negotiated TLS key exchange algorithm. If the server prefers PQ secure connections, a green "PQ" tag appears with a message confirming the connection is "post-quantum secure." Otherwise, a red tag indicates the connection is "not post-quantum secure", showing the classical algorithm that was negotiated.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3rfEG4dMlwR4FJkaKXTRWF/8cab135242057ce57f3b0e4a92be4cec/6.png" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/PXu3kjzwhVkb29kIFREOn/41785c06297e0667ff9e2b261ae9b819/7.png" />
          </figure><p>Under the hood, this tool uses <a href="https://developers.cloudflare.com/containers/"><u>Cloudflare Containers</u></a> — a new capability that allows running container workloads alongside Workers. Since the Workers runtime is not exposed to details of the underlying TLS handshake, Workers cannot initiate TLS scans. Therefore, we created a Go container that leverages the <a href="https://pkg.go.dev/crypto/tls"><code><u>crypto/tls</u></code></a> package's support for post-quantum compatibility checks. The container runs on-demand and performs the actual handshake to determine the negotiated TLS key exchange algorithm, returning results through the <a href="https://developers.cloudflare.com/api/resources/radar/subresources/post_quantum/subresources/tls/methods/support/"><u>Radar API</u></a>.</p><p>With the addition of these origin-facing insights, complementing the existing client-facing insights, we have moved all the post-quantum content to <a href="https://radar.cloudflare.com/post-quantum"><u>its own section on Radar</u></a>. </p>
    <div>
      <h2>Securing E2EE messaging systems with Key Transparency</h2>
      <a href="#securing-e2ee-messaging-systems-with-key-transparency">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/71b8HJK1iT0udJscvkqqI4/778efb329047fca017ff2cf4153330ad/8.png" />
          </figure><p><a href="https://www.cloudflare.com/learning/privacy/what-is-end-to-end-encryption/"><u>End-to-end encrypted (E2EE)</u></a> messaging apps like WhatsApp and Signal have become essential tools for private communication, relied upon by billions of people worldwide. These apps use <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/"><u>public-key cryptography</u></a> to ensure that only the sender and recipient can read the contents of their messages — not even the messaging service itself. However, there's an often-overlooked vulnerability in this model: users must trust that the messaging app is distributing the correct public keys for each contact.</p><p>If an attacker were able to substitute an incorrect public key in the messaging app's database, they could intercept messages intended for someone else — all without the sender knowing.</p><p>Key Transparency addresses this challenge by creating an auditable, append-only log of public keys — similar in concept to <a href="https://radar.cloudflare.com/certificate-transparency"><u>Certificate Transparency</u></a> for TLS certificates. Messaging apps publish their users' public keys to a transparency log, and independent third parties can verify and vouch that the log has been constructed correctly and consistently over time. In September 2024, Cloudflare <a href="https://blog.cloudflare.com/key-transparency/"><u>announced</u></a> such a Key Transparency auditor for WhatsApp, providing an independent verification layer that helps ensure the integrity of public key distribution for the messaging app's billions of users.</p><p>Today, we're publishing Key Transparency audit data in a new <a href="https://radar.cloudflare.com/key-transparency"><u>Key Transparency section</u></a> on Cloudflare Radar. This section showcases the Key Transparency logs that Cloudflare audits, giving researchers, security professionals, and curious users a window into the health and activity of these critical systems.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LZ1DUzv0SCgBa0XqDURKP/26ccd8b0741073895cbb52aa7f1d5643/image11.png" />
          </figure><p>The new page launches with two monitored logs: WhatsApp and Facebook Messenger Transport. Each monitored log is displayed as a card containing the following information:</p><ul><li><p><b>Status:</b> Indicates whether the log is online, in initialization, or disabled. An "online" status means the log is actively publishing key updates into epochs that Cloudflare audits. (An epoch represents a set of updates applied to the key directory at a specific time.)</p></li><li><p><b>Last signed epoch:</b> The most recent epoch that has been published by the messaging service's log and acknowledged by Cloudflare. By clicking on the eye icon, users can view the full epoch data in JSON format, including the epoch number, timestamp, cryptographic digest, and signature.</p></li><li><p><b>Last verified epoch:</b> The most recent epoch that Cloudflare has verified. Verification involves checking that the transition of the transparency log data structure from the previous epoch to the current one represents a valid tree transformation — ensuring the log has been constructed correctly. The verification timestamp indicates when Cloudflare completed its audit.</p></li><li><p><b>Root:</b> The current root hash of the <a href="https://github.com/facebook/akd"><u>Auditable Key Directory (AKD)</u></a> tree. This hash cryptographically represents the entire state of the key directory at the current epoch. Like the epoch fields, users can click to view the complete JSON response from the auditor.</p></li></ul><p>The data shown on the page is also available via the Key Transparency Auditor API, with endpoints for <a href="https://developers.cloudflare.com/key-transparency/api/auditor-information/"><u>auditor information</u></a> and <a href="https://developers.cloudflare.com/key-transparency/api/namespaces/"><u>namespaces</u></a>.</p><p>If you would like to perform audit proof verification yourself, you can follow the instructions in our <a href="https://blog.cloudflare.com/key-transparency/"><u>Auditing Key Transparency blog post</u></a>. We hope that these use cases are the first of many that we publish in this Key Transparency section in Radar — if your company or organization is interested in auditing for your public key or related infrastructure, you can <a href="https://www.cloudflare.com/lp/privacy-edge/"><u>reach out to us here</u></a>.</p>
    <div>
      <h2>Tracking RPKI ASPA adoption</h2>
      <a href="#tracking-rpki-aspa-adoption">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2LAbrwY9ziVbe1BzfUyl7K/821a40f86c62dd9b44f7bcaee018dd28/10.png" />
          </figure><p>While the <a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/"><u>Border Gateway Protocol (BGP)</u></a> is the backbone of Internet routing, it was designed without built-in mechanisms to verify the validity of the paths it propagates. This inherent trust has long left the global network vulnerable to route leaks and hijacks, where traffic is accidentally or maliciously detoured through unauthorized networks.</p><p>Although <a href="https://en.wikipedia.org/wiki/Resource_Public_Key_Infrastructure"><u>RPKI</u></a> and <a href="https://www.arin.net/resources/manage/rpki/roas/"><u>Route Origin Authorizations (ROAs)</u></a> have successfully hardened the origin of routes, they cannot verify the path traffic takes between networks. This is where <a href="https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/"><u>ASPA (Autonomous System Provider Authorization)</u></a><b> </b>comes in. ASPA extends RPKI protection by allowing an <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>Autonomous System (AS)</u></a> to cryptographically sign a record listing the networks authorized to propagate its routes upstream. By validating these Customer-to-Provider relationships, ASPA allows systems to detect invalid path announcements with confidence and react accordingly.</p><p>While the specific IETF standard remains <a href="https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/"><u>in draft</u></a>, the operational community is moving fast. Support for creating ASPA objects has already landed in the portals of Regional Internet Registries (RIRs) like <a href="https://www.arin.net/announcements/20260120/"><u>ARIN</u></a> and <a href="https://labs.ripe.net/author/tim_bruijnzeels/aspa-in-the-rpki-dashboard-a-new-layer-of-routing-security/"><u>RIPE NCC</u></a>, and validation logic is available in major software routing stacks like <a href="https://www.undeadly.org/cgi?action=article;sid=20231002135058"><u>OpenBGPD</u></a> and <a href="https://bird.network.cz/?get_doc&amp;v=20&amp;f=bird-5.html"><u>BIRD</u></a>.</p><p>To provide better visibility into the adoption of this emerging standard, we have added comprehensive RPKI ASPA support to the <a href="https://radar.cloudflare.com/routing"><u>Routing section</u></a> of Cloudflare Radar. Tracking these records globally allows us to understand how quickly the industry is moving toward better path validation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6SI6A5vd2bAp3QnBAsJFmZ/24e11445eb0309252d759e88dbf2ba62/11.png" />
          </figure><p>Our new ASPA deployment view allows users to examine the growth of ASPA adoption over time, with the ability to visualize trends across the five <a href="https://en.wikipedia.org/wiki/Regional_Internet_registry"><u>Regional Internet Registries</u></a> (RIRs) based on AS registration. You can view the entire history of ASPA entries, dating back to October 1, 2023, or zoom into specific date ranges to correlate spikes in adoption with industry events, such as the introduction of ASPA features on ARIN and RIPE NCC online dashboards.</p><p>Beyond aggregate trends, we have also introduced a granular, searchable explorer for real-time ASPA content. This table view allows you to inspect the current state of ASPA records, searchable by AS number, AS name, or by filtering for only providers or customer ASNs. This allows network operators to verify that their records are published correctly and to view other networks’ configurations.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/K97G5TC7O1MYwkvFbrdTl/85b27f807401f85d2bbe140f1611a034/12.png" />
          </figure><p>We have also integrated ASPA data directly into the country/region routing pages. Users can now track how different locations are progressing in securing their infrastructure, based on the associated ASPA records from the customer ASNs registered locally.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6mhZyfrHexdo1GDAoKZEd7/44b63675595a01939fa4748210d8c482/13.png" />
          </figure><p>On individual AS pages, we have updated the Connectivity section. Now, when viewing the connections of a network, you may see a visual indicator for "ASPA Verified Provider." This annotation confirms that an ASPA record exists authorizing that specific upstream connection, providing an immediate signal of routing hygiene and trust.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3lVJY4fZWv3KaFdKwLHfAV/aeb2bc27bdccb6a9025345dbaed5b762/14.png" />
          </figure><p>For ASes that have deployed ASPA, we now display a complete list of authorized provider ASNs along with their details. Beyond the current state, Radar also provides a detailed timeline of ASPA activity involving the AS. This history distinguishes between changes initiated by the AS itself ("As customer") and records created by others designating it as a provider ("As provider"), allowing users to immediately identify when specific routing authorizations were established or modified.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ZIlAn2l0sDTLCyEMMcBI9/871b8d7abffe17b3aee060502eaa4c1c/15.png" />
          </figure><p>Visibility is an essential first step toward broader adoption of emerging routing security protocols like ASPA. By surfacing this data, we aim to help operators deploy protections and assist researchers in tracking the Internet's progress toward a more secure routing path. For those who need to integrate this data into their own workflows or perform deeper analysis, we are also exposing these metrics programmatically. Users can now access ASPA content snapshots, historical timeseries, and detailed changes data using the newly introduced endpoints in the<a href="https://developers.cloudflare.com/api/resources/radar/subresources/bgp/subresources/rpki/subresources/aspa/"> <u>Cloudflare Radar API</u></a>.</p>
    <div>
      <h2>As security evolves, so does our data</h2>
      <a href="#as-security-evolves-so-does-our-data">
        
      </a>
    </div>
    <p>Internet security continues to evolve, with new approaches, protocols, and standards being developed to ensure that information, applications, and networks remain secure. The security data and insights available on Cloudflare Radar will continue to evolve as well. The new sections highlighted above serve to expand existing routing security, transparency, and post-quantum insights already available on Cloudflare Radar. </p><p>If you share any of these new charts and graphs on social media, be sure to tag us: <a href="https://x.com/CloudflareRadar"><u>@CloudflareRadar</u></a> (X), <a href="https://noc.social/@cloudflareradar"><u>noc.social/@cloudflareradar</u></a> (Mastodon), and <a href="https://bsky.app/profile/radar.cloudflare.com"><u>radar.cloudflare.com</u></a> (Bluesky). If you have questions or comments, or suggestions for data that you’d like to see us add to Radar, you can reach out to us on social media, or contact us via <a href="#"><u>email</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5jAzDXss7PvszWkwGC0q2g/df14de40bf268052fac11239952fc1ed/16.png" />
          </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Radar]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Routing]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">1Iy1Qvw9TsOhRwgjUYqFxO</guid>
            <dc:creator>David Belson</dc:creator>
            <dc:creator>Mingwei Zhang</dc:creator>
            <dc:creator>André Jesus</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Sabina Zejnilovic</dc:creator>
            <dc:creator>Thibault Meunier</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Internet measurement, resilience, and transparency: blog takeover from Cloudflare Research and friends]]></title>
            <link>https://blog.cloudflare.com/internet-measurement-resilience-transparency-week/</link>
            <pubDate>Mon, 27 Oct 2025 12:00:00 GMT</pubDate>
            <description><![CDATA[ Coinciding with the ACM’s Internet Measurement Conference, the Cloudflare Research team is publishing a series of posts this week to share their research on building a more measurable, resilient, and transparent Internet. These posts will cover foundational concepts in Internet measurement, Internet resilience, cryptography, and networking.  ]]></description>
            <content:encoded><![CDATA[ <p>The Cloudflare Research team spends our time investigating how we can apply new technologies to continue to help build a better Internet. We don’t just <a href="https://research.cloudflare.com/publications/"><u>write papers</u></a> – we put ideas into practice, and test our hypotheses in real time.</p><p>Our work is deeply collaborative by nature, working closely with academia, standards bodies like the <a href="https://www.ietf.org/"><u>IETF</u></a>, the open-source community, and our own product and engineering teams. We believe in doing this research in the open so that others can learn from it, give us feedback, and work with us to make the next version of the Internet even better. That’s why this week we’re publishing a series of posts to make more of our research public – research that we think will help push forward a more measurable, resilient, and transparent Internet.</p><p>Internet Measurement will be one of the week’s major themes because our posts here coincide with the Association for Computing Machinery (ACM)’s annual <a href="https://conferences.sigcomm.org/imc/2025/"><u>Internet Measurement Conference</u></a>, a venue for new work that measures and analyzes the behavior, performance, and evolution of the Internet and networked systems. Internet measurement is hard to get right, so we’re taking the opportunity to dive deeper into some of the foundational concepts and products that define how we do measurement at Cloudflare scale.   </p><p>Each day this week we share new stories from our Research team and friends in our engineering groups elsewhere at Cloudflare. We will dive deep into Internet measurement data, establish new frameworks for Internet resilience, discuss cryptographic protocols for an increasingly automated web, and explore new advances in networking technologies.</p><p>We’re excited to showcase this work, so stay tuned this week for the posts to follow. Want a preview of what to expect? Read on for an outline of what we will cover this week.</p>
    <div>
      <h2>An ode to Internet measurement </h2>
      <a href="#an-ode-to-internet-measurement">
        
      </a>
    </div>
    <p>We’ll start the week with a foundational look at what Internet measurement actually consists of, explaining the jargon behind the science and some of the fundamental tradeoffs one has to make when trying to do measurement well. A former Cloudflare intern will share how working with Cloudflare-scale data completely changed his perspective on detecting connection tampering. We’ll also dig into how Cloudflare Radar has evolved in the past few years, and take a deeper look at how our <a href="https://speed.cloudflare.com/"><u>Internet speed test</u></a> works! </p>
    <div>
      <h2>A better Internet is a more resilient Internet </h2>
      <a href="#a-better-internet-is-a-more-resilient-internet">
        
      </a>
    </div>
    <p>Something that we take for granted, but notice when it fails: a network's ability not just to stay online, but to withstand, adapt to, and rapidly recover from breakdowns – otherwise known as Internet Resilience. There are many factors that can cause Internet disruption, from cyberattack to natural disaster to government-directed shutdowns. We’ll go deeper into these disruptions in our quarterly Internet Disruption Summary, which details the length and impact of each outage as observed from Cloudflare’s network. </p><p>It’s easy to say Internet Resilience is the goal, but it can be harder to define what that actually means. In our blog “A Framework for Internet Resilience,” we do exactly that – establish a framework for how governments, infrastructure providers, and researchers can assess how resilient their infrastructure is, from first principles.   </p><p>A resilient Internet is also immune to quantum compromise. Much has happened since we published our highly cited <a href="https://blog.cloudflare.com/pq-2024/"><u>State of the Post-Quantum Internet</u></a>, so we’ll share an updated view of progress of post-quantum deployment over the past year, as well as a deep dive into Merkle Tree Certificates, an experimental design with Chrome to make post-quantum certificates deployable at scale. </p>
    <div>
      <h2>A transparent look into Cloudflare’s network</h2>
      <a href="#a-transparent-look-into-cloudflares-network">
        
      </a>
    </div>
    <p>Cloudflare sees millions of connections and IP addresses per second – and characterizing them at scale isn’t easy. We’ll take a deeper look at what a connection actually <i>means </i>at Cloudflare: what server-side characteristics we observe and measure across our network, and what they tell us about the size and flow of data through the Internet.</p><p>Many products at Cloudflare aren’t possible without pushing the limits of network hardware and software to deliver improved performance, increased efficiency, or novel capabilities. That’s why we’re sharing a deep dive into how we bend the limits of our Linux networking stack to be economical with addressing space while maintaining performance.</p><p>All of this theory has real-world applications we’ll dive into: from detecting shared IP space (CGNAT), to defending against DDoS attacks, to improving the efficiency of our cache.   </p>
    <div>
      <h2>Cryptographic protocols for an agentic web</h2>
      <a href="#cryptographic-protocols-for-an-agentic-web">
        
      </a>
    </div>
    <p>The rise of AI agents and AI crawlers is a turning point for infrastructure providers. For instance, traffic from many users is condensed into a few beefy datacenters, and request patterns appear to be more automated as LLMs orchestrate web browsers. Measuring the impact of this shift has become an interesting and complex problem.</p><p>This week, we’ll dive into how honest agents and website operators can work together to stay safe, private, and resilient. We’ll discuss new work being done in the IETF that builds upon <a href="https://blog.cloudflare.com/web-bot-auth/"><u>Web Bot Auth</u></a> – a protocol that allows automated HTTP clients like bots and agents to identify themselves to the rest of the Internet. In addition, in order to empower honest users, we’ll propose new cryptographic protocols that allow them through while protecting websites from DDoS, fraud, or <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">scraping attacks</a>. We will present real-world deployment considerations, as well as mechanisms to future-proof them in the face of the imminent post-quantum transition.</p>
    <div>
      <h2>Get your reading glasses on </h2>
      <a href="#get-your-reading-glasses-on">
        
      </a>
    </div>
    <p>Expect blog posts this week that push the boundaries of emerging research in their respective fields, establish new frameworks and ideas, and bridge the gap between academic theory and real-world applications. We couldn’t be more excited to share them with you!</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">10mTvbwbgtwvoeI31cIbnV</guid>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[How we built the most efficient inference engine for Cloudflare’s network ]]></title>
            <link>https://blog.cloudflare.com/cloudflares-most-efficient-ai-inference-engine/</link>
            <pubDate>Wed, 27 Aug 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Infire is an LLM inference engine that employs a range of techniques to maximize resource utilization, allowing us to serve AI models more efficiently with better performance for Cloudflare workloads. ]]></description>
            <content:encoded><![CDATA[ <p>Inference powers some of today’s most powerful AI products: chat bot replies, <a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/"><u>AI agents</u></a>, autonomous vehicle decisions, and fraud detection. The problem is, if you’re building one of these products on top of a hyperscaler, you’ll likely need to rent expensive GPUs from large centralized data centers to run your inference tasks. That model doesn’t work for Cloudflare — there’s a mismatch between Cloudflare’s globally-distributed network and a typical centralized AI deployment using large multi-GPU nodes. As a company that operates our own compute on a lean, fast, and widely distributed network within 50ms of 95% of the world’s Internet-connected population, we need to be running inference tasks more efficiently than anywhere else.</p><p>This is further compounded by the fact that AI models are getting larger and more complex. As we started to support these models, like the Llama 4 herd and gpt-oss, we realized that we couldn’t just throw money at the scaling problems by buying more GPUs. We needed to utilize every bit of idle capacity and be agile with where each model is deployed. </p><p>After running most of our models on the widely used open source inference and serving engine <a href="https://github.com/vllm-project/vllm"><u>vLLM</u></a>, we figured out it didn’t allow us to fully utilize the GPUs at the edge. Although it can run on a very wide range of hardware, from personal devices to data centers, it is best optimized for large data centers. When run as a dedicated inference server on powerful hardware serving a specific model, vLLM truly shines. However, it is much less optimized for dynamic workloads, distributed networks, and for the unique security constraints of running inference at the edge alongside other services.</p><p>That’s why we decided to build something that will be able to meet the needs of Cloudflare inference workloads for years to come. Infire is an LLM inference engine, written in Rust, that employs a range of techniques to maximize memory, network I/O, and GPU utilization. It can serve more requests with fewer GPUs and significantly lower CPU overhead, saving time, resources, and energy across our network. </p><p>Our initial benchmarking has shown that Infire completes inference tasks up to 7% faster than vLLM 0.10.0 on unloaded machines equipped with an H100 NVL GPU. On infrastructure under real load, it performs significantly better. </p><p>Currently, Infire is powering the Llama 3.1 8B model for <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a>, and you can test it out today at <a href="https://developers.cloudflare.com/workers-ai/models/llama-3.1-8b-instruct-fast/"><u>@cf/meta/llama-3.1-8b-instruct</u></a>!</p>
    <div>
      <h2>The Architectural Challenge of LLM Inference at Cloudflare </h2>
      <a href="#the-architectural-challenge-of-llm-inference-at-cloudflare">
        
      </a>
    </div>
    <p>Thanks to industry efforts, inference has improved a lot over the past few years. vLLM has led the way here with the recent release of the vLLM V1 engine with features like an optimized KV cache, improved batching, and the implementation of Flash Attention 3. vLLM is great for most inference workloads — we’re currently using it for several of the models in our <a href="https://developers.cloudflare.com/workers-ai/models/"><u>Workers AI catalog</u></a> — but as our AI workloads and catalog has grown, so has our need to optimize inference for the exact hardware and performance requirements we have. </p><p>Cloudflare is writing much of our <a href="https://blog.cloudflare.com/rust-nginx-module/"><u>new infrastructure in Rust</u></a>, and vLLM is written in Python. Although Python has proven to be a great language for prototyping ML workloads, to maximize efficiency we need to control the low-level implementation details. Implementing low-level optimizations through multiple abstraction layers and Python libraries adds unnecessary complexity and leaves a lot of CPU performance on the table, simply due to the inefficiencies of Python as an interpreted language.</p><p>We love to contribute to open-source projects that we use, but in this case our priorities may not fit the goals of the vLLM project, so we chose to write a server for our needs. For example, vLLM does not support co-hosting multiple models on the same GPU without using Multi-Instance GPU (MIG), and we need to be able to dynamically schedule multiple models on the same GPU to minimize downtime. We also have an in-house AI Research team exploring unique features that are difficult, if not impossible, to upstream to vLLM. </p><p>Finally, running code securely is our top priority across our platform and <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Workers AI</u></a> is no exception. We simply can’t trust a 3rd party Python process to run on our edge nodes alongside the rest of our services without strong sandboxing. We are therefore forced to run vLLM via <a href="https://gvisor.dev"><u>gvisor</u></a>. Having an extra virtualization layer adds another performance overhead to vLLM. More importantly, it also increases the startup and tear downtime for vLLM instances — which are already pretty long. Under full load on our edge nodes, vLLM running via gvisor consumes as much as 2.5 CPU cores, and is forced to compete for CPU time with other crucial services, that in turn slows vLLM down and lowers GPU utilization as a result.</p><p>While developing Infire, we’ve been incorporating the latest research in inference efficiency — let’s take a deeper look at what we actually built.</p>
    <div>
      <h2>How Infire works under the hood </h2>
      <a href="#how-infire-works-under-the-hood">
        
      </a>
    </div>
    <p>Infire is composed of three major components: an OpenAI compatible HTTP server, a batcher, and the Infire engine itself.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3BypYSG9QFsPjPFhjlOEsa/6ef5d4ccaabcd96da03116b7a14e8439/image2.png" />
          </figure><p><i><sup>An overview of Infire’s architecture </sup></i></p>
    <div>
      <h2>Platform startup</h2>
      <a href="#platform-startup">
        
      </a>
    </div>
    <p>When a model is first scheduled to run on a specific node in one of our data centers by our auto-scaling service, the first thing that has to happen is for the model weights to be fetched from our <a href="https://www.cloudflare.com/developer-platform/products/r2/"><u>R2 object storage</u></a>. Once the weights are downloaded, they are cached on the edge node for future reuse.</p><p>As the weights become available either from cache or from R2, Infire can begin loading the model onto the GPU. </p><p>Model sizes vary greatly, but most of them are <b>large, </b>so transferring them into GPU memory can be a time-consuming part of Infire’s startup process. For example, most non-quantized models store their weights in the BF16 floating point format. This format has the same dynamic range as the 32-bit floating format, but with reduced accuracy. It is perfectly suited for inference providing the sweet spot of size, performance and accuracy. As the name suggests, the BF16 format requires 16 bits, or 2 bytes per weight. The approximate in-memory size of a given model is therefore double the size of its parameters. For example, LLama3.1 8B has approximately 8B parameters, and its memory footprint is about 16 GB. A larger model, like LLama4 Scout, has 109B parameters, and requires around 218 GB of memory. Infire utilizes a combination of <a href="https://developer.nvidia.com/blog/how-optimize-data-transfers-cuda-cc/#pinned_host_memory"><u>Page Locked</u></a> memory with CUDA asynchronous copy mechanism over multiple streams to speed up model transfer into GPU memory.</p><p>While loading the model weights, Infire begins just-in-time compiling the required kernels based on the model's parameters, and loads them onto the device. Parallelizing the compilation with model loading amortizes the latency of both processes. The startup time of Infire when loading the Llama-3-8B-Instruct model from disk is just under 4 seconds. </p>
    <div>
      <h3>The HTTP server</h3>
      <a href="#the-http-server">
        
      </a>
    </div>
    <p>The Infire server is built on top of <a href="https://docs.rs/hyper/latest/hyper/"><u>hyper</u></a>, a high performance HTTP crate, which makes it possible to handle hundreds of connections in parallel – while consuming a modest amount of CPU time. Because of ChatGPT’s ubiquity, vLLM and many other services offer OpenAI compatible endpoints out of the box. Infire is no different in that regard. The server is responsible for handling communication with the client: accepting connections, handling prompts and returning responses. A prompt will usually consist of some text, or a "transcript" of a chat session along with extra parameters that affect how the response is generated. Some parameters that come with a prompt include the temperature, which affects the randomness of the response, as well as other parameters that affect the randomness and length of a possible response.</p><p>After a request is deemed valid, Infire will pass it to the tokenizer, which transforms the raw text into a series of tokens, or numbers that the model can consume. Different models use different kinds of tokenizers, but the most popular ones use byte-pair encoding. For tokenization, we use HuggingFace's tokenizers crate. The tokenized prompts and params are then sent to the batcher, and scheduled for processing on the GPU, where they will be processed as vectors of numbers, called <a href="https://www.cloudflare.com/learning/ai/what-are-embeddings/"><u>embeddings</u></a>.</p>
    <div>
      <h2>The batcher</h2>
      <a href="#the-batcher">
        
      </a>
    </div>
    <p>The most important part of Infire is in how it does batching: by executing multiple requests in parallel. This makes it possible to better utilize memory bandwidth and caches. </p><p>In order to understand why batching is so important, we need to understand how the inference algorithm works. The weights of a model are essentially a bunch of two-dimensional matrices (also called tensors). The prompt represented as vectors is passed through a series of transformations that are largely dominated by one operation: vector-by-matrix multiplication. The model weights are so large, that the cost of the multiplication is dominated by the time it takes to fetch it from memory. In addition, modern GPUs have hardware units dedicated to matrix-by-matrix multiplications (called Tensor Cores on Nvidia GPUs). In order to amortize the cost of memory access and take advantage of the Tensor Cores, it is necessary to aggregate multiple operations into a larger matrix multiplication.</p><p>Infire utilizes two techniques to increase the size of those matrix operations. The first one is called prefill: this technique is applied to the prompt tokens. Because all the prompt tokens are available in advance and do not require decoding, they can all be processed in parallel. This is one reason why input tokens are often cheaper (and faster) than output tokens.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1pqyNSzgWLcgrV3urpCvA0/e204ac477992d591a7368632c36e97eb/image1.png" />
          </figure><p><sup><i>How Infire enables larger matrix multiplications via batching</i></sup></p><p>The other technique is called batching: this technique aggregates multiple prompts into a single decode operation.</p><p>Infire mixes both techniques. It attempts to process as many prompts as possible in parallel, and fills the remaining slots in a batch with prefill tokens from incoming prompts. This is also known as continuous batching with chunked prefill.</p><p>As tokens get decoded by the Infire engine, the batcher is also responsible for retiring prompts that reach an End of Stream token, and sending tokens back to the decoder to be converted into text. </p><p>Another job the batcher has is handling the KV cache. One demanding operation in the inference process is called <i>attention</i>. Attention requires going over the KV values computed for all the tokens up to the current one. If we had to recompute those previously encountered KV values for every new token we decode, the runtime of the process would explode for longer context sizes. However, using a cache, we can store all the previous values and re-read them for each consecutive token. Potentially the KV cache for a prompt can store KV values for as many tokens as the context window allows. In LLama 3, the maximal context window is 128K tokens. If we pre-allocated the KV cache for each prompt in advance, we would only have enough memory available to execute 4 prompts in parallel on H100 GPUs! The solution for this is paged KV cache. With paged KV caching, the cache is split into smaller chunks called pages. When the batcher detects that a prompt would exceed its KV cache, it simply assigns another page to that prompt. Since most prompts rarely hit the maximum context window, this technique allows for essentially unlimited parallelism under typical load.</p><p>Finally, the batcher drives the Infire forward pass by scheduling the needed kernels to run on the GPU.</p>
    <div>
      <h2>CUDA kernels</h2>
      <a href="#cuda-kernels">
        
      </a>
    </div>
    <p>Developing Infire gives us the luxury of focusing on the exact hardware we use, which is currently Nvidia Hopper GPUs. This allowed us to improve performance of specific compute kernels using low-level PTX instructions for this specific architecture.</p><p>Infire just-in-time compiles its kernel for the specific model it is running, optimizing for the model’s parameters, such as the hidden state size, dictionary size and the GPU it is running on. For some operations, such as large matrix multiplications, Infire will utilize the high performance cuBLASlt library, if it would deem it faster.</p><p>Infire also makes use of very fine-grained CUDA graphs, essentially creating a dedicated CUDA graph for every possible batch size on demand. It then stores it for future launch. Conceptually, a CUDA graph is another form of just-in-time compilation: the CUDA driver replaces a series of kernel launches with a single construct (the graph) that has a significantly lower amortized kernel launch cost, thus kernels executed back to back will execute faster when launched as a single graph as opposed to individual launches.</p>
    <div>
      <h2>How Infire performs in the wild </h2>
      <a href="#how-infire-performs-in-the-wild">
        
      </a>
    </div>
    <p>We ran synthetic benchmarks on one of our edge nodes with an H100 NVL GPU.</p><p>The benchmark we ran was on the widely used ShareGPT v3 dataset. We ran the benchmark on a set of 4,000 prompts with a concurrency of 200. We then compared Infire and vLLM running on bare metal as well as vLLM running under gvisor, which is the way we currently run in production. In a production traffic scenario, an edge node would be competing for resources with other traffic. To simulate this, we benchmarked vLLM running in gvisor with only one CPU available.</p><table><tr><td><p>
</p></td><td><p>requests/s</p></td><td><p>tokens/s</p></td><td><p>CPU load</p></td></tr><tr><td><p>Infire</p></td><td><p>40.91</p></td><td><p>17224.21</p></td><td><p>25%</p></td></tr><tr><td><p>vLLM 0.10.0</p></td><td><p>38.38</p></td><td><p>16164.41</p></td><td><p>140%</p></td></tr><tr><td><p>vLLM under gvisor</p></td><td><p>37.13</p></td><td><p>15637.32</p></td><td><p>250%</p></td></tr><tr><td><p>vLLM under gvisor with CPU constraints</p></td><td><p>22.04</p></td><td><p>9279.25</p></td><td><p>100%</p></td></tr></table><p>As evident from the benchmarks we achieved our initial goal of matching and even slightly surpassing vLLM performance, but more importantly, we’ve done so at a significantly lower CPU usage, in large part because we can run Infire as a trusted bare-metal process. Inference no longer takes away precious resources from our other services and we see GPU utilization upward of 80%, reducing our operational costs.</p><p>This is just the beginning. There are still multiple proven performance optimizations yet to be implemented in Infire – for example, we’re integrating Flash Attention 3, and most of our kernels don’t utilize kernel fusion. Those and other optimizations will allow us to unlock even faster inference in the near future.</p>
    <div>
      <h2>What’s next </h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Running AI inference presents novel challenges and demands to our infrastructure. Infire is how we’re running AI efficiently — close to users around the world. By building upon techniques like continuous batching, a paged KV-cache, and low-level optimizations tailored to our hardware, Infire maximizes GPU utilization while minimizing overhead. Infire completes inference tasks faster and with a fraction of the CPU load of our previous vLLM-based setup, especially under the strict security constraints we require. This allows us to serve more requests with fewer resources, making requests served via Workers AI faster and more efficient.</p><p>However, this is just our first iteration — we’re excited to build in multi-GPU support for larger models, quantization, and true multi-tenancy into the next version of Infire. This is part of our goal to make Cloudflare the best possible platform for developers to build AI applications.</p><p>Want to see if your AI workloads are faster on Cloudflare? <a href="https://developers.cloudflare.com/workers-ai/"><u>Get started</u></a> with Workers AI today. </p> ]]></content:encoded>
            <category><![CDATA[AI Week]]></category>
            <category><![CDATA[LLM]]></category>
            <category><![CDATA[Workers AI]]></category>
            <guid isPermaLink="false">7Li4fkq9b4B8QlgwSmZrqE</guid>
            <dc:creator>Vlad Krasnov</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[How Cloudflare runs more AI models on fewer GPUs: A technical deep-dive ]]></title>
            <link>https://blog.cloudflare.com/how-cloudflare-runs-more-ai-models-on-fewer-gpus/</link>
            <pubDate>Wed, 27 Aug 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare built an internal platform called Omni. This platform uses lightweight isolation and memory over-commitment to run multiple AI models on a single GPU. ]]></description>
            <content:encoded><![CDATA[ <p>As the demand for AI products grows, developers are creating and tuning a wider variety of models. While adding new models to our <a href="https://developers.cloudflare.com/workers-ai/models/"><u>growing catalog</u></a> on Workers AI, we noticed that not all of them are used equally – leaving infrequently used models occupying valuable GPU space. Efficiency is a core value at Cloudflare, and with GPUs being the scarce commodity they are, we realized that we needed to build something to fully maximize our GPU usage.</p><p>Omni is an internal platform we’ve built for running and managing AI models on Cloudflare’s edge nodes. It does so by spawning and managing multiple models on a single machine and GPU using lightweight isolation. Omni makes it easy and efficient to run many small and/or low-volume models, combining multiple capabilities by:  </p><ul><li><p>Spawning multiple models from a single control plane,</p></li><li><p>Implementing lightweight process isolation, allowing models to spin up and down quickly,</p></li><li><p>Isolating the file system between models to easily manage per-model dependencies, and</p></li><li><p>Over-committing GPU memory to run more models on a single GPU.</p></li></ul><p>Cloudflare aims to place GPUs as close as we possibly can to people and applications that are using them. With Omni in place, we’re now able to run more models on every node in our network, improving model availability, minimizing latency, and reducing power consumed by idle GPUs.</p><p>Here’s how. </p>
    <div>
      <h2>Omni’s architecture – at a glance</h2>
      <a href="#omnis-architecture-at-a-glance">
        
      </a>
    </div>
    <p>At a high level, Omni is a platform to run AI models. When an <a href="https://www.cloudflare.com/learning/ai/inference-vs-training/"><u>inference</u></a> request is made on Workers AI, we load the model’s configuration from <a href="https://developers.cloudflare.com/kv/"><u>Workers KV</u></a> and our routing layer forwards it to the closest Omni instance that has available capacity. For inferences using the <a href="https://developers.cloudflare.com/workers-ai/features/batch-api/"><u>Asynchronous Batch API</u></a>, we route to an Omni instance that is idle, which is typically in a location where it’s night.</p><p>Omni runs a few checks on the inference request, runs model specific pre and post processing, then hands the request over to the model.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4zlObplZsGgpxPyUoD5NXe/ddd1cb8af444460d54fa5e0ab6e58c87/1.png" />
          </figure>
    <div>
      <h2>Elastic scaling by spawning multiple models from a single control plane</h2>
      <a href="#elastic-scaling-by-spawning-multiple-models-from-a-single-control-plane">
        
      </a>
    </div>
    <p>If you’re developing an AI application, a typical setup is having a container or a VM dedicated to running a single model with a GPU attached to it. This is simple. But it’s also heavy-handed — because it requires managing the entire stack from provisioning the VM, installing GPU drivers, downloading model weights, and managing the Python environment. At scale, managing infrastructure this way is incredibly time consuming and often requires an entire team. </p><p>If you’re using Workers AI, we handle all of this for you. Omni uses a single control plane for running multiple models, called the scheduler, which automatically provisions models and spawns new instances as your traffic scales. When starting a new model instance, it downloads model weights, Python code, and any other dependencies. Omni’s scheduler provides fine-grained control and visibility over the model’s lifecycle: it receives incoming inference requests and routes them to the corresponding model processes, being sure to distribute the load between multiple GPUs. It then makes sure the model processes are running, rolls out new versions as they are released, and restarts itself when detecting errors or failure states. It also collects metrics for billing and emits logs.</p><p>The inference itself is done by a per-model process, supervised by the scheduler. It receives the inference request and some metadata, then sends back a response. Depending on the model, the response can be various types; for instance, a JSON object or a SSE stream for text generation, or binary for image generation.</p><p>The scheduler and the child processes communicate by passing messages over Inter-Process Communication (IPC). Usually the inference request is buffered in the scheduler for applying features, like prompt templating or tool calling, before the request is passed to the child process. For potentially large binary requests, the scheduler hands over the underlying TCP connection to the child process for consuming the request body directly.</p>
    <div>
      <h2>Implementing lightweight process and Python isolation</h2>
      <a href="#implementing-lightweight-process-and-python-isolation">
        
      </a>
    </div>
    <p>Typically, deploying a model requires its own dedicated container, but we want to colocate more models on a single container to conserve memory and GPU capacity. In order to do so, we needed finer-grained controls over CPU memory and the ability to isolate a model from its dependencies and environment. We deploy Omni in two configurations; a container running multiple models or bare metal running a single model. In both cases, process isolation and Python virtual environments allow us to isolate models with different dependencies by creating namespaces and are limited by <a href="https://en.wikipedia.org/wiki/Cgroups"><u>cgroups</u></a>. </p><p>Python doesn’t take into account cgroups memory limits for memory allocations, which can lead to OOM errors. Many AI Python libraries rely on <a href="https://pypi.org/project/psutil/"><u>psutil</u></a> for pre-allocating CPU memory. psutil reads /proc/meminfo to determine how much memory is available. Since in Omni each model has its own configurable memory limits, we need psutil to reflect the current usage and limits for a given model, not for the entire system.</p><p>The solution for us was to create a virtual file system, using <a href="https://en.wikipedia.org/wiki/Filesystem_in_Userspace"><u>fuse</u></a>, to mount our own version of /proc/meminfo which reflects the model’s current usage and limits.</p><p>To illustrate this, here’s an Omni instance running a model (running as pid 8). If we enter the mount namespace and look at /proc/meminfo it will reflect the model’s configuration:</p>
            <pre><code># Enter the mount (file system) namespace of a child process
$ nsenter -t 8 -m

$ mount
...
none /proc/meminfo fuse ...

$ cat /proc/meminfo
MemTotal:     7340032 kB
MemFree:     7316388 kB
MemAvailable:     7316388 kB</code></pre>
            <p>In this case the model has 7Gib of memory available and the entire container 15Gib. If the model tries to allocate more than 7Gib of memory, it will be OOM killed and restarted by the scheduler’s process manager, without causing any problems to the other models.</p><p>For isolating Python and some system dependencies, each model runs in a Python virtual environment, managed by <a href="https://docs.astral.sh/uv/"><u>uv</u></a>. Dependencies are cached on the machine and, if possible, shared between models (uv uses symbolic links between its cache and virtual environments).</p><p>Also separated processes for models allows to have different CUDA contexts and isolation for error recovery. </p>
    <div>
      <h2>Over-committing memory to run more models on a single GPU</h2>
      <a href="#over-committing-memory-to-run-more-models-on-a-single-gpu">
        
      </a>
    </div>
    <p>Some models don’t receive enough traffic to fully utilize a GPU, and with Omni we can pack more models on a single GPU, freeing up capacity for other workloads. When it comes to GPU memory management, Omni has two main jobs: safely over-commit GPU memory, so that more models than normal can share a single GPU, and enforce memory limits, to prevent any single model from running out of memory while running.      </p><p>Over-committing memory means allocating more memory than is physically available to the device. </p><p>For example, if a GPU has 10 Gib of memory, Omni would allow 2 models of 10Gib each on that GPU.</p><p>Right now, Omni is configured to run 13 models and is allocating about 400% GPU memory on a single GPU, saving up 4 GPUs. Omni does this by injecting a CUDA stub library that intercepts CUDA memory allocations (cuMalloc* or cudaMalloc*) calls and forces memory allocations to be performed in <a href="https://developer.nvidia.com/blog/unified-memory-in-cuda-6/"><u>unified memory mode</u></a>.</p><p>In Unified memory mode CUDA shares the same memory address space for both the GPU and the CPU:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2G5zd0TDi15ZeFAmcJy812/1b292429140ec2c4bd0a81bee4954150/2.png" />
          </figure><p><sup><i>CUDA’s </i></sup><a href="https://developer.nvidia.com/blog/maximizing-unified-memory-performance-cuda/"><sup><i><u>unified memory mode</u></i></sup></a><sup><i> </i></sup></p><p>In practice this is what memory over-commitment looks like: imagine 3 models (A, B and C). Models A+B fit in the GPU’s memory but C takes up the entire memory.</p><ol><li><p>Models A+B are loaded first and are in GPU memory, while model C is in CPU memory</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xU141x0PaZRp83XlF6hWz/527915ee03309f619a64e6b43c62cd92/3.png" />
          </figure></li><li><p>Omni receives a request for model C so models A+B are swapped out and C is swapped in.
</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4fD3Y2xyyawGmo1gpdLsQz/1cd36ebaed6b7f9e95b3d31ead1c1098/4.png" />
          </figure></li><li><p>Omni receives a request for model B, so model C is partly swapped out and model B is swapped back in.
</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2v5JjDW0NCkVUfEBXwIgpL/62009bc970b0967a850cb31ef87be44b/5.png" />
          </figure></li><li><p>Omni receives a request for model A, so model A is swapped back in and model C is completely swapped out.</p></li></ol>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3cWGbEGgv3QckT7jgUIs9d/2c500a432be451a83dce0c71ccdcb89f/6.png" />
          </figure><p>The trade-off is added latency: if performing an inference requires memory that is currently on the host system, it must be transferred to the GPU. For smaller models, this latency is minimal, because with PCIe 4.0, the physical bus between your GPU and system, provides 32 GB/sec of bandwidth. On the other hand, if a model need to be “cold started” i.e. it’s been swapped out because it hasn’t been used in a while, the system may need to swap back the entire model – a larger sized model, for example, might use 5Gib of GPU memory for weights and caches, and would take ~156ms to be swapped back into the GPU. Naturally, over time, inactive models are put into CPU memory, while active models stay hot in the GPU.</p><p>Rather than allowing the model to choose how much GPU memory it uses, AI frameworks tend to pre-allocate as much GPU memory as possible for performance reasons, making co-locating models more complicated. Omni allows us to control how much memory is actually exposed to any given model to prevent a greedy model from over-using the GPU allocated to it. We do this by overriding the CUDA runtime and driver APIs (<a href="https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1g376b97f5ab20321ca46f7cfa9511b978"><u>cudaMemGetInfo</u></a> and <a href="https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__MEM.html#group__CUDA__MEM_1g808f555540d0143a331cc42aa98835c0"><u>cuMemGetInfo</u></a>). Instead of exposing the entire GPU memory, we only expose a subset of memory to each model.</p>
    <div>
      <h2>How Omni runs multiple models for Workers AI </h2>
      <a href="#how-omni-runs-multiple-models-for-workers-ai">
        
      </a>
    </div>
    <p>AI models can run in a variety of inference engines or backends: <a href="https://github.com/vllm-project/vllm"><u>vLLM</u></a>, Python, and now our very own inference engine, <a href="http://blog.cloudflare.com/cloudflares-most-efficient-ai-inference-engine/"><u>Infire</u></a>. While models have different capabilities, each model needs to support <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI features</u></a>, like batching and function calling. Omni acts as a unified layer for integrating these systems. It integrates into our internal routing and scheduling systems, and provides a Python API for our engineering team to add new models more easily. Let’s take a closer look at how Omni does this in practice:</p>
            <pre><code>from omni import Response
import cowsay


def handle_request(request, context):
    try:
        json = request.body.json
        text = json["text"]
    except Exception as err:
        return Response.error(...)

    return cowsay.get_output_string('cow', text)</code></pre>
            <p>Similar to how a JavaScript Worker works, Omni calls a request handler, running the model’s logic and returning a response. </p><p>Omni installs Python dependencies at model startup. We run an internal Python registry and mirror the public registry. In either case we declare dependencies in requirements.txt:</p>
            <pre><code>cowsay==6.1</code></pre>
            <p>The handle_request function can be async and return different Python types, including <a href="https://docs.pydantic.dev/latest/"><u>pydantic</u></a> objects. Omni will convert the return value into a Workers AI response for the eyeball.</p><p>A Python package is injected, named omni, containing all the Python APIs to interact with the request, the Workers AI systems, building Responses, error handling, etc. Internally we publish it as regular Python package to be used in standalone, for unit testing for instance:</p>
            <pre><code>from omni import Context, Request
from model import handle_request


def test_basic():
    ctx = Context.inactive()
    req = Request(json={"text": "my dog is cooler than you!"})
    out = handle_request(req, ctx)
    assert out == """  __________________________
| my dog is cooler than you! |
  ==========================
                          \\
                           \\
                             ^__^
                             (oo)\\_______
                             (__)\\       )\\/\\
                                 ||----w |
                                 ||     ||"""</code></pre>
            
    <div>
      <h2>What’s next </h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Omni allows us to run models more efficiently by spawning them from a single control plane and implementing lightweight process isolation. This enables quick starting and stopping of models, isolated file systems for managing Python and system dependencies, and over-committing GPU memory to run more models on a single GPU. This improves the performance for our entire Workers AI stack, reduces the cost of running GPUs, and allows us to ship new models and features quickly and safely.</p><p>Right now, Omni is running in production on a handful of models in the Workers AI catalog, and we’re adding more every week. Check out <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a> today to experience Omni’s performance benefits on your AI application. </p> ]]></content:encoded>
            <category><![CDATA[AI Week]]></category>
            <category><![CDATA[AI]]></category>
            <guid isPermaLink="false">KjxPspfQBaaHQ5K8ALjv8</guid>
            <dc:creator>Sven Sauleau</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Message Signatures are now part of our Verified Bots Program, simplifying bot authentication]]></title>
            <link>https://blog.cloudflare.com/verified-bots-with-cryptography/</link>
            <pubDate>Tue, 01 Jul 2025 10:00:00 GMT</pubDate>
            <description><![CDATA[ Bots can start authenticating to Cloudflare using public key cryptography, preventing them from being spoofed and allowing origins to have confidence in their identity. ]]></description>
            <content:encoded><![CDATA[ <p>As a site owner, how do you know which bots to allow on your site, and which you’d like to block? Existing identification methods rely on a combination of IP address range (which may be shared by other services, or change over time) and user-agent header (easily spoofable). These have limitations and deficiencies. In our <a href="https://blog.cloudflare.com/web-bot-auth/"><u>last blog post</u></a>, we proposed using HTTP Message Signatures: a way for developers of bots, agents, and crawlers to clearly identify themselves by cryptographically signing requests originating from their service. </p><p>Since we published the blog post on Message Signatures and the <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>IETF draft for Web Bot Auth</u></a> in May 2025, we’ve seen significant interest around implementing and deploying Message Signatures at scale. It’s clear that well-intentioned bot owners want a clear way to identify their bots to site owners, and site owners want a clear way to identify and manage bot traffic. Both parties seem to agree that deploying cryptography for the purposes of authentication is the right solution.     </p><p>Today, we’re announcing that we’re integrating HTTP Message Signatures directly into our <b>Verified Bots Program</b>. This announcement has two main parts: (1) for bots, crawlers, and agents, we’re simplifying enrollment into the Verified Bots program for those who sign requests using Message Signatures, and (2) we’re encouraging <i>all bot operators moving forward </i>to use Message Signatures over existing verification mechanisms. Because Verified Bots are considered authenticated, they do not face challenges from our Bot Management to identify as bots, given they’re already identified as such.</p><p>For site owners, no additional action is required – Cloudflare will automatically validate signatures on our edge, and if that validation is a success, that traffic will be marked as verified so that site owners can use the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/categories/"><u>verified bot fields</u></a> to create Bot Management and <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF rules</u></a> based on it.  </p><p>This isn't just about simplifying things for bot operators — it’s about giving website owners unparalleled accuracy in identifying trusted bot traffic, cutting down on the overhead for cryptographic verification, and fundamentally transforming how we manage authentication across the Cloudflare network.</p>
    <div>
      <h2>Become a Verified Bot with Message Signatures</h2>
      <a href="#become-a-verified-bot-with-message-signatures">
        
      </a>
    </div>
    <p>Cloudflare’s existing <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/"><u>Verified Bots program</u></a> is for bots that are transparent about who they are and what they do, like indexing sites for search or scanning for security vulnerabilities. You can see a list of these verified bots in <a href="https://radar.cloudflare.com/bots#verified-bots"><u>Cloudflare Radar</u></a>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2lMYno3QOwtwfTDDgeqFx8/c69088229dcf9fc08f5a76ce7e0a0354/1.png" />
          </figure><p><sup><i>A preview of the Verified Bots page on Cloudflare Radar. </i></sup></p><p>In the past, in order to <a href="https://dash.cloudflare.com/?to=/:account/configurations/verified-bots"><u>apply</u></a> to be a verified bot, we used to ask for IP address ranges or reverse DNS names so that we could verify your identity. This required some manual steps like checking that the IP address range is valid and is associated with the appropriate <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>ASN</u></a>. </p><p>With the integration of Message Signatures, we’re aiming to streamline applications into our Verified Bot program. Bots applying with well-formed Message Signatures will be prioritized, and approved more quickly! </p>
    <div>
      <h2>Getting started</h2>
      <a href="#getting-started">
        
      </a>
    </div>
    <p>In order to make generating Message Signatures as easy as possible, Cloudflare is providing two open source libraries: a <a href="https://crates.io/crates/web-bot-auth"><u>web-bot-auth library in rust</u></a>, and a <a href="https://www.npmjs.com/package/web-bot-auth"><u>web-bot-auth npm package in TypeScript</u></a>. If you’re working on a different implementation, <a href="https://www.cloudflare.com/lp/verified-bots/"><u>let us know</u></a> – we’d love to add it to our <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/"><u>developer docs</u></a>!</p><p>At a high level, signing your requests with web bot auth consists of the following steps: </p><ul><li><p>Generate a valid signing key. See <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/#1-generate-a-valid-signing-key"><u>Signing Key section</u></a> for step-by-step instructions.</p></li><li><p>Host a JSON web key set containing your public key under <code>/.well-known/http-message-signature-directory</code> of your website.</p></li><li><p>Sign responses for that URL using a Web Bot Auth library, one signature for each key contained in it, to prove you own it. See the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/web-bot-auth/#2-host-a-key-directory"><u>Hosting section</u></a> for step-by-step instructions.</p></li><li><p>Register that URL with us, using our Verified Bots form. This can be done directly in your Cloudflare account. See <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/overview/"><u>our documentation</u></a>.</p></li><li><p>Sign requests using a Web Bot Auth library. </p></li></ul><p>
As an example, <a href="https://radar.cloudflare.com/scan"><u>Cloudflare Radar's URL Scanner</u></a> lets you scan any URL and get a publicly shareable report with security, performance, technology, and network information. Here’s an example of what a well-formed signature looks like for requests coming from URL Scanner:</p>
            <pre><code>GET /path/to/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Signature-Agent: "https://web-bot-auth-directory.radar-cfdata-org.workers.dev"
Signature-Input: sig=("@authority" "signature-agent");\
             	 created=1700000000;\
             	 expires=1700011111;\
             	 keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U";\
             	 tag="web-bot-auth"
Signature:sig=jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKrD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA==:</code></pre>
            <p>Since we’ve already registered URLScanner as a Verified Bot, Cloudflare will now automatically verify that the signature in the <code>Signature</code> header matches the request — more on that later.</p>
    <div>
      <h2>Register your bot</h2>
      <a href="#register-your-bot">
        
      </a>
    </div>
    <p>Access the <a href="https://dash.cloudflare.com/?to=/:account/configurations/verified-bots"><u>Verified Bots submission form</u></a> on your account. If that link does not immediately take you there, go to <i>your Cloudflare account</i> →  <i>Account Home</i>  → <i>the three dots next to your account name</i>  → <i>Configurations</i> → <i>Verified Bots.</i></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/73yQcvLmiVDe19HJXYvBIc/ca2bdb2bb81addc29583568087c2ccc2/3.png" />
          </figure><p>If you do not have a Cloudflare account, you can <a href="https://dash.cloudflare.com/sign-up"><u>sign up for a free one</u></a>.</p><p>For the verification method, select "Request Signature", then enter the URL of your key directory in Validation Instructions. Specifying the User-Agent values is optional if you’re submitting a Request Signature bot. </p><p>Once your application has gone through our (now shortened) review process, you don’t need to take any further action.</p>
    <div>
      <h2>Message Signature verification for origins</h2>
      <a href="#message-signature-verification-for-origins">
        
      </a>
    </div>
    <p>Starting today, Cloudflare is ramping up verification of <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>cryptographic signatures provided by automated crawlers and bots</u></a>. This is currently available for all Free and Pro plans, and as we continue to test and validate at scale, will be released to all Business and Enterprise plans. This means that as time passes, the number of unauthenticated web crawlers should diminish, ensuring most bot traffic is authenticated before it reaches your website’s servers, helping to prevent spoofing attacks. </p><p>At a high level, signature verification works like this: </p><ol><li><p>A bot or agent sends a request to a website behind Cloudflare.</p></li><li><p>Cloudflare’s Message Signature verification service checks for the <code>Signature</code>, <code>Signature-Input</code>, and <code>Signature-Agent</code> headers.</p></li><li><p>It checks that the incoming request presents a <code>keyid</code> parameter in your Signature-Input that points to a key we already know.</p></li><li><p>It looks at the <code>expires</code> parameter in the incoming bot request. If the current time is after expiration, verification fails. This guards against replay attacks, preventing malicious agents from trying to pass as a bot by retrying messages they captured in the past.</p></li><li><p>It checks that you’ve specified a <code>tag</code> parameter indicating <code>web-bot-auth</code>, to indicate your intent that the message be handled using web bot authentication specifically</p></li><li><p>It looks at all the <a href="https://www.rfc-editor.org/rfc/rfc9421#covered-components"><u>components</u></a> chosen in your <code>Signature-Input</code> header, and constructs <a href="https://www.rfc-editor.org/rfc/rfc9421#name-creating-the-signature-base"><u>a signature base</u></a> from it. </p></li><li><p>If all pre-flight checks pass, Cloudflare attempts to verify the signature base against the value in Signature field using an <a href="https://www.rfc-editor.org/rfc/rfc9421#name-eddsa-using-curve-edwards25"><u>ed25519 verification algorithm</u></a> and the key supplied in <code>keyid</code>.</p></li><li><p>Verified Bots and other systems at Cloudflare use a successful verification as proof of your identity, and apply rules corresponding to that identity. </p></li></ol><p>If any of the above steps fail, Cloudflare falls back to existing bot identification and mitigation mechanisms. As the system matures, we would strengthen these requirements, and limit the possibilities of a soft downgrade.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/128Ox15wBqBPVKUUzvn4gA/acca9b9e6df243b8317b8964285ce57c/2.png" />
          </figure><p>As a site owner, you can segment your Verified Bot traffic by its type and purpose by adding the <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/categories/"><u>Verified Bot Categories</u></a> field <code>cf.verified_bot_category</code> as a filter criterion in <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF Custom rules</u></a>, <a href="https://developers.cloudflare.com/waf/rate-limiting-rules/"><u>Advanced Rate Limiting</u></a>, and Late <a href="https://developers.cloudflare.com/rules/transform/"><u>Transform rules</u></a>. For instance, to allow the Bibliothèque nationale de France and the Library of Congress, and institutions dedicated to academic research, you can add a rule that allows bots in the <code>Academic Research</code> category.</p>
    <div>
      <h2>Where we’re going next</h2>
      <a href="#where-were-going-next">
        
      </a>
    </div>
    <p>HTTP Message Signatures is a primitive that is useful beyond Cloudflare – the IETF standardized it as part of <a href="https://datatracker.ietf.org/doc/html/rfc9421"><u>RFC 9421</u></a>.</p><p>As discussed in our <a href="https://blog.cloudflare.com/web-bot-auth/#introducing-http-message-signatures"><u>previous blog post</u></a>, Cloudflare believes that making Message Signatures a core component of bot authentication on the web should follow the same path. The <a href="https://www.ietf.org/archive/id/draft-meunier-web-bot-auth-architecture-02.html"><u>specifications</u></a> for the protocol are being built in the open, and they have already evolved following feedback.</p><p>Moreover, due to widespread interest, the IETF is considering forming a working group around <a href="https://datatracker.ietf.org/wg/webbotauth/about/"><u>Web Bot Auth</u></a>. Should you be a crawler, an origin, or even a CDN, we invite you to provide feedback to ensure the solution gets stronger, and suits your needs.</p>
    <div>
      <h2>A better, more trusted Internet</h2>
      <a href="#a-better-more-trusted-internet">
        
      </a>
    </div>
    <p>For bot, agent, and crawler operators that act transparently and provide vital services for the Internet, we’re providing a faster and more automated path to being recognized as a Verified Bot, reducing manual processes. We trust that this approach improves bot authentication from what were formerly brittle and unreliable authentication methods, to a secure and reliable alternative. It should reduce the overall volume of friction and hurdles genuinely useful bots face.</p><p>For site owners, Message Signatures provides better assurance that the bot traffic is legitimate — automatically recognized and allowed, minimizing disruption to essential services (e.g., search engine indexing, monitoring). In line with our commitments to making TLS/<a href="https://blog.cloudflare.com/introducing-universal-ssl/"><u>SSL</u></a> and <a href="https://blog.cloudflare.com/pt-br/post-quantum-zero-trust/"><u>Post-Quantum</u></a> certificates available for everyone, we’ll always offer the cryptographic verification of Message Signatures for all sites because we believe in a safer and more efficient Internet by fostering a trusted environment for both human and automated traffic.</p><p>If you have a feature request, feedback, or are interested in partnering with us, please <a href="https://www.cloudflare.com/lp/verified-bots/"><u>reach out</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Pay Per Crawl]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">5K5btgE8vXWGaGxCrs5yFH</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Akshat Mahajan</dc:creator>
            <dc:creator>Gauri Baraskar</dc:creator>
            <dc:creator>Helen Du</dc:creator>
        </item>
        <item>
            <title><![CDATA[Orange Me2eets: We made an end-to-end encrypted video calling app and it was easy]]></title>
            <link>https://blog.cloudflare.com/orange-me2eets-we-made-an-end-to-end-encrypted-video-calling-app-and-it-was/</link>
            <pubDate>Thu, 26 Jun 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Orange Meets, our open-source video calling web application, now supports end-to-end encryption using the MLS protocol with continuous group key agreement. ]]></description>
            <content:encoded><![CDATA[ <p>Developing a new video conferencing application often begins with a peer-to-peer setup using <a href="https://webrtc.org/"><u>WebRTC</u></a>, facilitating direct data exchange between clients. While effective for small demonstrations, this method encounters scalability hurdles with increased participants. The data transmission load for each client escalates significantly in proportion to the number of users, as each client is required to send data to every other client except themselves (n-1).</p><p>In the scaling of video conferencing applications, Selective Forwarding Units (SFUs) are essential.  Essentially a media stream routing hub, an SFU receives media and data flows from participants and intelligently determines which streams to forward. By strategically distributing media based on network conditions and participant needs, this mechanism minimizes bandwidth usage and greatly enhances scalability. Nearly every video conferencing application today uses SFUs.</p><p>In 2024, we announced <a href="https://blog.cloudflare.com/cloudflare-calls-anycast-webrtc/"><u>Cloudflare Realtime</u></a> (then called Cloudflare Calls), our suite of WebRTC products, and we also released <a href="https://github.com/cloudflare/orange"><u>Orange Meets</u></a>, an open source video chat application built on top of our SFU.</p><p>We also realized that use of an SFU often comes with a privacy cost, as there is now a centralized hub that could see and listen to all the media contents, even though its sole job is to forward media bytes between clients as a data plane.</p><p>We believe end-to-end encryption should be the industry standard for secure communication and that’s why today we’re excited to share that we’ve implemented and open sourced end-to-end encryption in Orange Meets. Our generic implementation is client-only, so it can be used with any WebRTC infrastructure. Finally, our new <i>designated committer </i>distributed algorithm is verified in a bounded model checker to verify this algorithm handles edge cases gracefully.</p>
    <div>
      <h2>End-to-end encryption for video conferencing is different than for text messaging</h2>
      <a href="#end-to-end-encryption-for-video-conferencing-is-different-than-for-text-messaging">
        
      </a>
    </div>
    <p>End-to-end encryption describes a secure communication channel whereby only the intended participants can read, see, or listen to the contents of the conversation, not anybody else. WhatsApp and iMessage, for example, are end-to-end-encrypted, which means that the companies that operate those apps or any other infrastructure can’t see the contents of your messages. </p><p>Whereas encrypted group chats are usually long-lived, highly asynchronous, and low bandwidth sessions, video and audio calls are short-lived, highly synchronous, and require high bandwidth. This difference comes with plenty of interesting tradeoffs, which influenced the design of our system.</p><p>We had to consider how factors like the ephemeral nature of calls, compared to the persistent nature of group text messages, also influenced the way we designed E2EE for Orange Meets. In chat messages, users must be able to decrypt messages sent to them while they were offline (e.g. while taking a flight). This is not a problem for real-time communication.</p><p>The bandwidth limitations around audio/video communication and the use of an SFU prevented us from using some of the E2EE technologies already available for text messages. Apple’s iMessage, for example, encrypts a message N-1 times for an N-user group chat. We can't encrypt the video for each recipient, as that could saturate the upload capacity of Internet connections as well as slow down the client. Media has to be encrypted once and decrypted by each client while preserving secrecy around only the current participants of the call.</p>
    <div>
      <h2>Messaging Layer Security (MLS)</h2>
      <a href="#messaging-layer-security-mls">
        
      </a>
    </div>
    <p>Around the same time we were working on Orange Meets, we saw a lot of excitement around new apps being built with <a href="https://messaginglayersecurity.rocks/"><u>Messaging Layer Security</u></a> (MLS), an IETF-standardized protocol that describes how you can do a group key exchange in order to establish end-to-end-encryption for group communication. </p><p>Previously, the only way to achieve these properties was to essentially run your own fork of the <a href="https://signal.org/docs/"><u>Signal protocol</u></a>, which itself is more of a living protocol than a solidified standard. Since MLS is standardized, we’ve now seen multiple high-quality implementations appear, and we’re able to use them to achieve Signal-level security with far less effort.</p><p>Implementing MLS here wasn’t easy: it required a moderate amount of client modification, and the development and verification of an encrypted room-joining protocol. Nonetheless, we’re excited to be pioneering a standards-based approach that any customer can run on our network, and to share more details about how our implementation works. </p><p>We did not have to make any changes to the SFU to get end-to-end encryption working. Cloudflare’s SFU doesn’t care about the contents of the data forwarded on our data plane and whether it’s encrypted or not.</p>
    <div>
      <h2>Orange Meets: the basics </h2>
      <a href="#orange-meets-the-basics">
        
      </a>
    </div>
    <p>Orange Meets is a video calling application built on <a href="https://workers.cloudflare.com/"><u>Cloudflare Workers</u></a> that uses the <a href="https://developers.cloudflare.com/realtime/calls-vs-sfus/"><u>Cloudflare Realtime SFU service</u></a> as the data plane. The roles played by the three main entities in the application are as follows:</p><ul><li><p>The <i>user</i> is a participant in the video call. They connect to the Orange Meets server and SFU, described below.</p></li><li><p>The <i>Orange Meets Server </i>is a simple service run on a Cloudflare Worker that runs the small-scale coordination logic of Orange Meets, which is concerned with which user is in which video call — called a <i>room </i>— and what the state of the room is. Whenever something in the room changes, like a participant joining or leaving, or someone muting themselves, the app server broadcasts the change to all room participants. You can use any backend server for this component, we just chose Cloudflare Workers for its convenience.</p></li><li><p>Cloudflare Realtime <i>Selective Forwarding Unit</i> (SFU) is a service that Cloudflare runs, which takes everyone’s audio and video and broadcasts it to everyone else. These connections are potentially lossy, using UDP for transmission. This is done because a dropped video frame from five seconds ago is not very important in the context of a video call, and so should not be re-sent, as it would be in a TCP connection.</p></li></ul>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/61htaksggj580PqX02XoVB/3b0f1ed34ee681e41b2009257fdc8525/image2.png" />
          </figure><p><sup><i>The network topology of Orange Meets</i></sup></p><p>Next, we have to define what we mean by end-to-end encryption in the context of video chat.</p>
    <div>
      <h2>End-to-end encrypting Orange Meets </h2>
      <a href="#end-to-end-encrypting-orange-meets">
        
      </a>
    </div>
    <p>The most immediate way to end-to-end encrypt Orange Meets is to simply have the initial users agree on a symmetric encryption/decryption key at the beginning of a call, and just encrypt every video frame using that key. This is sufficient to hide calls from Cloudflare’s SFU. Some source-encrypted video conferencing implementations, such as <a href="https://jitsi.org/e2ee-in-jitsi/"><u>Jitsi Meet</u></a>, work this way.</p><p>The issue, however, is that kicking a malicious user from a call does not invalidate their key, since the keys are negotiated just once. A joining user learns the key that was used to encrypt video from before they joined. These failures are more formally referred to as failures of <i>post-compromise security</i> and <i>perfect forward secrecy</i>. When a protocol successfully implements these in a group setting, we call the protocol a <b>continuous group key agreement protocol</b>.</p><p>Fortunately for us, MLS is a continuous group key agreement protocol that works out of the box, and the nice folks at <a href="https://phnx.im/"><u>Phoenix R&amp;D</u></a> and <a href="https://cryspen.com/"><u>Cryspen</u></a> have a well-documented <a href="https://github.com/openmls/openmls/tree/main"><u>open-source Rust implementation</u></a> of most of the MLS protocol. </p><p>All we needed to do was write an MLS client and compile it to WASM, so we could decrypt video streams in-browser. We’re using WASM since that’s one way of running Rust code in the browser. If you’re running a video conferencing application on a desktop or mobile native environment, there are other MLS implementations in your preferred programming language.</p><p>Our setup for encryption is as follows:</p><p><b>Make a web worker for encryption.</b> We wrote a web worker in Rust that accepts a WebRTC video stream, broken into individual frames, and encrypts each frame. This code is quite simple, as it’s just an MLS encryption:</p>
            <pre><code>group.create_message(
	&amp;self.mls_provider,
	self.my_signing_keys.as_ref()?,
	frame,
)</code></pre>
            <p><b>Postprocess outgoing audio/video.</b> We take our normal stream and, using some newer features of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API"><u>WebRTC API</u></a>, add a transform step to it. This transform step simply sends the stream to the worker:</p>
            <pre><code>const senderStreams = sender.createEncodedStreams()
const { readable, writable } = senderStreams
this.worker.postMessage(
	{
    	    type: 'encryptStream',
    	    in: readable,
    	    out: writable,
	},
	[readable, writable]
)</code></pre>
            <p>And the same for decryption:</p>
            <pre><code>const receiverStreams = receiver.createEncodedStreams()
const { readable, writable } = receiverStreams
this.worker.postMessage(
	{
    	    type: 'decryptStream',
    	    in: readable,
    	    out: writable,
	},
	[readable, writable]
)</code></pre>
            <p>Once we do this for both audio and video streams, we’re done.</p>
    <div>
      <h2>Handling different codec behaviors</h2>
      <a href="#handling-different-codec-behaviors">
        
      </a>
    </div>
    <p>The streams are now encrypted before sending and decrypted before rendering, but the browser doesn’t know this. To the browser, the stream is still an ordinary video or audio stream. This can cause errors to occur in the browser’s depacketizing logic, which expects to see certain bytes in certain places, depending on the codec. This results in some extremely cypherpunk artifacts every dozen seconds or so:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/72baLJkLPZPdbjHjGVxSU5/2ea34b02826aacc2b23086b463a4938f/image3.png" />
          </figure><p>Fortunately, this exact issue was discovered by engineers at Discord, who handily documented it in their <a href="https://github.com/discord/dave-protocol/blob/main/protocol.md"><u>DAVE</u></a> E2EE videocalling protocol. For the VP8 codec, which we use by default, the solution is simple: split off the first 1–10 bytes of each packet, and send them unencrypted:</p>
            <pre><code>fn split_vp8_header(frame: &amp;[u8]) -&gt; Option&lt;(&amp;[u8], &amp;[u8])&gt; {
    // If this is a keyframe, keep 10 bytes unencrypted. Otherwise, 1 is enough
    let is_keyframe = frame[0] &gt;&gt; 7 == 0;
    let unencrypted_prefix_size = if is_keyframe { 10 } else { 1 };
    frame.split_at_checked(unencrypted_prefix_size)
}</code></pre>
            <p>These bytes are not particularly important to encrypt, since they only contain versioning info, whether or not this frame is a keyframe, some constants, and the width and height of the video.</p><p>And that’s truly it for the stream encryption part! The only thing remaining is to figure out how we will let new users join a room.</p>
    <div>
      <h2>“Join my Orange Meet” </h2>
      <a href="#join-my-orange-meet">
        
      </a>
    </div>
    <p>Usually, the only way to join the call is to click a link. And since the protocol is encrypted, a joining user needs to have some cryptographic information in order to decrypt any messages. How do they receive this information, though? There are a few options.</p><p>DAVE does it by using an MLS feature called <i>external proposals</i>. In short, the Discord server registers itself as an <i>external sender</i>, i.e., a party that can send administrative messages to the group, but cannot receive any. When a user wants to join a room, they provide their own cryptographic material, called a <i>key package</i>, and the server constructs and sends an MLS <a href="https://www.rfc-editor.org/rfc/rfc9420.html#section-12.1.8"><u>External Add message</u></a> to the group to let them know about the new user joining. Eventually, a group member will <i>commit</i> this External Add, sending the joiner a <i>Welcome</i> message containing all information necessary to send and receive video.
</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1gQm3r3Bai8Rks4M82JuSh/87ff851a12505f5c17c241e3f1eade6a/image4.png" />
          </figure><p><sup><i>A user joining a group via MLS external proposals. Recall the Orange Meets app server functions as a broadcast channel for the whole group. We consider a group of 3 members. We write member #2 as the one committing to the proposal, but this can be done by any member. Member #2 also sends a Commit message to the other members, but we omit this for space.</i></sup><sup>  </sup></p><p>This is a perfectly viable way to implement room joining, but implementing it would require us to extend the Orange Meets server logic to have some concept of MLS. Since part of our goal is to keep things as simple as possible, we would like to do all our cryptography client-side.</p><p>So instead we do what we call the <i>designated committer</i> algorithm. When a user joins a group, they send their cryptographic material to one group member, the <i>designated committer</i>, who then constructs and sends the Add message to the rest of the group. Similarly, when notified of a user’s exit, the designated committer constructs and sends a Remove message to the rest of the group. With this setup, the server’s job remains nothing more than broadcasting messages! It’s quite simple too—the full implementation of the designated committer state machine comes out to <a href="https://github.com/cloudflare/orange/blob/66e80d6d9146e2aedd4668e581810c0ee6aeb4a0/rust-mls-worker/src/mls_ops.rs#L90-L446"><u>300 lines of Rust</u></a>, including the MLS boilerplate, and it’s about as efficient.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3k3U7kFcYTwY81XzSrggt8/c27945dec311f251493826542704d370/image1.png" />
          </figure><p><sup><i>A user joining a group via the designated committer algorithm.</i></sup></p><p>One cool property of the designated committer algorithm is that something like this isn’t possible in a text group chat setting, since any given user (in particular, the designated committer) may be offline for an arbitrary period of time. Our method works because it leverages the fact that video calls are an inherently synchronous medium.</p>
    <div>
      <h3>Verifying the Designated Committer Algorithm with TLA<sup>+</sup></h3>
      <a href="#verifying-the-designated-committer-algorithm-with-tla">
        
      </a>
    </div>
    <p>The designated committer algorithm is a pretty neat simplification, but it comes with some non-trivial edge cases that we need to make sure we handle, such as:</p><ul><li><p><i>How do we make sure there is only one designated committer at a time?</i> The designated committer is the alive user with the smallest index in the MLS group state, which all users share.</p></li><li><p><i>What happens if the designated committer exits?</i> Then the next user will take its place. Every user keeps track of pending Adds and Removes, so it can continue where the previous designated committer left off.</p></li><li><p><i>If a user has not caught up to all messages, could they think they’re the designated committer?</i> No, they have to believe first that all prior eligible designated committers are disconnected.</p></li></ul><p>To make extra sure that this algorithm was correct, we formally modeled it and put it through the <a href="https://lamport.azurewebsites.net/tla/high-level-view.html"><u>TLA</u><u><sup>+</sup></u></a> model checker. To our surprise, it caught some low-level bugs! In particular, it found that, if the designated committer dies while adding a user, the protocol does not recover. We fixed these by breaking up MLS operations and enforcing a strict ordering on messages locally (e.g., a Welcome is always sent before its corresponding Add).</p><p>You can find an explainer, lessons learned, and the full <a href="https://learntla.com/core/index.html"><u>PlusCal</u></a> program (a high-level language that compiles to TLA<sup>+</sup>) <a href="https://github.com/cloudflareresearch/orange-e2ee-model-check"><u>here</u></a>. The caveat, as with any use of a bounded model checker, is that the checking is, well, bounded. We verified that no invalid protocol states are possible in a group of up to five users. We think this is good evidence that the protocol is correct for an arbitrary number of users. Because there are only two distinct roles in the protocol (designated committer and other group member), any weird behavior ought to be reproducible with two or three users, max.</p>
    <div>
      <h2>Preventing Monster-in-the-Middle attacks</h2>
      <a href="#preventing-monster-in-the-middle-attacks">
        
      </a>
    </div>
    <p>One important concern to address in any end-to-end encryption setup is how to prevent the service provider from replacing users’ key packages with their own. If the Orange Meets app server did this, and colluded with a malicious SFU to decrypt and re-encrypt video frames on the fly, then the SFU could see all the video sent through the network, and nobody would know.</p><p>To resolve this, like DAVE, we include a <i>safety number</i> in the corner of the screen for all calls. This number uniquely represents the cryptographic state of the group. If you check out-of-band (e.g., in a Signal group chat) that everyone agrees on the safety number, then you can be sure nobody’s key material has been secretly replaced.</p><p>In fact, you could also read the safety number aloud in the video call itself, but doing this is not provably secure. Reading a safety number aloud is an <i>in-band verification</i> mechanism, i.e., one where a party authenticates a channel within that channel. If a malicious app server colluding with a malicious SFU were able to construct believable video and audio of the user reading the safety number aloud, it could bypass this safety mechanism. So if your threat model includes adversaries that are able to break into a Worker and Cloudflare’s SFU, and simultaneously generate real-time deep-fakes, you should use out-of-band verification 😄.</p>
    <div>
      <h2>Future work</h2>
      <a href="#future-work">
        
      </a>
    </div>
    <p>There are some areas we could improve on:</p><ul><li><p>There is another attack vector for a malicious app server: it is possible to simply serve users malicious JavaScript. This problem, more generally called the <a href="https://web.archive.org/web/20200731144044/https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/"><u>JavaScript Cryptography Problem</u></a>, affects any in-browser application where the client wants to hide data from the server. Fortunately, we are working on a standard to address this, called <a href="https://github.com/beurdouche/explainers/blob/main/waict-explainer.md"><u>Web Application Manifest Consistency, Integrity, and Transparency</u></a>. In short, like our <a href="https://blog.cloudflare.com/key-transparency/"><u>Code Verify</u></a> solution for WhatsApp, this would allow every website to commit to the JavaScript it serves, and have a third party create an auditable log of the code. With transparency, malicious JavaScript can still be distributed, but at least now there is a log that records the code.</p></li><li><p>We can make out-of-band authentication easier by placing trust in an identity provider. Using <a href="https://www.bastionzero.com/openpubkey"><u>OpenPubkey</u></a>, it would be possible for a user to get the identity provider to sign their cryptographic material, and then present that. Then all the users would check the signature before using the material. Transparency would also help here to ensure no signatures were made in secret.</p></li></ul>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We built end-to-end encryption into the Orange Meets video chat app without a lot of engineering time, and by modifying just the client code. To do so, we built a WASM (compiled from Rust) <a href="https://github.com/cloudflare/orange/blob/e2ee/rust-mls-worker"><u>service worker</u></a> that sets up an <a href="https://www.rfc-editor.org/rfc/rfc9420.html"><u>MLS</u></a> group and does stream encryption and decryption, and designed a new joining protocol for groups, called the <i>designated committer algorithm</i>, and <a href="https://github.com/cloudflareresearch/orange-e2ee-model-check"><u>formally modeled it in TLA</u><u><sup>+</sup></u></a>. We made comments for all kinds of optimizations that are left to do, so please send us a PR if you’re so inclined!</p><p>Try using Orange Meets with E2EE enabled at <a href="https://e2ee.orange.cloudflare.dev/"><u>e2ee.orange.cloudflare.dev</u></a>, or deploy your own instance using the <a href="https://github.com/cloudflare/orange"><u>open source repository</u></a> on Github.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Encryption]]></category>
            <category><![CDATA[Video]]></category>
            <category><![CDATA[Cloudflare Realtime]]></category>
            <guid isPermaLink="false">6X6FQzpKaqVyTLVk7rw6xm</guid>
            <dc:creator>Michael Rosenberg</dc:creator>
            <dc:creator>Kevin Kipp</dc:creator>
            <dc:creator>Renan Dincer</dc:creator>
            <dc:creator>Felipe Astroza Araya</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Forget IPs: using cryptography to verify bot and agent traffic]]></title>
            <link>https://blog.cloudflare.com/web-bot-auth/</link>
            <pubDate>Thu, 15 May 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Bots now browse like humans. We're proposing bots use cryptographic signatures so that website owners can verify their identity. Explanations and demonstration code can be found within the post. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>With the rise of traffic from <a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/">AI agents</a>, what’s considered a bot is no longer clear-cut. There are some clearly malicious bots, like ones that DoS your site or do <a href="https://www.cloudflare.com/learning/bots/what-is-credential-stuffing/">credential stuffing</a>, and ones that most site owners do want to interact with their site, like the bot that indexes your site for a search engine, or ones that fetch RSS feeds.      </p><p>Historically, Cloudflare has relied on two main signals to verify legitimate web crawlers from other types of automated traffic: user agent headers and IP addresses. The <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent"><code><u>User-Agent</u></code><u> header</u></a> allows bot developers to identify themselves, i.e. <code>MyBotCrawler/1.1</code>. However, user agent headers alone are easily spoofed and are therefore insufficient for reliable identification. To address this, user agent checks are often supplemented with <a href="https://developers.cloudflare.com/bots/concepts/bot/verified-bots/policy/#ip-validation"><u>IP address validation</u></a>, the inspection of published IP address ranges to confirm a crawler's authenticity. However, the logic around IP address ranges representing a product or group of users is brittle – connections from the crawling service might be shared by multiple users, such as in the case of <a href="https://blog.cloudflare.com/icloud-private-relay/"><u>privacy proxies</u></a> and VPNs, and these ranges, often maintained by cloud providers, change over time.</p><p>Cloudflare will always try to block malicious bots, but we think our role here is to also provide an affirmative mechanism to authenticate desirable bot traffic. By using well-established cryptography techniques, we’re proposing a better mechanism for legitimate agents and bots to declare who they are, and provide a clearer signal for site owners to decide what traffic to permit. </p><p><b>Today, we’re introducing two proposals – HTTP message signatures and request mTLS – for </b><a href="https://blog.cloudflare.com/friendly-bots/"><b><u>friendly bots</u></b></a><b> to authenticate themselves, and for customer origins to identify them. </b>In this blog post, we’ll share how these authentication mechanisms work, how we implemented them, and how you can participate in our closed beta.</p>
    <div>
      <h2>Existing bot verification mechanisms are broken </h2>
      <a href="#existing-bot-verification-mechanisms-are-broken">
        
      </a>
    </div>
    <p>Historically, if you’ve worked on ChatGPT, Claude, Gemini, or any other agent, you’ve had several options to identify your HTTP traffic to other services: </p><ol><li><p>You define a <a href="https://www.rfc-editor.org/rfc/rfc9110#name-user-agent"><u>user agent</u></a>, an HTTP header described in <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-user-agent"><u>RFC 9110</u></a>. The problem here is that this header is easily spoofable and there’s not a clear way for agents to identify themselves as semi-automated browsers — agents often use the Chrome user agent for this very reason, which is discouraged. The RFC <a href="https://www.rfc-editor.org/rfc/rfc9110.html#section-10.1.5-9"><u>states</u></a>: 
<i>“If a user agent masquerades as a different user agent, recipients can assume that the user intentionally desires to see responses tailored for that identified user agent, even if they might not work as well for the actual user agent being used.” </i> </p></li><li><p>You publish your IP address range(s). This has limitations because the same IP address might be shared by multiple users or multiple services within the same company, or even by multiple companies when hosting infrastructure is shared (like <a href="https://www.cloudflare.com/developer-platform/products/workers/">Cloudflare Workers</a>, for example). In addition, IP addresses are prone to change as underlying infrastructure changes, leading services to use ad-hoc sharing mechanisms like <a href="https://www.cloudflare.com/ips-v4"><u>CIDR lists</u></a>. </p></li><li><p>You go to every website and share a secret, like a <a href="https://www.rfc-editor.org/rfc/rfc6750"><u>Bearer</u></a> token. This is impractical at scale because it requires developers to maintain separate tokens for each website their bot will visit.</p></li></ol><p>We can do better! Instead of these arduous methods, we’re proposing that developers of bots and agents cryptographically sign requests originating from their service. When protecting origins, <a href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/">reverse proxies</a> such as Cloudflare can then validate those signatures to confidently identify the request source on behalf of site owners, allowing them to take action as they see fit. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3yB6h6XcSWNQO5McRWIpL8/edf32f7938b01a4c8f5eedefee2b9328/image2.png" />
          </figure><p>A typical system has three actors:</p><ul><li><p>User: the entity that wants to perform some actions on the web. This may be a human, an automated program, or anything taking action to retrieve information from the web.</p></li><li><p>Agent: an orchestrated browser or software program. For example, Chrome on your computer, or OpenAI’s <a href="https://operator.chatgpt.com/"><u>Operator</u></a> with ChatGPT. Agents can interact with the web according to web standards (HTML rendering, JavaScript, subrequests, etc.).</p></li><li><p>Origin: the website hosting a resource. The user wants to access it through the browser. This is Cloudflare when your website is using our services, and it’s your own server(s) when exposed directly to the Internet.</p></li></ul><p>In the next section, we’ll dive into HTTP Message Signatures and request mTLS, two mechanisms a browser agent may implement to sign outgoing requests, with different levels of ease for an origin to adopt. </p>
    <div>
      <h2>Introducing HTTP Message Signatures</h2>
      <a href="#introducing-http-message-signatures">
        
      </a>
    </div>
    <p><a href="https://www.rfc-editor.org/rfc/rfc9421.html"><u>HTTP Message Signatures</u></a> is a standard that defines the cryptographic authentication of a request sender. It’s essentially a cryptographically sound way to say, “hey, it’s me!”. It’s not the only way that developers can sign requests from their infrastructure — for example, AWS has used <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html"><u>Signature v4</u></a>, and Stripe has a framework for <a href="https://docs.stripe.com/webhooks#verify-webhook-signatures-with-official-libraries"><u>authenticating webhooks</u></a> — but Message Signatures is a published standard, and the cleanest, most developer-friendly way to sign requests.  </p><p>We’re working closely with the wider industry to support these standards-based approaches. For example, OpenAI has started to sign their requests. In their own words:   </p><blockquote><p><i>"Ensuring the authenticity of Operator traffic is paramount. With HTTP Message Signatures (</i><a href="https://www.rfc-editor.org/rfc/rfc9421.html"><i><u>RFC 9421</u></i></a><i>), OpenAI signs all Operator requests so site owners can verify they genuinely originate from Operator and haven’t been tampered with” </i>– Eugenio, Engineer, OpenAI</p></blockquote><p>Without further delay, let’s dive in how HTTP Messages Signatures work to identify bot traffic.</p>
    <div>
      <h3>Scoping standards to bot authentication</h3>
      <a href="#scoping-standards-to-bot-authentication">
        
      </a>
    </div>
    <p>Generating a message signature works like this: before sending a request, the agent signs the target origin with a public key. When fetching <code>https://example.com/path/to/resource</code>, it signs <code>example.com</code>. This public key is known to the origin, either because the agent is well known, because it has previously registered, or any other method. Then, the agent writes a <b>Signature-Input</b> header with the following parameters:</p><ol><li><p>A validity window (<code>created</code> and <code>expires</code> timestamps)</p></li><li><p>A Key ID that uniquely identifies the key used in the signature. This is a <a href="https://www.rfc-editor.org/rfc/rfc7638.html"><u>JSON Web Key Thumbprint</u></a>.  </p></li><li><p>A tag that shows websites the signature’s purpose and validation method, i.e. <code>web-bot-auth</code> for bot authentication.</p></li></ol><p>In addition, the <code>Signature-Agent</code> header indicates where the origin can find the public keys the agent used when signing the request, such as in a directory hosted by <code>signer.example.com</code>. This header is part of the signed content as well.</p><p>Here’s an example:</p>
            <pre><code>GET /path/to/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 Chrome/113.0.0 MyBotCrawler/1.1
Signature-Agent: signer.example.com
Signature-Input: sig=("@authority" "signature-agent");\
             	 created=1700000000;\
             	 expires=1700011111;\
             	 keyid="ba3e64==";\
             	 tag="web-bot-auth"
Signature: sig=abc==</code></pre>
            <p>For those building bots, <a href="https://datatracker.ietf.org/doc/draft-meunier-web-bot-auth-architecture/"><u>we propose</u></a> signing the authority of the target URI, i.e. www.example.com, and a way to retrieve the bot public key in the form of <a href="https://datatracker.ietf.org/doc/draft-meunier-http-message-signatures-directory/"><u>signature-agent</u></a>, if present, i.e. <a href="http://crawler.search.google.com"><u>crawler.search.google.com</u></a> for Google Search, <a href="http://operator.openai.com"><u>operator.openai.com</u></a> for OpenAI Operator, workers.dev for Cloudflare Workers.</p><p>The <code>User-Agent</code> from the example above indicates that the software making the request is Chrome, because it is an agent that uses an orchestrated Chrome to browse the web. You should note that <code>MyBotCrawler/1.1</code> is still present. The <code>User-Agent</code> header can actually contain multiple products, in decreasing order of importance. If our agent is making requests via Chrome, that’s the most important product and therefore comes first.</p><p>At Internet-level scale, these signatures may add a notable amount of overhead to request processing. However, with the right cryptographic suite, and compared to the cost of existing bot mitigation, both technical and social, this seems to be a straightforward tradeoff. This is a metric we will monitor closely, and report on as adoption grows.</p>
    <div>
      <h3>Generating request signatures</h3>
      <a href="#generating-request-signatures">
        
      </a>
    </div>
    <p>We’re making several examples for generating Message Signatures for bots and agents <a href="https://github.com/cloudflareresearch/web-bot-auth/"><u>available on Github</u></a> (though we encourage other implementations!), all of which are standards-compliant, to maximize interoperability. </p><p>Imagine you’re building an agent using a managed Chromium browser, and want to sign all outgoing requests. To achieve this, the <a href="https://github.com/w3c/webextensions"><u>webextensions standard</u></a> provides <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeSendHeaders"><u>chrome.webRequest.onBeforeSendHeaders</u></a>, where you can modify HTTP headers before they are sent by the browser. The event is <a href="https://developer.chrome.com/docs/extensions/reference/api/webRequest#life_cycle_of_requests"><u>triggered</u></a> before sending any HTTP data, and when headers are available.</p><p>Here’s what that code would look like: </p>
            <pre><code>chrome.webRequest.onBeforeSendHeaders.addListener(
  function (details) {
	// Signature and header assignment logic goes here
      // &lt;CODE&gt;
  },
  { urls: ["&lt;all_urls&gt;"] },
  ["blocking", "requestHeaders"] // requires "installation_mode": "force_installed"
);</code></pre>
            <p>Cloudflare provides a <a href="https://www.npmjs.com/package/web-bot-auth"><u>web-bot-auth</u></a> helper package on npm that helps you generate request signatures with the correct parameters. <code>onBeforeSendHeaders</code> is a Chrome extension hook that needs to be implemented synchronously. To do so, we <code>import {signatureHeadersSync} from “web-bot-auth”</code>. Once the signature completes, both <code>Signature</code> and <code>Signature-Input</code> headers are assigned. The request flow can then continue.</p>
            <pre><code>const request = new URL(details.url);
const created = new Date();
const expired = new Date(created.getTime() + 300_000)


// Perform request signature
const headers = signatureHeadersSync(
  request,
  new Ed25519Signer(jwk),
  { created, expires }
);
// `headers` object now contains `Signature` and `Signature-Input` headers that can be used</code></pre>
            <p>This extension code is available on <a href="https://github.com/cloudflareresearch/web-bot-auth/"><u>GitHub</u></a>, alongside a  debugging server, deployed at <a href="https://http-message-signatures-example.research.cloudflare.com"><u>https://http-message-signatures-example.research.cloudflare.com</u></a>. </p>
    <div>
      <h3>Validating request signatures </h3>
      <a href="#validating-request-signatures">
        
      </a>
    </div>
    <p>Using our <a href="https://http-message-signatures-example.research.cloudflare.com"><u>debug server</u></a>, we can now inspect and validate our request signatures from the perspective of the website we’d be visiting. We should now see the Signature and Signature-Input headers:  </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/18P5OyGxu2fU0Dpyv70Gjz/d82d62355524ad1914deb41b601bcad2/image3.png" />
          </figure><p><sup><i>In this example, the homepage of the debugging server validates the signature from the RFC 9421 Ed25519 verifying key, which the extension uses for signing.</i></sup></p><p>The above demo and code walkthrough has been fully written in TypeScript: the verification website is on Cloudflare Workers, and the client is a Chrome browser extension. We are cognisant that this does not suit all clients and servers on the web. To demonstrate the proposal works in more environments, we have also implemented bot signature validation in Go with a <a href="https://github.com/cloudflareresearch/web-bot-auth/tree/main/examples/caddy-plugin"><u>plugin</u></a> for <a href="https://caddyserver.com/"><u>Caddy server</u></a>.</p>
    <div>
      <h2>Experimentation with request mTLS</h2>
      <a href="#experimentation-with-request-mtls">
        
      </a>
    </div>
    <p>HTTP is not the only way to convey signatures. For instance, one mechanism that has been used in the past to authenticate automated traffic against secured endpoints is <a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/"><u>mTLS</u></a>, the “mutual” presentation of <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificates</a>. As described in our <a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/"><u>knowledge base</u></a>:</p><blockquote><p><i>Mutual TLS, or mTLS for short, is a method for</i><a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-authentication/"><i> </i><i><u>mutual authentication</u></i></a><i>. mTLS ensures that the parties at each end of a network connection are who they claim to be by verifying that they both have the correct private</i><a href="https://www.cloudflare.com/learning/ssl/what-is-a-cryptographic-key/"><i> </i><i><u>key</u></i></a><i>. The information within their respective</i><a href="https://www.cloudflare.com/learning/ssl/what-is-an-ssl-certificate/"><i> </i><i><u>TLS certificates</u></i></a><i> provides additional verification.</i></p></blockquote><p>While mTLS seems like a good fit for bot authentication on the web, it has limitations. If a user is asked for authentication via the mTLS protocol but does not have a certificate to provide, they would get an inscrutable and unskippable error. Origin sites need a way to conditionally signal to clients that they accept or require mTLS authentication, so that only mTLS-enabled clients use it.</p>
    <div>
      <h3>A TLS flag for bot authentication</h3>
      <a href="#a-tls-flag-for-bot-authentication">
        
      </a>
    </div>
    <p>TLS flags are an efficient way to describe whether a feature, like mTLS, is supported by origin sites. Within the IETF, we have proposed a new TLS flag called <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><code><u>req mTLS</u></code></a> to be sent by the client during the establishment of a connection that signals support for authentication via a client certificate. </p><p>This proposal leverages the <a href="https://www.ietf.org/archive/id/draft-ietf-tls-tlsflags-14.html"><u>tls-flags</u></a> proposal under discussion in the IETF. The TLS Flags draft allows clients and servers to send an array of one bit flags to each other, rather than creating a new extension (with its associated overhead) for each piece of information they want to share. This is one of the first uses of this extension, and we hope that by using it here we can help drive adoption.</p><p>When a client sends the <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><code><u>req mTLS</u></code></a> flag to the server, they signal to the server that they are able to respond with a certificate if requested. The server can then safely request a certificate without risk of blocking ordinary user traffic, because ordinary users will never set this flag. </p><p>Let’s take a look at what an example of such a req mTLS would look like in <a href="https://www.wireshark.org/"><u>Wireshark</u></a>, a network protocol analyser. You can follow along in the packet capture <a href="https://github.com/cloudflareresearch/req-mtls/tree/main/assets/demonstration-capture.pcapng"><u>here</u></a>.</p>
            <pre><code>Extension: req mTLS (len=12)
	Type: req mTLS (65025)
	Length: 12
	Data: 0b0000000000000000000001</code></pre>
            <p>The extension number is 65025, or 0xfe01. This corresponds to an unassigned block of <a href="https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-1"><u>TLS extensions</u></a> that can be used to experiment with TLS Flags. Once the standard is adopted and published by the IETF, the number would be fixed. To use the <code>req mTLS</code> flag the client needs to set the 80<sup>th</sup> bit to true, so with our block length of 12 bytes, it should  contain the data 0b0000000000000000000001, which is the case here. The server then responds with a certificate request, and the request follows its course.</p>
    <div>
      <h3>Request mTLS in action</h3>
      <a href="#request-mtls-in-action">
        
      </a>
    </div>
    <p><i>Code for this section is available in GitHub under </i><a href="https://github.com/cloudflareresearch/req-mtls"><i><u>cloudflareresearch/req-mtls</u></i></a></p><p>Because mutual TLS is widely supported in TLS libraries already, the parts we need to introduce to the client and server are:</p><ol><li><p>Sending/parsing of TLS-flags</p></li><li><p>Specific support for the <code>req mTLS</code> flag</p></li></ol><p>To the best of our knowledge, there is no complete public implementation of either scheme. Using it for bot authentication may provide a motivation to do so.</p><p>Using <a href="https://github.com/cloudflare/go"><u>our experimental fork of Go</u></a>, a TLS client could support req mTLS as follows:</p>
            <pre><code>config := &amp;tls.Config{
    	TLSFlagsSupported:  []tls.TLSFlag{0x50},
    	RootCAs:       	rootPool,
    	Certificates:  	certs,
    	NextProtos:    	[]string{"h2"},
}
trans := http.Transport{TLSClientConfig: config, ForceAttemptHTTP2: true}</code></pre>
            <p>This example library allows you to configure Go to send <code>req mTLS 0x50</code> bytes in the <code>TLS Flags</code> extension. If you’d like to test your implementation out, you can prompt your client for certificates against <a href="http://req-mtls.research.cloudflare.com"><u>req-mtls.research.cloudflare.com</u></a> using the Cloudflare Research client <a href="https://github.com/cloudflareresearch/req-mtls"><u>cloudflareresearch/req-mtls</u></a>. For clients, once they set the TLS Flags associated with <code>req mTLS</code>, they are done. The code section taking care of normal mTLS will take over at that point, with no need to implement something new.</p>
    <div>
      <h2>Two approaches, one goal</h2>
      <a href="#two-approaches-one-goal">
        
      </a>
    </div>
    <p>We believe that developers of agents and bots should have a public, standard way to authenticate themselves to CDNs and website hosting platforms, regardless of the technology they use or provider they choose. At a high level, both HTTP Message Signatures and request mTLS achieve a similar goal: they allow the owner of a service to authentically identify themselves to a website. That’s why we’re participating in the standardizing effort for both of these protocols at the IETF, where many other authentication mechanisms we’ve discussed here — from TLS to OAuth Bearer tokens –— been developed by diverse sets of stakeholders and standardized as RFCs.   </p><p>Evaluating both proposals against each other, we’re prioritizing <a href="https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture"><u>HTTP Message Signatures for Bots</u></a> because it relies on the previously adopted <a href="https://datatracker.ietf.org/doc/html/rfc9421"><u>RFC 9421</u></a> with several <a href="https://httpsig.org/"><u>reference implementations</u></a>, and works at the HTTP layer, making adoption simpler. <a href="https://datatracker.ietf.org/doc/draft-jhoyla-req-mtls-flag/"><u>request mTLS</u></a> may be a better fit for site owners with concerns about the additional bandwidth, but <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-tlsflags"><u>TLS Flags</u></a> has fewer implementations, is still waiting for IETF adoption, and upgrading the TLS stack has proven to be more challenging than with HTTP. Both approaches share similar discovery and key management concerns, as highlighted in a <a href="https://datatracker.ietf.org/doc/draft-meunier-web-bot-auth-glossary/"><u>glossary</u></a> draft at the IETF. We’re actively exploring both options, and would love to <a href="https://www.cloudflare.com/lp/verified-bots/"><u>hear</u></a> from both site owners and bot developers about how you’re evaluating their respective tradeoffs.</p>
    <div>
      <h2>The bigger picture </h2>
      <a href="#the-bigger-picture">
        
      </a>
    </div>
    <p>In conclusion, we think request signatures and mTLS are promising mechanisms for bot owners and developers of AI agents to authenticate themselves in a tamper-proof manner, forging a path forward that doesn’t rely on ever-changing IP address ranges or spoofable headers such as <code>User-Agent</code>. This authentication can be consumed by Cloudflare when acting as a reverse proxy, or directly by site owners on their own infrastructure. This means that as a bot owner, you can now go to content creators and discuss crawling agreements, with as much granularity as the number of bots you have. You can start implementing these solutions today and test them against the research websites we’ve provided in this post.</p><p>Bot authentication also empowers site owners small and large to have more control over the traffic they allow, empowering them to continue to serve content on the public Internet while monitoring automated requests. Longer term, we will integrate these authentication mechanisms into our <a href="https://blog.cloudflare.com/cloudflare-ai-audit-control-ai-content-crawlers/"><u>AI Audit</u></a> and <a href="https://developers.cloudflare.com/bots/get-started/bot-management/"><u>Bot Management</u></a> products, to provide better visibility into the bots and agents that are willing to identify themselves.</p><p>Being able to solve problems for both origins and clients is key to helping build a better Internet, and we think identification of automated traffic is a step towards that. If you want us to start verifying your message signatures or client certificates, have a compelling use case you’d like us to consider, or any questions, please <a href="https://www.cloudflare.com/lp/verified-bots/"><u>reach out</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">2hUP3FdePgIYVDwhgJVLeV</guid>
            <dc:creator>Thibault Meunier</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[What’s new in Cloudflare: MASQUE now powers 1.1.1.1 & WARP apps, DEX now generally available with Remote Captures]]></title>
            <link>https://blog.cloudflare.com/masque-now-powers-1-1-1-1-and-warp-apps-dex-available-with-remote-captures/</link>
            <pubDate>Fri, 27 Dec 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[ This roundup blog post shares the latest new features and capabilities at Cloudflare. ]]></description>
            <content:encoded><![CDATA[ <p>At Cloudflare, we are constantly innovating and launching new features and capabilities across our product portfolio. Today’s roundup blog post shares two exciting updates across our platform: our cross-platform <a href="https://www.cloudflare.com/en-gb/learning/dns/what-is-1.1.1.1/"><u>1.1.1.1</u></a> &amp; <a href="https://developers.cloudflare.com/warp-client/"><u>WARP</u></a> applications (consumer) and device agents (Zero Trust)  now use <a href="https://blog.cloudflare.com/masque-building-a-new-protocol-into-cloudflare-warp/"><u>MASQUE</u></a>, a cutting-edge <a href="https://www.cloudflare.com/en-gb/learning/performance/what-is-http3/"><u>HTTP/3</u></a>-based protocol, to secure your Internet connection. Additionally, DEX is now available for general availability. </p>
    <div>
      <h2>Faster and more stable: our 1.1.1.1 &amp; WARP apps now use MASQUE by default</h2>
      <a href="#faster-and-more-stable-our-1-1-1-1-warp-apps-now-use-masque-by-default">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6CghJvmC5DBnhKLM36MY3O/ecf722a9d9b5a4e4a048afea06237749/image1.png" />
          </figure><p>We’re excited to announce that as of today, our cross-platform <a href="https://www.cloudflare.com/en-gb/learning/dns/what-is-1.1.1.1/"><u>1.1.1.1</u></a> &amp; <a href="https://developers.cloudflare.com/warp-client/"><u>WARP</u></a> apps now use <a href="https://blog.cloudflare.com/masque-building-a-new-protocol-into-cloudflare-warp/"><u>MASQUE</u></a>, a cutting-edge <a href="https://www.cloudflare.com/en-gb/learning/performance/what-is-http3/"><u>HTTP/3</u></a>-based protocol, to secure your Internet connection.</p><p>As a reminder, our 1.1.1.1 &amp; WARP apps have two main functions: send all DNS queries through 1.1.1.1, our privacy-preserving DNS resolver, and protect your device’s network traffic via WARP by creating a private and encrypted tunnel to the resources you’re accessing, preventing unwanted third parties or public Wi-Fi networks from snooping on your traffic.</p><p>There are many ways to encrypt and proxy Internet traffic — you may have heard of a few, such as IPSec, WireGuard, or OpenVPN. There are many tradeoffs we considered when choosing a protocol, but we believe MASQUE is the future of fast, secure, and stable Internet proxying, it aligns with our belief in building on top of open Internet standards, and we’ve deployed it successfully at scale for customers like <a href="https://blog.cloudflare.com/icloud-private-relay/"><u>iCloud Private Relay</u></a> and <a href="https://blog.cloudflare.com/cloudflare-now-powering-microsoft-edge-secure-network/"><u>Microsoft Edge Secure Network</u></a>.</p>
    <div>
      <h3>Why MASQUE?</h3>
      <a href="#why-masque">
        
      </a>
    </div>
    <p><a href="https://blog.cloudflare.com/masque-building-a-new-protocol-into-cloudflare-warp/"><b><u>MASQUE</u></b></a> is a modern framework for proxying traffic that allows a variety of application protocols, including HTTP/3, to utilize QUIC as their transport mechanism. That’s a lot of acronyms, so let's make sure those are clear. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6XkQ3rF8oo8JaG0Iujskia/6383b0c0bce36a94298960c163495843/image4.png" />
          </figure><p><a href="https://blog.cloudflare.com/quic-version-1-is-live-on-cloudflare/"><b><u>QUIC</u></b></a> is a general-purpose transport protocol and <a href="https://www.rfc-editor.org/rfc/rfc9000.html"><u>Internet standard</u></a> that operates on top of UDP (instead of TCP), is encrypted by default, and solves several performance issues that plagued its predecessors. <a href="https://www.cloudflare.com/en-gb/learning/performance/what-is-http3/"><b><u>HTTP/3</u></b></a><b> </b>is the latest version of the HTTP protocol, defining the application-layer protocol that runs on top of QUIC as its transport mechanism. MASQUE is a set of mechanisms for tunneling traffic over HTTP. It extends the existing HTTP CONNECT model, to allow tunneling UDP and IP traffic. This is especially efficient when combined with the QUIC’s <a href="https://datatracker.ietf.org/doc/html/rfc9221"><u>unreliable datagram extension</u></a>. </p><p>For example, we can use MASQUE’s <a href="https://www.rfc-editor.org/rfc/rfc9484.html"><u>CONNECT-IP method</u></a> to establish a tunnel that can send multiple concurrent requests over a single QUIC connection:</p>
            <pre><code>HEADERS
:method = CONNECT
:protocol = connect-ip
:scheme = https
:path = /.well-known/masque/ip/*/*/
:authority = example.org
capsule-protocol = ?1</code></pre>
            <p>The benefit these protocols have for the quality and security of everyone’s Internet browsing experience is real. Earlier transport protocols were built before the advent of smartphones and mobile networks, so QUIC was designed to support a mobile world, maintaining connections even in poorly connected networks, and minimizing disruptions as people switch rapidly between networks as they move through their day. Leveraging HTTP/3 as the application layer means that MASQUE is more like “normal” HTTP traffic on the Internet, meaning that it is easier to support, is compatible with existing firewall and security rules, and that it supports cryptographic agility (i.e. support for <a href="https://blog.cloudflare.com/post-quantum-for-all/"><u>post-quantum crypto</u></a>), making this traffic more secure and resilient in the long term.</p>
    <div>
      <h3>Get started now </h3>
      <a href="#get-started-now">
        
      </a>
    </div>
    <p>All new installations of our 1.1.1.1 &amp; WARP apps support MASQUE, including iOS, Android, macOS, Windows, and Linux, and we’ve started to roll it out as the preferred protocol over WireGuard. <a href="https://developers.cloudflare.com/warp-client/get-started/"><u>On mobile</u></a>, to check if your connection is already secured over MASQUE, or change your device’s default option, you can toggle this setting via <i>Advanced &gt; Connection options &gt; Tunnel protocol:</i></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3c7lAh7C5huXDUYt4v7B7w/a089967f8d9d668b2ded321f40b35cf4/Screenshot_2024-12-23_at_18.26.20.png" />
          </figure><p><sup><i>Protocol connection options shown here on the iOS app</i></sup></p><p>We offer the following options: </p><ul><li><p><b>Auto</b>: this allows the app to choose the protocol.</p></li><li><p><b>MASQUE</b>: always use MASQUE to secure your connection.</p></li><li><p><b>WireGuard</b>: always use WireGuard to secure your connection.</p></li></ul><p>On <a href="https://developers.cloudflare.com/warp-client/get-started/linux/"><u>desktop</u></a> versions, you can switch the protocol by using the WARP command-line interface. For example:</p>
            <pre><code>warp-cli tunnel protocol set WireGuard
warp-cli tunnel protocol set MASQUE</code></pre>
            <p>With this rollout, we're excited to see MASQUE deliver increased performance and stability to millions of users. Download <a href="https://one.one.one.one/"><u>one of the WARP apps</u></a> today!</p>
    <div>
      <h2>DEX now Generally Available: Announcing detailed device visibility with DEX Remote Captures</h2>
      <a href="#dex-now-generally-available-announcing-detailed-device-visibility-with-dex-remote-captures">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2RkuqjgXZh8tmoj4W1narK/baaf61dcde00bbfa4cef71e5dbd2cc23/image2.png" />
          </figure><p><i>Following the successful beta launch of Digital Experience Monitoring (DEX), we are thrilled to announce the general availability of DEX, along with new Remote Captures functionality.</i></p><p>In today's hyper distributed environment, user experience is paramount. Recurring performance problems can lead to decreased user satisfaction, lost productivity, and damaged brand reputation.  <a href="https://www.cloudflare.com/learning/performance/what-is-digital-experience-monitoring/"><u>Digital Experience Monitoring (DEX)</u></a> offers a comprehensive solution to these challenges. Previous blog posts have discussed the solution and its capabilities. (<a href="https://blog.cloudflare.com/introducing-digital-experience-monitoring/"><i><u>Introducing Digital Experience Monitoring</u></i></a><i>, </i><a href="https://blog.cloudflare.com/digital-experience-monitoring-beta/"><i><u>Understanding end user-connectivity and performance with Digital Experience Monitoring, now available in beta</u></i></a><i>, </i><a href="https://blog.cloudflare.com/tag/dex"><i><u>What's new in Cloudflare One: Digital Experience monitoring notifications</u></i></a>)</p>
    <div>
      <h3>Introducing Remote Captures: PCAP and WARP Diag</h3>
      <a href="#introducing-remote-captures-pcap-and-warp-diag">
        
      </a>
    </div>
    <p>Imagine this: an end user is frustrated with a slow application, and your IT team is struggling to pinpoint the root cause. Traditionally, troubleshooting such issues involved contacting the end user and asking them to manually collect and share network traffic data. This process is time-consuming, prone to errors, and often disruptive to the end user's workflow.</p><p>Building upon the capabilities of DEX, we are excited to introduce Remote Captures, a powerful new feature that empowers IT admins to gain unprecedented visibility into end-user devices and network performance. DEX now introduces Remote Captures, a powerful new feature that empowers IT admins to remotely initiate network <a href="https://en.wikipedia.org/wiki/Pcap"><u>packet captures (PCAP)</u></a> and <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/troubleshooting/warp-logs/"><u>WARP Diag logs</u></a> directly from your end users’ devices and capture diagnostic information automatically from our device client. This streamlined approach accelerates troubleshooting, reduces the burden on end users, and provides valuable insights into network performance and security.</p>
    <div>
      <h3>Why Remote Captures?</h3>
      <a href="#why-remote-captures">
        
      </a>
    </div>
    <p>Remote Captures offer several key advantages. By analyzing detailed network traffic, IT teams can quickly pinpoint the root cause of network issues. Furthermore, granular network data empowers security teams to proactively detect and investigate potential threats. Finally, by identifying bottlenecks and latency issues, Remote Captures enable organizations to optimize network performance for a smoother user experience.</p>
    <div>
      <h3>How Remote Captures work</h3>
      <a href="#how-remote-captures-work">
        
      </a>
    </div>
    <p>Initiating a Remote Capture is straightforward. First, select the specific device you wish to troubleshoot. Then, with a few simple clicks, start capturing network traffic and/or WARP Diag data. Once the capture is complete, download the captured data and utilize your preferred tools for in-depth analysis.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5NWQAhlUK8OQvuydQV0lb7/d93f6792e897120aa5e2f837a6ec7786/image3.png" />
          </figure>
    <div>
      <h3>Get started today</h3>
      <a href="#get-started-today">
        
      </a>
    </div>
    <p>DEX Remote Captures are now available for Cloudflare One customers. They can be configured by going to <a href="https://dash.cloudflare.com/"><u>Cloudflare Dashboard</u></a> &gt;  Zero Trust &gt; DEX &gt; Remote Captures, and then selecting the device you wish to collect from. For more information, refer to <a href="https://developers.cloudflare.com/cloudflare-one/insights/dex/remote-captures/"><u>Remote captures</u></a>. This new capability highlights just one of the many ways our unified SASE platform helps organizations find and fix security issues across SaaS applications. <a href="https://dash.cloudflare.com/sign-up/teams"><u>Try it out now</u></a> using our free tier to get started.</p>
    <div>
      <h2>Never miss an update </h2>
      <a href="#never-miss-an-update">
        
      </a>
    </div>
    <p>We hope you enjoy reading our roundup blog posts as we continue to build and innovate. Stay tuned to the <a href="https://blog.cloudflare.com/"><u>Cloudflare Blog</u></a> for the latest news and updates.</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Zero Trust]]></category>
            <category><![CDATA[DEX]]></category>
            <category><![CDATA[1.1.1.1]]></category>
            <category><![CDATA[MASQUE]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">1zc4C9M6VIkj5TrfugGxum</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Guy Nir</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare helps verify the security of end-to-end encrypted messages by auditing key transparency for WhatsApp]]></title>
            <link>https://blog.cloudflare.com/key-transparency/</link>
            <pubDate>Tue, 24 Sep 2024 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is now verifying WhatsApp’s Key Transparency audit proofs to ensure the security of end-to-end encrypted messaging conversations without having to manually check QR codes. We are publishing the results of the proof verification to https://dash.key-transparency.cloudflare.com for independent researchers and security experts to compare against WhatsApp’s. Cloudflare does not have access to underlying public key material or message metadata as part of this infrastructure. ]]></description>
            <content:encoded><![CDATA[ <p>Chances are good that today you’ve sent a message through an <a href="https://www.cloudflare.com/learning/privacy/what-is-end-to-end-encryption"><u>end-to-end encrypted (E2EE)</u></a> messaging app such as WhatsApp, Signal, or iMessage. While we often take the privacy of these conversations for granted, they in fact rely on decades of research, testing, and standardization efforts, the foundation of which is a <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/"><u>public-private key exchange</u></a>. There is, however, an oft-overlooked implicit trust inherent in this model: that the messaging app infrastructure is distributing the public keys of all of its users correctly.</p><p>Here’s an example: if Joe and Alice are messaging each other on WhatsApp, Joe uses Alice’s phone number to retrieve Alice’s public key from the WhatsApp database, and Alice receives Joe’s public key. Their messages are then encrypted using this key exchange, so that no one — even WhatsApp — can see the contents of their messages besides Alice and Joe themselves. However, in the unlikely situation where an attacker, Bob, manages to register a different public key in WhatsApp’s database, Joe would try to message Alice but unknowingly be messaging Bob instead. And while this threat is most salient for journalists, activists, and those most vulnerable to cyber attacks<i>, </i>we believe that protecting the privacy and integrity of end-to-end encrypted conversations is for everyone.</p><p>There are several methods that end-to-end encrypted messaging apps have deployed thus far to protect the integrity of public key distribution, the most common of which is to do an in-person verification of the QR code fingerprint of your public key (<a href="https://faq.whatsapp.com/2416198805185327?helpref=faq_content"><u>WhatsApp</u></a> and <a href="https://signal.org/blog/safety-number-updates/"><u>Signal</u></a> both have a version of this). As you can imagine, this experience is inconvenient and unwieldy, especially as your number of contacts and group chats increase.</p><p>Over the past few years, there have been significant developments in this area of cryptography, and WhatsApp has paved the way with their <a href="https://engineering.fb.com/2023/04/13/security/whatsapp-key-transparency/"><u>Key Transparency announcement</u></a>. But as an independent third party, Cloudflare can provide stronger reassurance: that’s why we’re excited to announce that we’re now verifying WhatsApp’s Key Transparency audit proofs. </p>
    <div>
      <h2>Auditing: the next frontier of encryption </h2>
      <a href="#auditing-the-next-frontier-of-encryption">
        
      </a>
    </div>
    <p>We didn’t build this in a vacuum: similar to how the web and messaging apps became encrypted over time, we see auditing public key infrastructure as the next logical step in securing Internet infrastructure. This solution builds upon learnings from <a href="https://en.wikipedia.org/wiki/Certificate_Transparency"><u>Certificate Transparency</u></a> and<a href="https://binary.transparency.dev/"><u> Binary Transparency</u></a>, which share some of the underlying data structure and cryptographic techniques, and we’re excited about the formation of a <a href="https://mailarchive.ietf.org/arch/browse/keytrans/"><u>working group at the IETF</u></a> to make multi-party operation of Key Transparency-like systems tractable for a broader set of use cases. </p><p>We see our role here as a pioneer of a real world deployment of this auditing infrastructure, working through and sharing the operational challenges of operating a system that is critical for a messaging app used by billions of people around the world.   </p><p>We’ve also done this before — in 2022, Cloudflare announced <a href="https://blog.cloudflare.com/cloudflare-verifies-code-whatsapp-web-serves-users/"><u>Code Verify</u></a>, a partnership in which we verify that the code delivered in the browser for <a href="https://web.whatsapp.com/"><u>WhatsApp Web</u></a> has not been tampered with. When users run WhatsApp in their browser, the <a href="https://faq.whatsapp.com/639766781216714?cms_platform=web&amp;helpref=faq_content"><u>WhatsApp Code Verify extension</u></a> compares a hash of the code that is executing in the browser with the hash that Cloudflare has of the codebase, enabling WhatsApp web users to easily see whether the code that is executing is the code that was publicly committed to. </p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/451BUpYOdkMZ9KqtGKBbFQ/69edee8fe9e64d124b16908a95bf0933/Code_Verify_-_Blog.png" />
            
            </figure><p><sup><i>In Code Verify, Cloudflare builds a non-mutable chain associating the WhatsApp version with the hash of its code.</i></sup></p><p>Cloudflare’s role in Key Transparency is similar in that we are checking that a tree-based directory of public keys (more on this later) has been constructed correctly, and has been done so consistently over time.</p>
    <div>
      <h2>How Key Transparency works</h2>
      <a href="#how-key-transparency-works">
        
      </a>
    </div>
    <p>The architectural foundation of Key Transparency is the <a href="https://github.com/facebook/akd/"><u>Auditable Key Directory (AKD)</u></a>: a tree-shaped data structure, constructed and maintained by WhatsApp, in which the nodes contain hashed contact details of each user. We’ll explain the basics here but if you’re interested in learning more, check out the <a href="https://eprint.iacr.org/2018/607.pdf"><u>SEEMless</u></a> and <a href="https://eprint.iacr.org/2023/081.pdf"><u>Parakeet</u></a> papers.</p><p>The AKD tree is constructed by building a binary tree, each parent node of which is a hash of each of its left and right child nodes:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5Dl16PIqBNBiKn6qhzanCU/b67a1128bef4ab8733337f720c53f160/Mini_tree_-_Blog.png" />
            
            </figure><p><sup><i>Each child node on the tree contains contact and public key details for a user (shown here for illustrative purposes). In reality, Cloudflare only sees a hash of each node rather than Alice and Bob’s contact info in plaintext.</i></sup></p><p>An epoch describes a specific version of the tree at a given moment in time, identified by its root node. Using a structure similar to Code Verify, the WhatsApp Log stores each root node hash as part of an append-only time structure of updates.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/43FGTWfTV2aIaaMkfyplY2/8576b9c096bead64ede52a034481149b/Key_Transparency_combined_tree_-_Blog.png" />
            
            </figure><p>What kind of changes are valid to be included in a given epoch? When a new person, Brian, joins WhatsApp, WhatsApp inserts a new “B” node in the AKD tree, and a new epoch. If Alice loses her phone and rotates her key, her “version” is updated to <code>v1</code> in the next update.  </p>
    <div>
      <h2>How we built the Auditor on Cloudflare Workers </h2>
      <a href="#how-we-built-the-auditor-on-cloudflare-workers">
        
      </a>
    </div>
    <p>The role of the Auditor is to provide two main guarantees: that epochs are globally unique, and that they are valid. They are, however, quite different: global uniqueness requires consistency on whether an epoch and its associated root hash has been seen, while validity is a matter of computation — is the transition from the previous epoch to the current one a correct tree transformation?</p>
    <div>
      <h3>Timestamping service</h3>
      <a href="#timestamping-service">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5QHtfUaKoIBcIcK5o6H53j/ebaa147f3b22de32a29754d3cd7e73bd/Key_Transparency_Auditor_3_.png" />
            
            </figure><p><sup><i>Timestamping service architecture (Cloudflare Workers in Rust, using a Durable Object for storage)</i></sup></p><p>At regular intervals, the WhatsApp Log puts all new updates into the tree, and cuts a new epoch in the format “{counter}/{previous}/{current}”. The counter is a number, whereby “previous” is a hexadecimal encoded hash of the previous tree root, and “current” is a hexadecimal encoded hash for the new tree root. As a shorthand, epochs can be referred to by their counter only.</p><p>Here’s an example:</p><p><code>1001/d0bbf29c48716f26a951ae2a244eb1d070ee38865c29c8ad8174e8904e3cdc1a/e1006114485e8f0bbe2464e0ebac77af37bce76851745592e8dd5991ff2cd411</code></p><p>Once an epoch is constructed, the WhatsApp Log sends it to the Auditor for cross-signing, to ensure it has only been seen once. The Auditor adds a timestamp as to when this new epoch has been seen. Cloudflare’s Auditor uses a <a href="https://developers.cloudflare.com/durable-objects/platform/known-issues/#global-uniqueness"><u>Durable Object</u></a> for every epoch to create their timestamp. This guarantees the global uniqueness of an epoch, and the possibility of replay in the event the WhatsApp Log experiences an outage or is distributed across multiple locations. WhatsApp’s Log is expected to produce new epochs at regular intervals, given this constrains the propagation of public key updates seen by their users. Therefore, Cloudflare Auditor does not have to keep the durable object state forever. Once replay and consistency have been accounted for, this state is cleared. This is done after a month, thanks to durable object <a href="https://developers.cloudflare.com/durable-objects/api/alarms/"><u>alarms</u></a>.</p><p>Additional checks are performed by the service, such as checking that the epochs are consecutive, or that their digest is unique. This enforces a chain of epochs and their associated digests, provided by the WhatsApp Log and signed by the Auditor, providing a consistent view for all to see.</p><p>We decided to write this service in Rust because Workers rely on <a href="https://github.com/cloudflare/workers-rs"><u>cloudflare/workers-rs</u></a> bindings, and the auditable key directory library is also in Rust (<a href="https://github.com/facebook/akd"><u>facebook/akd</u></a>).</p>
    <div>
      <h3>Tree validation service</h3>
      <a href="#tree-validation-service">
        
      </a>
    </div>
    <p>With the timestamping service above, WhatsApp users (as well as their Log) have assurance that epochs are transparent. WhatsApp’s directory can be audited at any point in time, and if it were to be tampered with by WhatsApp or an intermediary, the WhatsApp Log can be held accountable for it.</p><p>Epochs and their digests are only representations of their underlying key directory. To fully audit the directory, the transition from the previous digest to a current digest has to be validated. To perform validation, we need to run the epoch validation method. Specifically, we want to run <a href="https://github.com/facebook/akd/blob/fcd665aa20f829cd9e06cb3d70cbe0c32ffe6b67/akd/src/auditor.rs#L56"><u>verify_consecutive_append_only</u></a> on every epoch constructed by the Log. The size of an epoch varies with the number of updates it contains, and therefore the number of associated nodes in the tree to construct as well. While Workers are able to run such validation for a small number of updates, this is a compute-intensive task. Therefore, still leveraging the same Rust codebase, the Auditor leverages a container that only performs the tree construction and validation. The Auditor retrieves the updates for a given epoch, copies them into its own R2 bucket, and delegates the validation to a <a href="https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler/src/cloudchamber"><u>container</u></a> running on Cloudflare. Once validated, the epoch is marked as verified.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5fNbebayPfLZPn4pEIoWpP/b8d2da4ac9867aeb44e9e1ff52405be9/Key_Transparency_Auditor_4_.png" />
            
            </figure><p><sup><i>Architecture for Cloudflare’s Plexi Auditor. The proof verification and signatures stored do not contain personally identifiable information such as your phone number, public key, or other metadata tied to your WhatsApp account.</i></sup></p><p>This decouples global uniqueness requirements and epoch validation, which happens at two distinct times. It allows the validation to take more time, and not be latency sensitive.</p>
    <div>
      <h2>How can I verify Cloudflare has signed an epoch?</h2>
      <a href="#how-can-i-verify-cloudflare-has-signed-an-epoch">
        
      </a>
    </div>
    <p>Anyone can perform audit proof verification — <a href="https://dash.key-transparency.cloudflare.com"><u>the proofs are publicly available</u></a> — but Cloudflare will be doing so automatically and publicly to make the results accessible to all. Verify that Cloudflare’s signature matches WhatsApp’s by visiting our <a href="https://dash.key-transparency.cloudflare.com"><u>Key Transparency website</u></a>, or via our <a href="https://github.com/cloudflare/plexi"><u>command line</u></a> tool.</p><p>To use our command line tool, you’ll need to download the <a href="https://github.com/cloudflare/plexi"><u>plexi</u></a> client. It helps construct data structures which are used for signatures, and requires you to have git and cargo installed.</p>
            <pre><code>cargo install plexi</code></pre>
            <p>With the client installed, let’s now check the audit proofs for WhatsApp namespace: <code>whatsapp.key-transparency.v1</code>. Plexi Auditor is represented by one public key, which can verify and vouch for multiple Logs with their own dedicated “namespace.” To validate an epoch, such as epoch 458298 (the epoch at which the log decided to start sharing data), you can run the following command:</p>
            <pre><code>plexi audit --remote-url 'https://akd-auditor.cloudflare.com' --namespace 'whatsapp.key-transparency.v1' --long
Namespace
  Name              	: whatsapp.key-transparency.v1
  Ciphersuite       	: ed25519(protobuf)

Signature (2024-09-23T16:53:45Z)
  Epoch height      	: 489193
  Epoch digest      	: cbe5097ae832a3ae51ad866104ffd4aa1f7479e873fd18df9cb96a02fc91ebfe
  Signature         	: fe94973e19da826487b637c019d3ce52f0c08093ada00b4fe6563e2f8117b4345121342bc33aae249be47979dfe704478e2c18aed86e674df9f934b718949c08
  Signature verification: success
  Proof verification	: success</code></pre>
            
    <div>
      <h2>Interested in having Cloudflare audit your public key infrastructure?</h2>
      <a href="#interested-in-having-cloudflare-audit-your-public-key-infrastructure">
        
      </a>
    </div>
    <p>At the end of the day, security threats shouldn’t become usability problems — everyday messaging app users shouldn’t have to worry about whether the public keys of the people they’re talking to have been compromised. In the same way that <a href="https://ct.cloudflare.com/"><u>certificate transparency</u></a> is now built into the issuance and use of digital certificates to encrypt web traffic, we think that public key transparency and auditing should be built into end-to-end encrypted systems by default, so that users never have to do manual QR code verification again. </p><p>We built our auditing service to be general purpose, reliable, and fast, and WhatsApp’s Key Transparency is just the first of several use cases it will be used for – Cloudflare is interested in helping audit the delivery of code binaries and integrity of all types of end-to-end encrypted infrastructure. If your company or organization is interested in working with us, you can <a href="https://www.cloudflare.com/lp/privacy-edge/"><u>reach out to us here</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">4tzeNEI3qyBtnWskn5TbUa</guid>
            <dc:creator>Thibault Meunier</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Privacy-preserving measurement and machine learning]]></title>
            <link>https://blog.cloudflare.com/deep-dive-privacy-preserving-measurement/</link>
            <pubDate>Fri, 29 Sep 2023 13:00:45 GMT</pubDate>
            <description><![CDATA[ Cloudflare is implementing DAP (Distributed Aggregation Protocol) – a way of aggregating data without exposing individual measurements that uses  multi-party computation ]]></description>
            <content:encoded><![CDATA[ <p></p><p>In 2023, data-driven approaches to making decisions are the norm. We use data for everything from analyzing x-rays to translating thousands of languages to directing autonomous cars. However, when it comes to building these systems, the conventional approach has been to collect as much data as possible, and worry about privacy as an afterthought.</p><p>The problem is, data can be sensitive and used to identify individuals – even when explicit <a href="https://dataprivacylab.org/projects/identifiability/paper1.pdf">identifiers are removed</a> or noise is added.</p><p>Cloudflare Research has been interested in exploring different approaches to this question: is there a <i>truly private</i> way to perform data collection, especially for some of the most sensitive (but incredibly useful!) technology?</p><p>Some of the use cases we’re thinking about include: training federated <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning models</a> for predictive keyboards without collecting every user’s keystrokes; performing <a href="https://www.census.gov/data/academy/webinars/2021/disclosure-avoidance-series/simulated-reconstruction-abetted-re-identification-attack-on-the-2010-census.html">a census</a> without storing data about individuals’ responses; <a href="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">providing healthcare authorities with data about COVID-19 exposures without tracking peoples’ locations en masse</a>; figuring out the most common errors browsers are experiencing without reporting which websites are visiting.  </p><p>It’s with those use cases in mind that we’ve been participating in the Privacy Preserving Measurement <a href="https://datatracker.ietf.org/group/ppm/about/">working group at the IETF</a> whose goal is to develop systems for collecting and using this data while minimizing the amount of per-user information exposed to the data collector.</p><p>So far, the most promising standard in this space is <a href="https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/">DAP – Distributed Aggregation Protocol</a> – a clever way to use <a href="https://en.wikipedia.org/wiki/Secure_multi-party_computation">multi-party computation</a> to aggregate data without exposing individual measurements. Early versions of the algorithms used by DAP have been implemented by Google and Apple for <a href="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">exposure notifications</a>.</p><p>In this blog post, we’ll do a deep dive into the fundamental concepts behind the DAP protocol and give an example of how we’ve implemented it into <a href="https://github.com/cloudflare/daphne">Daphne</a>, our open source aggregator server. We hope this will inspire others to collaborate with us and get involved in this space!</p>
    <div>
      <h3>The principles behind DAP, an open standard for privacy preserving measurement</h3>
      <a href="#the-principles-behind-dap-an-open-standard-for-privacy-preserving-measurement">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Y8EEQM4c3MgIDKhYnp09B/c7626358f569efcd509c4571ff3fc409/MAnxtCSIuR-Y9c_2OkGchGPEHA_U4feb9db_mXD1BOWpc5cMy25ggAgcGg_Ir-8lkU6kCXkLIyq8M25cxxBmPksZL1EIrlsHErLD7rpZXvMxnRdeLmWdavhLIGww.png" />
            
            </figure><p>At a high level, using the DAP protocol forces us to think in terms of <i>data minimization</i><b>:</b> collect only the data that we use and nothing more. Abstractly, our goal is to devise a system with which a data collector can compute some function \( f(m_{1},...,m_{N}) \) of measurements \( m_{1},...,m_{N} \) uploaded by users without observing the measurements in the clear.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/qDmuIUgKzPXskT39UdfKf/17309b04fd740935c53fe01be8f4b11c/image12-3.png" />
            
            </figure><p><i>Alice wants to know some aggregate statistic – like the average salary of the people at the party – without knowing how much each individual person makes.</i></p><p>This may at first seem like an impossible task: to compute on data without knowing the data we're computing on. Nevertheless, —and, as is often the case in cryptography— once we've properly constrained the problem, solutions begin to emerge.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nMLQ0GblS8fPnWGtfm2oM/36cc8266ab7f74a7240d3aa266d26790/image9-2.png" />
            
            </figure><p><i>Strawperson solution: delegate the calculation to a trusted third party, Bob. The problem with this is that Bob can see the private inputs in the clear</i></p><p>In an ideal world (see above), there would be some server somewhere on the Internet that we could trust to consume measurements, aggregate them, and send the result to the data collector without ever disclosing anything else. However, in reality there's no reason for users to trust such a server more than the data collector; Indeed, both are subject to the usual assortment of attacks that can lead to a data breach.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6axqzCL6WF50qNFJu3qMT5/3781cd288e80cd53be27ad090ad52082/image1-42.png" />
            
            </figure><p>_MPC solution: secret-share the inputs across multiple parties, a.k.a. Bob and Daphne. If at least one person is honest, Alice gets the aggregate result without anyone knowing individual inputs in the clear._‌ ‌</p><p>Instead, what we do in DAP is <i>distribute</i> the computation across the servers such that no single server has a complete measurement. The key idea that makes this possible is <i>secret sharing</i>.</p>
    <div>
      <h2>Computing on secret shared data</h2>
      <a href="#computing-on-secret-shared-data">
        
      </a>
    </div>
    <p>To set things up, let's make the problem a little more concrete. Suppose each measurement \( m_{i} \) is a number and our goal is to compute the sum of the measurements. That is, \( f(m_{1},...,m_{N}) = m_{1} + \cdots + m_{N} \). Our goal is to use secret sharing to allow two servers, which we'll call <i>aggregators</i>, to jointly compute this sum.</p><p>To understand secret sharing, we're going to need a tiny bit of math—modular arithmetic. The expression \(  X + Y  (\textrm{mod})  \textit{q} \) means "add \(  X  \) and \(  Y  \), then divide the sum by \(  q  \) and return the remainder". For now the modulus \(  q  \) can be any large number, as long as it's larger than any sum we'd ever want to compute (\(  2 ^{64}  \), say). In the remainder of this section, we'll omit \(  q  \) and simply write \(  X  + Y \) for addition modulo \(  q  \).</p><p>The goal of secret sharing is to shard a measurement (i.e., a "secret") into two "shares" such that (i) the measurement can be recovered by combining the shares together and (ii) neither share leaks any information about the measurement. To secret share each \(  m_{i} \), we choose a random number \( R_{i} \in \lbrace  0,...,q - 1\rbrace \), set the first share to be \(X_{i} = m_{i} - R_{i} \) and set the other share to be \( Y_{i} = R_{i} \). To recover the measurement, we simply add the shares together. This works because \( X_{i} + Y_{i} = (m_{i} - R_{i}) + R_{i} = m_{i} \). Moreover, each share is indistinguishable from a random number: For example, \( 1337 \) might be secret-shared into \( 11419752798245067454 \) and \( 7026991275464485499 \) (modulo \( q = 2^{64} \)).</p><p>With this scheme we can devise a simple protocol for securely computing the sum:</p><ol><li><p>Each client shards its measurement \( m_{i} \) into \( X_{i} \) and \( Y_{i} \) and sends one share to each server.</p></li><li><p>The first aggregator computes \( X = X_{1} + \cdots + X_{N} \) and reveals \( X \) to the data collector. The second aggregator computes \( Y = Y_{1} + \cdots + Y_{N} \) and reveals \( Y \) to the data collector.</p></li><li><p>The data collector unshards the result as \( r = X + Y \).</p></li></ol><p>This works because the secret shares are additive, and the order in which we add things up is irrelevant to the function we're computing:</p><p>\( r = m_{1} + \cdots + m_{N} \) // by definition\( r = (m_{1} - R_{1}) + R_{1} + \cdots (m_{N} - R_{N}) + R_{N} \) // apply sharding\( r = (m_{1} - R_{1}) + \cdots + (m_{N} - R_{N}) + R_{1} + \cdots R_{N} \) // rearrange the sum\( r = X + Y \) // apply aggregation</p>
    <div>
      <h3>Rich data types</h3>
      <a href="#rich-data-types">
        
      </a>
    </div>
    <p>This basic template for secure aggregation was described in a paper from Henry Corrigan-Gibbs and Dan Boneh called <a href="https://www.usenix.org/conference/nsdi17/technical-sessions/presentation/corrigan-gibbs">"Prio: Private, Robust, and Scalable Computation of Aggregate Statistics"</a> (NSDI 2017). This paper is a critical milestone in DAP's history, as it showed that a wide variety of aggregation tasks (not just sums) can be solved within one, simple protocol framework, Prio. With DAP, our goal in large part is to bring this framework to life.</p><p>All Prio tasks are instances of the same template. Measurements are encoded in a form that allows the aggregation function to be expressed as the sum of (shares of) the encoded measurements. For example:</p><ol><li><p>To get arithmetic mean, we just divide the sum by the number of measurements.</p></li><li><p>Variance and standard deviation can be expressed as a linear function of the sum and the sum of squares (i.e., \( m_{i}, m_{i}^{2} \) for each \( i \)).</p></li><li><p>Quantiles (e.g., median) can be estimated reasonably well by mapping the measurements into buckets and aggregating the histogram.</p></li><li><p>Linear regression (i.e., finding a line of best fit through a set of data points) is a bit more complicated, but can also be expressed in the Prio framework.</p></li></ol><p>This degree of flexibility is essential for wide-spread adoption because it allows us to get the most value we can out of a relatively small amount of software. However, there are a couple problems we still need to overcome, both of which entail the need for some form of interaction.</p>
    <div>
      <h3>Input validation</h3>
      <a href="#input-validation">
        
      </a>
    </div>
    <p>The first problem is <i>input validation</i>. Software engineers, especially those of us who operate web services, know in our bones that validating inputs we get from clients is of paramount importance. (Never, <i>ever</i> stick a raw input you got from a client into an SQL query!) But if the inputs are secret shared, then there is no way for an aggregator to discern even a single bit of the measurement, let alone check that it has an expected value. (A secret share of a valid measurement and a number sampled randomly from \( \lbrace 0,...,q - 1 \rbrace \) look identical.) At least, not on its own.</p><p>The solution adopted by Prio (and the <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/">standard</a>, with some improvements), is a special kind of <a href="/introducing-zero-knowledge-proofs-for-private-web-attestation-with-cross-multi-vendor-hardware/"><i>zero-knowledge proof (ZKP)</i> system</a> designed to operate on secret shared data. The goal is for a prover to convince a verifier that a statement about some data it has committed to is true (e.g., the user has a valid hardware key), without revealing the data itself (e.g. which hardware key is in-use).</p><p>Our setting is exactly the same, except that we're working on secret-shared data rather than committed data. Along with the measurement shares, the client sends shares of a validity proof; then during aggregation, the aggregators interact with one another in order to check and verify the proof. (One round-trip over the network is required.)</p><p>A happy consequence of working with secret shared data is that proof generation and verification are much faster than for committed (or encrypted) data. This is mainly because we avoid the use of public-key cryptography (i.e., <a href="/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/">elliptic curves</a>) and are less constrained in how we choose cryptographic parameters. (We require the modulus \( q \) to be a prime number with a particular structure, but such primes are not hard to find.)</p>
    <div>
      <h3>Non-linear aggregation</h3>
      <a href="#non-linear-aggregation">
        
      </a>
    </div>
    <p>There are a variety of aggregation tasks for which Prio is not well-suited, in particular those that are non-linear. One such task is to find the "heavy hitters" among the set of measurements. The heavy hitters are the subset of the measurements that occur most frequently, say at least \( t \) times for some threshold \( t \). For example, the measurements might be the URLs visited on a given day by users of a web browser; the heavy hitters would be the set of URLs that were visited by at least \( t \) users.</p><p>This computation can be expressed as a simple program:</p>
            <pre><code>def heavy_hitters(measurements: list[bytes], t: int) -&gt; set[bytes]:
    hh = defaultdict(lambda: 0)
    for measurement in measurements:
        hh[measurement] += 1
    return set(map(lambda x: x[0], filter(lambda x: x[1] &gt;= t, hh.items())))</code></pre>
            <p>However, it cannot be expressed as a linear function, at least not efficiently (with sub-exponential space). This would be required to perform this computation on secret-shared measurements.</p><p>In order to enable non-linear computation on secret shared data, it is necessary to introduce some form of interaction. There are a few possibilities. For the heavy hitters problem in particular, Henry Corrigan-Gibbs and others devised a protocol called <a href="https://ieeexplore.ieee.org/document/9519492">Poplar</a> (IEEE Security &amp; Privacy 2021) in which several rounds of aggregation and unsharding are performed, where in each round, information provided by the collector is used to "query" the measurements to obtain a refined aggregate result.</p>
    <div>
      <h3>Helping to build a world of multi-party computation</h3>
      <a href="#helping-to-build-a-world-of-multi-party-computation">
        
      </a>
    </div>
    <p>Protocols like Prio or Poplar that enable computation over secret shared data fit into a rich tradition in cryptography known as <i>multi-party computation (MPC)</i>. MPC is at once an active research area in theoretical computer science and a class of protocols that are beginning to see real-world use—in our case, to minimize the amount of privacy-sensitive information we collect in order to keep the Internet moving.</p><p>The PPM working group at IETF represents a significant effort, by Cloudflare and others, to standardize MPC techniques for privacy preserving measurement. This work has three main prongs:</p><ol><li><p>To identify the types of problems that need to be solved.</p></li><li><p>To provide cryptography researchers from academia, industry, and the public sector with "templates" for solutions that we know how to deploy. One such template is called a <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/">"Verifiable Distributed Aggregation Function (VDAF)"</a>, which specifies a kind of "API boundary" between protocols like Prio and Poplar and the systems that are built around them. Cloudflare Research is leading development of the standard, contributing to <a href="https://github.com/divviup/libprio-rs">implementations</a>, and providing <a href="https://petsymposium.org/popets/2023/popets-2023-0126.pdf">security analysis</a>.</p></li><li><p>To provide a deployment roadmap for emerging protocols. <a href="https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/">DAP</a> is one such roadmap: it specifies execution of a generic VDAF over HTTPS and attends to the various operational considerations that arise as deployments progress. As well as contributing to the standard itself, Cloudflare has developed its own implementation designed for our own infrastructure (see below).</p></li></ol><p>The IETF is working on its first set of drafts (DAP/VDAF). These drafts are mature enough to deploy, and a number of deployments are scaling up as we speak. Our hope is that we have initiated positive feedback between theorists and practitioners: as new cryptographic techniques emerge, more practitioners will begin to work with them, which will lead to identifying new problems to solve, leading to new techniques, and so on.</p>
    <div>
      <h3>Daphne: Cloudflare’s implementation of a DAP Aggregation Server</h3>
      <a href="#daphne-cloudflares-implementation-of-a-dap-aggregation-server">
        
      </a>
    </div>
    <p>Our emerging technology group has been working on <a href="https://github.com/cloudflare/daphne">Daphne</a>, our Rust-based implementation of a DAP aggregator server. This is only half of a deployment – DAP architecture requires two aggregator servers to interoperate, both operated by different parties. Our current version only implements the DAP Helper role; the other role is the DAP Leader. Plans are in the works to implement the Leader as well, which will open us up to deploy Daphne for more use cases.</p><p>We made two big decisions in our implementation here: using Rust and using Workers. Rust has been skyrocketing in popularity in the past few years due to its performance and memory management – a favorite of cryptographers for similar reasons. <a href="https://workers.cloudflare.com/">Workers</a> is Cloudflare’s serverless execution environment that allows developers to easily deploy applications globally across our network – making it a favorite tool to prototype with at Cloudflare. This allows for easy integration with our Workers-based storage solutions like: <a href="https://developers.cloudflare.com/durable-objects/">Durable Objects</a>, which we’re using for storing various data artifacts as required by the DAP protocol; and <a href="https://www.cloudflare.com/developer-platform/workers-kv/">KV</a>, which we’re using for managing aggregation task configuration. We’ve learned a lot from our interop tests and deployment, which has helped improve our own Workers products and which we have also fed back into the PPM working group to help improve the DAP standard.</p><p>If you’re interested in learning more about Daphne or collaborating with us in this space, you can fill out <a href="https://www.cloudflare.com/lp/privacy-edge/">this form</a>. If you’d like to get involved in the DAP standard, you can check out the <a href="https://datatracker.ietf.org/wg/ppm/about/">working group</a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">2vQ2io72Fczi8H9Eh8HrWF</guid>
            <dc:creator>Christopher Patton</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare is now powering Microsoft Edge Secure Network]]></title>
            <link>https://blog.cloudflare.com/cloudflare-now-powering-microsoft-edge-secure-network/</link>
            <pubDate>Thu, 28 Sep 2023 13:00:30 GMT</pubDate>
            <description><![CDATA[ This integration will allow Microsoft Edge users who opt in to browse the Internet more privately, without being tracked across websites ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6FhPoKR9MPEZo0pbUSvp9L/7306503100e3ca940237488c05e2be14/image1-35.png" />
            
            </figure><p>Between <a href="https://www.cloudflare.com/learning/privacy/what-are-cookies/">third-party cookies</a> that track your activity across websites, to highly targeted advertising based on <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-my-ip-address/">your IP address</a> and browsing data, it's no secret that today’s Internet browsing experience isn’t as private as it should be. Here at Cloudflare, we believe everyone should be able to browse the Internet free of persistent tracking and prying eyes.</p><p>That’s why we’re excited to announce that we’ve partnered with Microsoft Edge to provide a fast and secure VPN, right in the browser. Users don’t have to install anything new or understand complex concepts to get the latest in network-level privacy: Edge Secure Network VPN is available on the latest consumer version of Microsoft Edge in most markets, and automatically comes with 5 GB of data. Just enable the feature by going to <i>[Microsoft Edge Settings &amp; more (…) &gt; Browser essentials,</i> and click <i>Get VPN for free]</i>. See Microsoft’s <a href="https://www.microsoft.com/en-us/edge/features/edge-secure-network-vpn?form=MT00D8">Edge Secure Network page</a> for more details.</p>
    <div>
      <h3>Cloudflare’s Privacy Proxy platform isn’t your typical VPN</h3>
      <a href="#cloudflares-privacy-proxy-platform-isnt-your-typical-vpn">
        
      </a>
    </div>
    <p>To take a step back: a VPN is a way in which the Internet traffic leaving your device is tunneled through an intermediary server operated by a provider – in this case, Cloudflare! There are many important pieces that make this possible, but among them is the VPN protocol, which defines the way in which the tunnel is established and how traffic flows through it. You may have heard of some of these protocols: Wireguard, IPsec, and OpenVPN, for example. And while we’re no stranger to these, (Cloudflare’s WireGuard implementation is currently in use by millions of devices that use <a href="/1111-warp-better-vpn/">1.1.1.1+WARP</a>) – we see our Privacy Proxy Platform as a way to push forward the next frontier of Internet privacy and embrace one of Cloudflare’s core values: open Internet standards.</p><p>The Privacy Proxy Platform implements HTTP CONNECT, a method defined in the <a href="https://www.cloudflare.com/learning/ddos/glossary/hypertext-transfer-protocol-http/">HTTP standard</a> that proxies traffic by establishing a tunnel and then sending reliable and ordered byte streams through that tunnel. You can read more about this proxying method (and its history!) in our <a href="/a-primer-on-proxies/">Primer on Proxies</a>.</p><p>We also leverage other parts of Cloudflare’s privacy-oriented infrastructure that are already deployed at scale: requests first utilize <a href="https://1.1.1.1/dns/">1.1.1.1</a> for DNS, a token proxy based on <a href="https://datatracker.ietf.org/wg/privacypass/about/">Privacy Pass</a> for client authentication, and <a href="/geoexit-improving-warp-user-experience-larger-network/">Geo-egress</a> to choose an accurate egress IP address without exposing users’ precise location.</p>
    <div>
      <h3>How it works</h3>
      <a href="#how-it-works">
        
      </a>
    </div>
    <p>Let’s dive into the details of these components. For the purposes of this blog, we’ll call the devices people are using to browse the Internet (your phone, tablet or computer) <i>clients,</i> and the websites they’re trying to visit <i>origin sites.</i></p><p>The Privacy Proxy Platform includes three main parts:</p><ol><li><p><b>Token Proxy</b>: this is the service that checks if you’re an Edge Secure Network user with a legitimate Microsoft account.</p></li><li><p><b>Privacy API</b>: based on the above, Cloudflare’s Privacy API issues authentication tokens that clients use for authenticating to the proxy itself.</p></li><li><p><b>Privacy Proxy</b>: this is the HTTP CONNECT-based proxy service running on Cloudflare’s network. This service checks that the client presents a valid authentication token, and if so, proxies the encrypted HTTP request to the origin site. It is also responsible for selecting a valid egress IP address to be used.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4Ct0FCenirtxHz2Hg5ZjLK/c6fa499c3ab95ba3cd1abbf7cb11b1a4/image2-24.png" />
            
            </figure><p>When Edge Secure Network protections are on – say, when a user connects to an open Wi-Fi network at a coffee shop – our proxy will automatically prompt that client for a token to authenticate. If the client has a token, it will present one. If it doesn’t, it will utilize the token proxy to mint a new pool using the help of an attester and issuer: the attester checks the validity of the client and Microsoft account, and the issuer issues tokens for that client in return. This dance is based on the <a href="/supporting-the-latest-version-of-the-privacy-pass-protocol/">Privacy Pass protocol</a>. Importantly, it allows Cloudflare to validate that clients are who they say they are without collecting or storing personal information from Microsoft users.</p><p>Once the client has presented the proxy server with a valid token, the Privacy Proxy then chooses a valid egress IP address based on a hash of the client’s geolocation. It then uses the <a href="https://www.cloudflare.com/learning/dns/dns-records/">DNS record</a> (provided by Cloudflare’s DNS resolver, <a href="https://1.1.1.1/">1.1.1.1</a>) to open up an encrypted session to the origin website. From there, it’s pretty straightforward: if the user continues to browse on that site, further requests will be sent through that connection, if they stop or close the browser, that connection will close as well.</p><p>Because Cloudflare proxies millions of requests per second, many of the operational aspects of the proxy are managed by <a href="/introducing-oxy/">Oxy</a>, our proxying framework that handles everything from telemetry, graceful restarts, to stream multiplexing and IP fallbacks, and authentication <a href="/oxy-extensibility/">hooks</a>.</p>
    <div>
      <h3>Low last-mile latency and geolocation parity thanks to Cloudflare’s Network</h3>
      <a href="#low-last-mile-latency-and-geolocation-parity-thanks-to-cloudflares-network">
        
      </a>
    </div>
    <p>Cloudflare’s privacy proxy implementation maximizes user experience without sacrificing privacy. When Edge Secure Network is enabled, users will have search and browsing results relevant to where they’re geographically located. At Cloudflare, we call this the pizza test: people should be able to use any of our privacy proxy products and still be able to get results for “<i>pizza places near me</i>”. We accomplish this by always egressing through a Cloudflare data center that has an IP address that corresponds to the user’s location – we’ve written more about how we did this for <a href="/geoexit-improving-warp-user-experience-larger-network/">1.1.1.1+WARP</a>.</p><p>Unlike your typical <a href="https://www.cloudflare.com/learning/access-management/what-is-a-vpn/">VPN</a> operator that has dozens – sometimes hundreds – of servers, Cloudflare has a much larger footprint: data centers in <a href="http://cloudflare.com/network">over 300 cities</a>. Because our network is an anycast “every service, everywhere” approach, each of our data centers can accept traffic from an Edge Secure network client. This means that Edge users will automatically detect and connect with a Cloudflare data center geographically very close to them, minimizing last-mile <a href="https://www.cloudflare.com/learning/performance/glossary/what-is-latency/">latency</a>. Finally, because Cloudflare also operates a <a href="https://www.cloudflare.com/application-services/products/cdn/">CDN</a>, websites that are already on Cloudflare will be given a “hot-path,” and will load faster.</p><p>We at Cloudflare are always striving to bring more privacy options to the open Internet, and we are excited to provide more private and secure browsing to Edge users. To learn more, head to <a href="https://www.microsoft.com/en-us/edge/features/edge-secure-network-vpn">Microsoft’s Edge Secure Network page</a> or <a href="https://support.microsoft.com/en-us/topic/use-the-microsoft-edge-secure-network-to-protect-your-browsing-885472e2-7847-4d89-befb-c80d3dda6318">Microsoft’s support page</a>. If you’re a partner interested in using a privacy-preserving proxy like this one, fill out <a href="https://www.cloudflare.com/lp/privacy-edge/">this form</a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Privacy]]></category>
            <guid isPermaLink="false">4SM38VnUUQdYfz0iQopzuV</guid>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Donning a MASQUE: building a new protocol into Cloudflare WARP]]></title>
            <link>https://blog.cloudflare.com/masque-building-a-new-protocol-into-cloudflare-warp/</link>
            <pubDate>Thu, 22 Jun 2023 13:00:02 GMT</pubDate>
            <description><![CDATA[ Announcing support for MASQUE, a cutting-edge new protocol for the beta version of our consumer WARP iOS app ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4OlWeYxXy94qT4DdzZNPeO/8a8146649f9cb850ed933cadeb6deb70/image2-22.png" />
            
            </figure><p>When we originally <a href="/announcing-warp-plus/">announced</a> WARP, we knew we were launching a product that was different from other VPNs. Cloudflare has not only hundreds more <a href="https://www.cloudflare.com/network/">data centers</a> than your typical VPN provider, but also a unique purview into the adoption of open <a href="/http3-the-past-present-and-future/">Internet standards</a>. The confluence of these two factors have led us to today’s announcement: support for MASQUE, a cutting-edge new protocol for the beta version of our consumer WARP iOS app.</p><p><a href="https://datatracker.ietf.org/wg/masque/about/">MASQUE</a> is a set of mechanisms that extend HTTP/3 and leverage the <a href="/unlocking-quic-proxying-potential/">unique properties</a> of the QUIC transport protocol to efficiently proxy IP and UDP traffic. Most importantly, it will make your Internet browsing experience faster and more stable without sacrificing privacy.</p><p>Like many products at Cloudflare, we’re offering this first as a free, consumer offering. Once we’ve had an opportunity to learn from what it’s like to operate MASQUE on mobile devices, at scale, we plan to integrate it into our <a href="https://www.cloudflare.com/zero-trust/">Zero Trust</a> enterprise product suite.</p>
    <div>
      <h3>We’re not saying goodbye to WireGuard</h3>
      <a href="#were-not-saying-goodbye-to-wireguard">
        
      </a>
    </div>
    <p>When we first built WARP we chose to go with WireGuard for many reasons – among them, simplicity. This is where WireGuard shines: ~4,000 lines of code that use public-key cryptography to create an encrypted tunnel between one computer and another. The cryptographic parts – encapsulation and decapsulation –  are fast, simple, and secure. This simplicity has allowed us to implement it cross-platform without much effort; today, we support <a href="https://developers.cloudflare.com/warp-client/">WireGuard clients</a> on iOS, Android, macOS, Windows, and Linux.</p><p>That being said, the protocol is not without its issues. Like many tradeoffs in technology, WireGuard’s strengths are also its drawbacks. While simple, it is also rigid: it’s not possible to extend it easily, for example, for session management, congestion control, or to recover more quickly from error-state behaviors we’re familiar with. Finally, neither the protocol nor the cryptography it uses are standards-based, making it difficult to keep up with the strongest known cryptography (<a href="/post-quantum-for-all/">post-quantum crypto</a>, for example).</p>
    <div>
      <h3>We want to move QUIC-ly</h3>
      <a href="#we-want-to-move-quic-ly">
        
      </a>
    </div>
    <p>We’re excited about MASQUE because it fits into the way the Internet is evolving. According to this year’s <a href="/http3-usage-one-year-on/">usage report from our Radar team</a>, HTTP/2 is currently the standard in use by the majority of Internet traffic, but HTTP/3 occupies a growing share – 28% as of June 2023. Cloudflare has always been dedicated towards adopting the cutting edge when it comes to standards: when RFC 9000 (the QUIC transport protocol) was published, we enabled it for all Cloudflare customers <a href="/quic-version-1-is-live-on-cloudflare/">the very next day</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/28cLqfK5SWtF4rPfghCg5C/968adb4b97779bf8268e786caf40c97f/image4-17.png" />
            
            </figure><p>So why do we think <a href="https://www.cloudflare.com/learning/performance/what-is-http3/">HTTP/3</a> is so promising? Well, a lot of it has to do with solving performance issues with HTTP/2. HTTP/3 promises a number of things.</p><p>Faster connection establishment: the TCP+TLS handshake of earlier HTTP versions typically takes two to three <a href="https://blog.chromium.org/2015/04/a-quic-update-on-googles-experimental.html">round trips</a>. QUIC performs the transport and security handshake at the same time, cutting down on the total required round trips.</p><p>No more <a href="https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/">head of line blocking</a>: when one packet of information does not make it to its destination, it will no longer block all streams of information.</p><p>Agility and evolution: QUIC has strong extension and version negotiation mechanisms. And because it encrypts all but a few bits of its wire image, deploying new transport features is easier and more practical. In contrast, TCP evolution was hampered by middleboxes that failed to keep up with the times.</p><p>Naturally, we’d want the proxying protocol we use for so many people’s everyday browsing to take advantage of these benefits. For example, the QUIC unreliable datagram extension doesn't help much for standard web traffic but it's ideal for tunneling UDP or IP packets that expect an unreliable substrate beneath them. Without the unreliable aspect, the protocols on top can get upset and start to perform badly. Datagrams help <a href="/unlocking-quic-proxying-potential/">unlock QUIC's proxying potential</a>.</p>
    <div>
      <h3>MASQUE: A new era for VPN performance and flexibility</h3>
      <a href="#masque-a-new-era-for-vpn-performance-and-flexibility">
        
      </a>
    </div>
    <p>You may have heard of HTTP GET, POST, and PUT, but what about CONNECT? HTTP-CONNECT is a method that opens up a tunnel between servers and proxies traffic between them. For a deeper dive, check out our <a href="/a-primer-on-proxies/">Primer on Proxies</a>. Many Cloudflare services use this method like so:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7wRyhoDt1llea6yFLatWM7/74be9b291b836b0e6206c91b1fa6f1e7/image3-19.png" />
            
            </figure><p>Clients send a CONNECT request, and if the proxy sends back a 2xx (success) status code, tunnel secured! Simple. However, remember that QUIC is UDP-based. Luckily, the MASQUE working group has figured out how to run multiple concurrently stream and datagram-based connections. Establishing one looks like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2oM2BqoRmCSSNBnZat6fKg/eea30bf8bfa9bff3cdffa2a2c80471e4/image7-6.png" />
            
            </figure><p>Here’s what this MASQUE proxying looks like:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/74WqCLMSGU3VlkvGpD1kRb/785c18b7a14e8f92fa1adb01ee714e43/image6-4.png" />
            
            </figure><p>From a development perspective, MASQUE also allows us to improve our performance in other ways: we’re already running it for <a href="/icloud-private-relay/">iCloud Private Relay</a> and other Privacy Proxy partners. The services that power these partnerships, from our Rust-based <a href="/introducing-oxy/">proxy framework</a> to our open source <a href="https://github.com/cloudflare/quiche">QUIC implementation</a>, are already deployed globally in our network and have proven to be fast, resilient, and reliable. We've already learned a lot about how to operate proxies at scale, but there’s plenty of room for improvement. The good news is that every performance improvement we make to speed up MASQUE-based connections for our WARP clients will also improve performance for our customers that use HTTP-CONNECT, and vice-versa.</p><p>From a protocol perspective, we also think that MASQUE will prove to be resilient over time. As you can see above, connections are made through port 443, which for both TCP and UDP blends in well with general HTTP/3 traffic and is less susceptible than WireGuard to blocking.</p><p>Finally, because MASQUE is an IETF standard, innovations via extensions are already underway. One we’re particularly excited about is <a href="https://datatracker.ietf.org/doc/draft-ietf-quic-multipath/">Multipath QUIC</a>, an extension whose implementation would allow us to use multiple concurrent network interfaces for a single logical QUIC connection. For example, using both LTE and WiFi on a single mobile device could allow for seamless switching between the two, helping to avoid pesky disruptions when you’re coming to and from work or home.</p><p>The magic of supporting MASQUE is that it combines some pretty cool (and very Cloudflare-y!) elements: a standards-based proxying protocol that provides real user-facing performance benefits, built upon Cloudflare’s widely available Anycast network, and encryption of that last-mile between that network and your phone.</p>
    <div>
      <h3>So how can I use it?</h3>
      <a href="#so-how-can-i-use-it">
        
      </a>
    </div>
    <p>If you’d like to join the waitlist for our beta tester program for MASQUE, you can <a href="https://www.cloudflare.com/lp/masque-building-a-new-protocol-into-cloudflare-warp/">sign up here</a>.</p><p>You’ll first need to download <a href="https://testflight.apple.com/">Testflight</a> on a valid iOS device. We will be sending out invites to download the app via Testflight first come, first served, as early as next week. Once you’ve downloaded the app, MASQUE will be available as the default connection in our beta iOS version, only available in iOS 17 (and up).</p><p>To toggle between WireGuard and MASQUE, go to Settings &gt; Personalization &gt; Protocol:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7znX2d4cNvCtyP1ZJkGcXp/6e533c1c01642ed66312bc57f5d48915/Screenshot-2023-06-22-at-11.55.53.png" />
            
            </figure>
    <div>
      <h3>Protocols come and go, but our privacy promise remains the same</h3>
      <a href="#protocols-come-and-go-but-our-privacy-promise-remains-the-same">
        
      </a>
    </div>
    <p>While the protocols that dominate the Internet may change, our promise to consumers remains the same – a more private Internet, free of cost. When using WARP, we still route all DNS queries through 1.1.1.1, our privacy-respecting DNS resolver; we will never write user-identifiable log data to disk; we will never sell your browsing data or use it in any way to target you with advertising data; and you can still use WARP without providing any personal information like your name, phone number, or email address.</p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[WARP]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">iA0K7orrJ18n2Cqtw2ox3</guid>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Privacy Gateway: a privacy preserving proxy built on Internet standards]]></title>
            <link>https://blog.cloudflare.com/building-privacy-into-internet-standards-and-how-to-make-your-app-more-private-today/</link>
            <pubDate>Thu, 27 Oct 2022 13:01:00 GMT</pubDate>
            <description><![CDATA[ Privacy Gateway enables privacy-forward applications to use Cloudflare as a trusted Relay, limiting which identifying information, including IP addresses, is visible to their infrastructure ]]></description>
            <content:encoded><![CDATA[ <p></p><p>If you’re running a privacy-oriented application or service on the Internet, your options to provably protect users’ privacy are limited. You can minimize logs and data collection but even then, at a network level, every HTTP request needs to come from <i>somewhere.</i> Information generated by HTTP requests, like users’ IP addresses and TLS fingerprints, can be sensitive especially when combined with application data.</p><p>Meaningful improvements to your users’ privacy require a change in how HTTP requests are sent from client devices to the server that runs your application logic. This was the motivation for Privacy Gateway: a service that relays encrypted HTTP requests and responses between a client and application server. With Privacy Gateway, Cloudflare knows where the request is coming from, but not what it contains, and applications can see what the request contains, but not where it comes from. <b>Neither Cloudflare nor the application server has the full picture</b>, improving end-user privacy.</p><p>We recently deployed Privacy Gateway for <a href="https://flo.health/">Flo Health Inc</a>., a leading female health app, for the launch of their <a href="https://www.theverge.com/2022/9/14/23351957/flo-period-tracker-privacy-anonymous-mode">Anonymous Mode</a>. With Privacy Gateway in place, all request data for Anonymous Mode users is encrypted between the app user and Flo, which prevents Flo from seeing the IP addresses of those users and Cloudflare from seeing the contents of that request data.</p><p>With Privacy Gateway in place, several other privacy-critical applications are possible:</p><ul><li><p>Browser developers can collect user telemetry in a privacy-respecting manner– what extensions are installed, what defaults a user might have changed — while removing what is still a potentially personal identifier (the IP address) from that data.</p></li><li><p>Users can visit a healthcare site to report a Covid-19 exposure without worrying that the site is tracking their IP address and/or location.</p></li><li><p>DNS resolvers can serve DNS queries without linking who made the request with what website they’re visiting – a pattern we’ve implemented with <a href="/oblivious-dns/">Oblivious DNS</a>.Privacy Gateway is based on <a href="https://datatracker.ietf.org/doc/draft-ietf-ohai-ohttp/">Oblivious HTTP (OHTTP), an emerging IETF standard</a> and is built upon standard <a href="https://datatracker.ietf.org/doc/html/rfc9180">hybrid public-key cryptography</a>.</p></li></ul>
    <div>
      <h2>How does it work?</h2>
      <a href="#how-does-it-work">
        
      </a>
    </div>
    <p>The main innovation in the Oblivious HTTP standard – beyond a basic proxy service – is that these messages are encrypted <i>to the application’s server</i>, such that Privacy Gateway learns nothing of the application data beyond the source and destination of each message.</p><p>Privacy Gateway enables application developers and platforms, especially those with strong privacy requirements, to build something that closely resembles a “<a href="https://en.wikipedia.org/wiki/Mix_network">Mixnet</a>”: an approach to obfuscating the source and destination of a message across a network. To that end, Privacy Gateway consists of three main components:</p><ol><li><p><b>Client:</b> the user’s device, or any client that’s configured to forward requests to Privacy Gateway.</p></li><li><p><b>Privacy Gateway:</b> a service operated by Cloudflare and designed to relay requests between the Client and the Gateway, without being able to observe the contents within.</p></li><li><p><b>Application server</b>: the origin or application web server responsible for decrypting requests from clients, and encrypting responses back.</p></li></ol><p>If you were to imagine request data as the contents of the envelope (a letter) and the IP address and request metadata as the address on the outside, with Privacy Gateway, Cloudflare is able to see the envelope’s address and safely forward it to its destination without being able to see what’s inside.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2sYdEzCvuyKU7h3wIUKju0/b845a85835291ffe7c9751355b9c6b5f/image4-9.png" />
            
            </figure><p>An Oblivious HTTP transaction using Privacy Gateway</p><p>In slightly more detail, the data flow is as follows:</p><ol><li><p>Client <a href="https://datatracker.ietf.org/doc/html/draft-thomson-http-oblivious-02#section-5.1">encapsulates an HTTP request</a> using the public key of the application server, and sends it to Privacy Gateway over an HTTPS connection.</p></li><li><p>Privacy Gateway forwards the request to the server over its own, separate HTTPS connection with the application server.</p></li><li><p>The application server  decapsulates the request, forwarding it to the target server which can produce the response.</p></li><li><p>The application server returns an <a href="https://datatracker.ietf.org/doc/html/draft-thomson-http-oblivious-02#section-5.2">encapsulated response</a> to Privacy Gateway, which then forwards the result to the client.As specified in the protocol, requests from the client to the server are encrypted using HPKE, a state-of-the-art standard for public key encryption – which you can read more about <a href="/hybrid-public-key-encryption/">here</a>. We’ve taken additional measures to ensure that OHTTP’s use of HPKE is secure by conducting a <a href="/stronger-than-a-promise-proving-oblivious-http-privacy-properties/">formal analysis of the protocol</a>, and we expect to publish a deeper analysis in the coming weeks.</p></li></ol>
    <div>
      <h2>How Privacy Gateway improves end-user privacy</h2>
      <a href="#how-privacy-gateway-improves-end-user-privacy">
        
      </a>
    </div>
    <p>This interaction offers two types of privacy, which we informally refer to as <i>request privacy</i> and <i>client privacy</i>.</p><p>Request privacy means that the application server does not learn information that would otherwise be revealed by an HTTP request, such as IP address, geolocation, TLS and HTTPS fingerprints, and so on. Because Privacy Gateway uses a separate HTTPS connection between itself and the application server, all of this per-request information revealed to the application server represents that of Privacy Gateway, not of the client. However, developers need to take care to not send personally identifying information in the contents of requests. If the request, once decapsulated, includes information like users’ email, phone number, or credit card info, for example, Privacy Gateway will not meaningfully improve privacy.</p><p>Client privacy is a stronger notion. Because Cloudflare and the application server are not colluding to share individual user’s data, from the server’s perspective, each individual transaction came from some unknown client behind Privacy Gateway. In other words, a properly configured Privacy Gateway deployment means that applications cannot link any two requests to the same client. In particular, with Privacy Gateway, privacy loves company. If there is only one end-user making use of Privacy Gateway, then it only provides request privacy (since the client IP address remains hidden from the Gateway). It would not provide client privacy, since the server would know that each request corresponds to the same, single client. Client privacy requires that there be many users of the system, so the application server cannot make this determination.</p><p>To better understand request and client privacy, consider the following HTTP request between a client and server:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6tEmiR5nN2XWpa1EqATvBY/e74edca6ab779548c43aaa357fd88578/image3-7.png" />
            
            </figure><p>Normal HTTP configuration with a client anonymity set of size 1</p><p>If a client connects directly to the server (or “Gateway” in OHTTP terms), the server is likely to see information about the client, including the IP address, TLS cipher used, and a degree of location data based on that IP address:</p>
            <pre><code>- ipAddress: 192.0.2.33 # the client’s real IP address
- ASN: 7922
- AS Organization: Comcast Cable
- tlsCipher: AEAD-CHACHA20-POLY1305-SHA256 # potentially unique
- tlsVersion: TLSv1.3
- Country: US
- Region: California
- City: Campbell</code></pre>
            <p>There’s plenty of sensitive information here that might be unique to the end-user. In other words, the connection offers neither request nor client privacy.</p><p>With Privacy Gateway, clients do not connect directly to the application server itself. Instead, they connect to Privacy Gateway, which in turn connects to the server. This means that the server only observes connections from Privacy Gateway, not individual connections from clients, yielding a different view:</p>
            <pre><code>- ipAddress: 104.16.5.5 # a Cloudflare IP
- ASN: 13335
- AS Organization: Cloudflare
- tlsCipher: ECDHE-ECDSA-AES128-GCM-SHA256 # shared across several clients
- tlsVersion: TLSv1.3
- Country: US
- Region: California
- City: Los Angeles</code></pre>
            
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/34pNp8QRamMWLMqBpT2Q05/4b400b029df3a7ad8821e7da69dd30b9/image1-18.png" />
            
            </figure><p>Privacy Gateway configuration with a client anonymity set of size k</p><p>This is request privacy. All information about the client’s location and identity are hidden from the application server. And all details about the application data are hidden from Privacy Gateway. For sensitive applications and protocols like DNS, keeping this metadata separate from the application data is an important step towards improving end-user privacy.</p><p>Moreover, applications should take care to not reveal sensitive, per-client information in their individual requests. Privacy Gateway cannot guarantee that applications do not send identifying info – such as email addresses, full names, etc – in request bodies, since it cannot observe plaintext application data. Applications which reveal user identifying information in requests may violate client privacy, but not request privacy. This is why – unlike our full <a href="/privacy-edge-making-building-privacy-first-apps-easier/">application-level Privacy Proxy</a> product – Privacy Gateway is <i>not</i> meant to be used as a generic proxy-based protocol for arbitrary applications and traffic. It is meant to be a special purpose protocol for sensitive applications, including DNS (as is evidenced by <a href="/oblivious-dns/">Oblivious DNS-over-HTTPS</a>), telemetry data, or generic API requests as discussed above.</p>
    <div>
      <h2>Integrating Privacy Gateway into your application</h2>
      <a href="#integrating-privacy-gateway-into-your-application">
        
      </a>
    </div>
    <p>Integrating with Privacy Gateway requires applications to implement the client and server side of the OHTTP protocol. Let’s walk through what this entails.</p>
    <div>
      <h3>Server Integration</h3>
      <a href="#server-integration">
        
      </a>
    </div>
    <p>The server-side part of the protocol is responsible for two basic tasks:</p><ol><li><p>Publishing a public key for request encapsulation; and</p></li><li><p>Decrypting encapsulated client requests, processing the resulting request, and encrypting the corresponding response.</p></li></ol><p>A <a href="https://ietf-wg-ohai.github.io/oblivious-http/draft-ietf-ohai-ohttp.html#name-key-configuration">public encapsulation key</a>, called a key configuration, consists of a key identifier (so the server can support multiple keys at once for rotation purposes), cryptographic algorithm identifiers for encryption and decryption, and a public key:</p>
            <pre><code>HPKE Symmetric Algorithms {
  HPKE KDF ID (16),
  HPKE AEAD ID (16),
}

OHTTP Key Config {
  Key Identifier (8),
  HPKE KEM ID (16),
  HPKE Public Key (Npk * 8),
  HPKE Symmetric Algorithms Length (16),
  HPKE Symmetric Algorithms (32..262140),
}</code></pre>
            <p>Clients need this public key to create their request, and there are lots of ways to do this. Servers could fix a public key and then bake it into their application, but this would require a software update to rotate the key. Alternatively, clients could discover the public key some other way. Many discovery mechanisms exist and vary based on your threat model – see <a href="https://datatracker.ietf.org/doc/html/draft-wood-key-consistency">this document</a> for more details. To start, a simple approach is to have clients fetch the public key directly from the server over some API. Below is a snippet of the API that our <a href="https://github.com/cloudflare/app-relay-gateway-go/blob/main/gateway.go#L116-L134">open source OHTTP server provides</a>:</p>
            <pre><code>func (s *GatewayResource) configHandler(w http.ResponseWriter, r *http.Request) {
	config, err := s.Gateway.Config(s.keyID)
	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	w.Write(config.Marshal())
}</code></pre>
            <p>Once public key generation and distribution is solved, the server then needs to handle encapsulated requests from clients. For each request, the server needs to decrypt the request, translate the plaintext to a corresponding HTTP request that can be resolved, and then encrypt the resulting response back to the client.</p><p>Open source OHTTP libraries typically offer functions for <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L455">request decryption</a> and <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L502-L541">response encryption</a>, whereas plaintext translation from <a href="https://datatracker.ietf.org/doc/html/rfc9292">binary HTTP</a> to an HTTP request is handled separately. For example, our open source server delegates this translation to a different library that is specific to how Go HTTP requests are represented in memory. In particular, the function to translate from a plaintext request to a <a href="https://pkg.go.dev/net/http#Request">Go HTTP request</a> is done with a function that has the following signature:</p>
            <pre><code>func UnmarshalBinaryRequest(data []byte) (*http.Request, error) {
	...
}</code></pre>
            <p>Conversely, translating a <a href="https://pkg.go.dev/net/http#Response">Go HTTP response</a> to a plaintext binary HTTP response message is done with a function that has the following signature:</p>
            <pre><code>type BinaryResponse http.Response

func (r *BinaryResponse) Marshal() ([]byte, error) {
	...
}</code></pre>
            <p>While there exist several open source libraries that one can use to implement OHTTP server support, we’ve packaged all of it up in our open source server implementation <a href="https://github.com/cloudflare/app-relay-gateway-go">available here</a>. It includes instructions for building, testing, and deploying to make it easy to get started.</p>
    <div>
      <h3>Client integration</h3>
      <a href="#client-integration">
        
      </a>
    </div>
    <p>Naturally, the client-side behavior of OHTTP mirrors that of the server. In particular, the client must:</p><ol><li><p>Discover or obtain the server public key; and</p></li><li><p>Encode and encrypt HTTP requests, send them to Privacy Gateway, and decrypt and decode the HTTP responses.</p></li></ol><p>Discovery of the server public key depends on the server’s chosen deployment model. For example, if the public key is available over an API, clients can simply fetch it directly:</p>
            <pre><code>$ curl https://server.example/ohttp-configs &gt; config.bin</code></pre>
            <p><a href="https://github.com/chris-wood/ohttp-go/blob/main/bhttp.go#L66">Encoding</a>, <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L321">encrypting</a>, <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L373">decrypting</a>, and decoding are again best handled by OHTTP libraries when available. With these functions available, building client support is rather straightforward. A trivial example Go client using the library functions linked above is as follows:</p>
            <pre><code>configEnc := ... // encoded public key
config, err := ohttp.UnmarshalPublicConfig(configEnc)
if err != nil {
	return err
}

request, err := http.NewRequest(http.MethodGet, "https://test.example/index.html", nil)
if err != nil {
	return err
}

binaryRequest := ohttp.BinaryRequest(*request)
encodedRequest, err := binaryRequest.Marshal()
if err != nil {
	return err
}

ohttpClient := ohttp.NewDefaultClient(config)
encapsulatedReq, reqContext, err := ohttpClient.EncapsulateRequest(encodedRequest)

relayRequest, err := http.NewRequest(http.MethodPost, "https://relay.example", bytes.NewReader(encapsulatedReq.Marshal()))
if err != nil {
	return err
}
relayRequest.Header.Set("Content-Type", "message/ohttp-req")

client := http.Client{}
relayResponse, err := client.Do(relayRequest)
if err != nil {
	return err
}
bodyBytes, err := ioutil.ReadAll(relayResponse.Body)
if err != nil {
	return err
}
encapsulatedResp, err := ohttp.UnmarshalEncapsulatedResponse(bodyBytes)
if err != nil {
	return err
}

receivedResp, err := reqContext.DecapsulateResponse(encapsulatedResp)
if err != nil {
	return err
}

response, err := ohttp.UnmarshalBinaryResponse(receivedResp)
if err != nil {
	return err
}

fmt.Println(response)</code></pre>
            <p>A standalone client like this isn’t likely very useful to you if you have an existing application. To help integration into your existing application, we created a <a href="https://github.com/cloudflare/app-relay-client-library">sample OHTTP client library</a> that’s compatible with iOS and macOS applications. Additionally, if there’s language or platform support you would like to see to help ease integration on either or the client or server side, please let us know!</p>
    <div>
      <h2>Interested?</h2>
      <a href="#interested">
        
      </a>
    </div>
    <p>Privacy Gateway is currently in early access – available to select privacy-oriented companies and partners. If you’re interested, <a href="https://www.cloudflare.com/lp/privacy-edge/">please get in touch</a>.</p> ]]></content:encoded>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Standards]]></category>
            <guid isPermaLink="false">4KXLduwaLrRcnGTcApXBpH</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Christopher Wood</dc:creator>
        </item>
        <item>
            <title><![CDATA[Private by design: building privacy-preserving products with Cloudflare's Privacy Edge]]></title>
            <link>https://blog.cloudflare.com/privacy-edge-making-building-privacy-first-apps-easier/</link>
            <pubDate>Wed, 28 Sep 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ Introducing Privacy Edge – a collection of products that make it easier for site owners and developers to protect their users’ privacy by default.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>When Cloudflare was founded, our value proposition had three pillars: more secure, more reliable, and more performant. Over time, we’ve realized that a better Internet is also a more private Internet, and we want to play a role in building it.</p><p>User awareness and expectations of and for privacy are higher than ever, but we believe that application developers and platforms shouldn’t have to start from scratch. We’re excited to introduce Privacy Edge – Code Auditability, Privacy Gateway, Privacy Proxy, and Cooperative Analytics – a suite of products that make it easy for site owners and developers to build privacy into their products, by default.</p>
    <div>
      <h3>Building network-level privacy into the foundations of app infrastructure</h3>
      <a href="#building-network-level-privacy-into-the-foundations-of-app-infrastructure">
        
      </a>
    </div>
    <p>As you’re browsing the web every day, information from the networks and apps you use can expose more information than you intend. When accumulated over time, <a href="https://coveryourtracks.eff.org/">identifiers</a> like your IP address, cookies, browser and device characteristics create a unique profile that can be used to track your browsing activity. We don’t think this status quo is right for the Internet, or that consumers should have to understand the complex ecosystem of third-party trackers to maintain privacy. Instead, we’ve been working on technologies that encourage and enable website operators and app developers to build privacy into their products at the protocol level.</p><p>Getting privacy right is hard. We figured we’d start in the area we know best: building privacy into our network infrastructure. Like other work we’ve done in this space – offering <a href="https://www.cloudflare.com/application-services/products/ssl/">free SSL certificates</a> to make encrypted HTTP requests the norm, and <a href="/announcing-1111/">launching 1.1.1.1</a>, a privacy-respecting DNS resolver, for example – the products we’re announcing today are built upon the foundations of open Internet standards, many of which are co-authored by members of our <a href="https://research.cloudflare.com/">Research Team</a>.</p><p>Privacy Edge – the collection of products we’re announcing today, includes:</p><ul><li><p><b>Privacy Gateway:</b> A lightweight proxy that encrypts request data and forwards it through an IP-blinding relay</p></li><li><p><b>Code Auditability:</b> A solution to verifying that code delivered in your browser hasn’t been tampered with</p></li><li><p><b>Private Proxy:</b> A proxy that offers the protection of a VPN, built natively into application architecture</p></li><li><p><b>Cooperative Analytics:</b> A multi-party computation approach to measurement and analytics based on an emerging distributed aggregation protocol.</p></li></ul><p>Today’s announcement of Privacy Edge isn’t exhaustive. We’re continuing to explore, research and develop new privacy-enabling technologies, and we’re excited about all of them.</p>
    <div>
      <h3>Privacy Gateway: IP address privacy for your users</h3>
      <a href="#privacy-gateway-ip-address-privacy-for-your-users">
        
      </a>
    </div>
    <p>There are situations in which applications only need to receive certain HTTP requests for app functionality, but linking that data with who or where it came from creates a privacy concern.</p><p>We recently partnered with <a href="https://www.theverge.com/2022/9/14/23351957/flo-period-tracker-privacy-anonymous-mode">Flo Health</a>, a period tracking app, to solve exactly that privacy concern: for users that have turned on “Anonymous mode,” Flo encrypts and forwards traffic through Privacy Gateway so that the network-level request information (most importantly, users’ IP addresses) are replaced by the Cloudflare network.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6ZyPg6bstt6kfkkKdgLrxX/635d48b71118bdb22b9fd8b2d6cb5adf/Screen-Shot-2022-10-10-at-3.23.56-PM.png" />
            
            </figure><p>How data is encapsulated, forwarded, and decapsulated in the Privacy Gateway system.</p><p>So how does it work? <b>Privacy Gateway</b> is based on Oblivious HTTP, an <a href="https://datatracker.ietf.org/doc/draft-ietf-ohai-ohttp/">emerging IETF standard</a>, and at a high level describes the following data flow:</p><ol><li><p>The client <a href="https://datatracker.ietf.org/doc/html/draft-ietf-ohai-ohttp-04#section-4.3">encapsulates an HTTP request</a> using the public key of the customer’s gateway server, and sends it to the relay over a client&lt;&gt;relay HTTPS connection.</p></li><li><p>The relay forwards the request to the server over its own relay&lt;&gt;gateway HTTPS connection.</p></li><li><p>The gateway server decapsulates the request, forwarding it to the application server.</p></li><li><p>The gateway server returns an <a href="https://datatracker.ietf.org/doc/html/draft-thomson-http-oblivious-02#section-5.2">encapsulated response</a> to the relay, which then forwards the result to the client.</p></li></ol><p>The novel feature Privacy Gateway implements from the OHTTP specification is that messages sent through the relay are encrypted (via <a href="/hybrid-public-key-encryption/">HPKE</a>) <i>to the application server</i>, so that the relay learns nothing of the application data beyond the source and destination of each message.</p><p>The end result is that the relay will know where the data request is coming from (i.e. users’ IP addresses) but not what it contains (i.e. contents of the request), and the application can see what the data contains but won’t know where it comes from. A win for end-user privacy.</p>
    <div>
      <h3>Delivering verifiable and authentic code for privacy-critical applications</h3>
      <a href="#delivering-verifiable-and-authentic-code-for-privacy-critical-applications">
        
      </a>
    </div>
    <p>How can you ensure that the code — the JavaScript, CSS or even HTML —delivered to a browser hasn’t been tampered with?</p><p>One way is to generate a hash (a consistent, unique, and shorter representation) of the code, and have two independent parties compare those hashes when delivered to the user's browser.</p><p>Our <b>Code Auditability</b> service does exactly that, and our recent <a href="/cloudflare-verifies-code-whatsapp-web-serves-users/">partnership with Meta</a> deployed it at scale to WhatsApp Web. Installing their <a href="https://chrome.google.com/webstore/detail/code-verify/llohflklppcaghdpehpbklhlfebooeog/">Code Verify browser extension</a> ensures users can be sure that they are delivered the code they’re intended to run – free of tampering or corrupted files.</p><p>With WhatsApp Web:</p><ol><li><p>WhatsApp publishes the latest version of their JavaScript libraries to their servers, and the corresponding hash for that version to Cloudflare’s audit endpoint.</p></li><li><p>A WhatsApp web client fetches the latest libraries from WhatsApp.</p></li><li><p>The Code Verify browser extension subsequently fetches the hash for that version from Cloudflare over a separate, secure connection.</p></li><li><p>Code Verify compares the “known good” hash from Cloudflare with the hash of the libraries it locally computed.</p></li></ol><p>If the hashes match, as they should under almost any circumstance, the code is “verified” from the perspective of the extension. If the hashes don’t match, it indicates that the code running on the user's browser is different from the code WhatsApp intended to run on all its user's browsers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7J7iewJRkCFkCVS83Vz78z/78ab22efc4567616ce4710193358d18f/image4-22.png" />
            
            </figure><p>How Cloudflare and WhatsApp Web verify code shipped to users isn't tampered with.</p><p>Right now, we call this "Code Auditability" and we see a ton of other potential use cases including password managers, email applications, certificate issuance – all technologies that are potentially targets of tampering or security threats because of the sensitive data they handle.</p><p>In the near term, we’re working with other app developers to co-design solutions that meet their needs for privacy-critical products. In the long term, we’re working on standardizing the approach, including building on existing <a href="https://w3c.github.io/webappsec-csp">Content Security Policy</a> standards, or the <a href="https://github.com/WICG/isolated-web-apps">Isolated Web Apps</a> proposal, and even an approach towards building Code Auditability natively into the browser so that a browser extension (existing or new) isn't required.</p>
    <div>
      <h3>Privacy-preserving proxying – built into applications</h3>
      <a href="#privacy-preserving-proxying-built-into-applications">
        
      </a>
    </div>
    <p>What if applications could build the protection of a VPN into their products, by default?</p><p><b>Privacy Proxy</b> is our platform to proxy traffic through Cloudflare using a combination of privacy protocols that make it much more difficult to track users’ web browsing activity over time. At a high level, the Privacy Proxy Platform encrypts browsing traffic, replaces a device’s IP address with one from the Cloudflare network, and then forwards it onto its destination.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7o0fEdQW7qgzJugHzkc4qO/cc8b78a91f186f4706ba163cd9f31d2b/image5-21.png" />
            
            </figure><p>System architecture for Privacy Proxy.</p><p>The Privacy Proxy platform consists of several pieces and protocols to make it work:</p><ol><li><p>Privacy API: a service that issues unique <a href="https://www.ietf.org/archive/id/draft-private-access-tokens-01.html">cryptographic tokens</a>, later redeemed against the proxy service to ensure that only valid clients are able to connect to the service.</p></li><li><p>Geolocated IP assignment: a service that assigns each connection a new Cloudflare IP address based on the client’s <a href="/geoexit-improving-warp-user-experience-larger-network/">approximate location</a>.</p></li><li><p>Privacy Proxy: the <a href="https://datatracker.ietf.org/wg/masque/about/?cf_target_id=FFEC349381334FBB00C45C937C7B2088">HTTP CONNECT</a>-based service running on Cloudflare’s network that handles the proxying of traffic. This service validates the privacy token passed by the client, enforces any double spend prevention necessary for the token.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7mtDkUW6hrd81lfVtxZJMw/5d5d85c528cc01e7b2d8be25c39fe000/image3-41.png" />
            
            </figure><p>We’re working on several partnerships to provide network-level protection for user’s browsing traffic, most recently with Apple for <a href="/icloud-private-relay/">Private Relay</a>. Private Relay’s design adds privacy to the traditional proxy design by adding an additional hop – an ingress proxy, operated by Apple – that separates handling users’ identities (i.e., whether they’re a valid iCloud+ user) from the proxying of traffic – the egress proxy, operated by Cloudflare.</p>
    <div>
      <h3>Measurements and analytics without seeing individual inputs</h3>
      <a href="#measurements-and-analytics-without-seeing-individual-inputs">
        
      </a>
    </div>
    <p>What if you could calculate the results of a poll, without seeing individuals' votes, or update inputs to a <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning model</a> that predicted COVID-19 exposure without seeing who was exposed?</p><p>It might seem like magic, but it's actually just cryptography. <b>Cooperative Analytics</b> is a multi-party computation system for aggregating privacy-sensitive user measurements that doesn’t reveal individual inputs, based on the <a href="https://github.com/ietf-wg-ppm/draft-ietf-ppm-dap">Distributed Aggregation Protocol</a> (DAP).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/l4oSgLQa7hJYT0ZDAR1b1/86d7511c982984e782f84a3e10e8e1c6/image6-11.png" />
            
            </figure><p>How data flows through the Cooperative Analytics system.</p><p>At a high-level, DAP takes the core concept behind <a href="https://en.wikipedia.org/wiki/MapReduce">MapReduce</a> — what became a fundamental way to aggregate large amounts of data — and rethinks how it would work with privacy-built in, so that each individual input cannot be (provably) mapped back to the original user.</p><p>Specifically:</p><ol><li><p>Measurements are first "secret shared," or split into multiple pieces. For example, if a user's input is the number 5, her input could be split into two shares of [10,-5].</p></li><li><p>The input share pieces are then distributed between different, non-colluding servers for aggregation (in this example, simply summed up). Similar to Privacy Gateway or Private Proxy, no one party has all the information needed to reconstruct any user's input.</p></li><li><p>Depending on the use case, the servers will then communicate with one another in order to verify that the input is "valid" – so that no one can insert an input that throws off the entire results. The magic of multi-party computation is that the servers can perform this computation without learning anything about the input beyond its validity.</p></li><li><p>Once enough input shares have been aggregated to ensure strong anonymity and a statistically significant sample size – each server sends its sum of the input shares to the overall consumer of this service to then compute the final result.</p></li></ol><p>For simplicity, the above example talks about measurements as summed up numbers, but DAP describes algorithms for multiple different types of inputs: the most common string input, or a linear regression, for example.</p><p>Early iterations of this system have been implemented by Apple and Google for COVID-19 <a href="https://www.abetterinternet.org/post/prio-services-for-covid-en/">exposure notifications</a>, but there are many other potential use cases for a system like this: think sensitive browser telemetry, geolocation data – any situation where one has a question about a population of users, but doesn't want to have to measure them directly.</p><p>Because this system requires different parties to operate separate aggregation servers, Cloudflare is working with several partners to act as one of the aggregation servers for DAP. We’re calling our implementation <a href="https://github.com/cloudflare/daphne">Daphne</a>, and it’s built on top of Cloudflare Workers.</p>
    <div>
      <h3>Privacy still requires trust</h3>
      <a href="#privacy-still-requires-trust">
        
      </a>
    </div>
    <p>Part of what's cool about these systems is that they distribute information — whether user data, network traffic, or both — amongst multiple parties.</p><p>While we think that products included in Privacy Edge are moving the Internet in the right direction, we understand that trust only goes so far. To that end, we're trying to be as transparent as possible.</p><ul><li><p>We've open sourced the code for Privacy Gateway's server and DAP's aggregation server, and all the standards work we're doing is in public with the IETF.</p></li><li><p>We're also working on detailed and accessible privacy notices for each product that describe exactly what kind of network data Cloudflare sees, doesn't see, and how long we retain it for.</p></li><li><p>And, most importantly, we’re continuing to develop new protocols (like <a href="https://datatracker.ietf.org/doc/draft-ietf-ohai-ohttp/">Oblivious HTTP</a>) and technologies that don’t just require trust, but that can provably minimize the data observed or logged.</p></li></ul><p>We'd love to see more folks get involved in the standards space, and we welcome feedback from privacy experts and potential customers on how we can improve the integrity of these systems.</p>
    <div>
      <h3>We’re looking for collaborators</h3>
      <a href="#were-looking-for-collaborators">
        
      </a>
    </div>
    <p>Privacy Edge products are currently in early access.</p><p>We're looking for application developers who want to build more private user-facing apps with Privacy Gateway; browser and existing VPN vendors looking to improve network-level security for their users via Privacy Proxy; and anyone shipping sensitive software on the Internet that is looking to iterate with us on code auditability and web app signing.</p><p>If you're interested in working with us on furthering privacy on the Internet, then <a href="https://www.cloudflare.com/lp/privacy-edge/">please reach out</a>, and we’ll be in touch!</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">1xemlVnKaLgTuKXb1dHZc9</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Matt Silverlock</dc:creator>
        </item>
        <item>
            <title><![CDATA[1.1.1.1 + WARP: More features, still private]]></title>
            <link>https://blog.cloudflare.com/geoexit-improving-warp-user-experience-larger-network/</link>
            <pubDate>Sat, 06 Aug 2022 16:15:03 GMT</pubDate>
            <description><![CDATA[ We’re announcing two major improvements to our 1.1.1.1 + WARP apps ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3UjKl9XnDNqhTMCEUDIXX0/8fae4ecbf1c930616a1f52cc9a8f5c80/WARP-Geoexit.png" />
            
            </figure><p>It’s a Saturday night. You open your browser, looking for nearby pizza spots that are open. If the search goes as intended, your browser will show you results that are within a few miles, often based on the assumed location of your IP address. At Cloudflare, we affectionately call this type of geolocation accuracy the “pizza test”. When you use a Cloudflare product that sits between you and the Internet (for example, <a href="/1111-warp-better-vpn/">WARP</a>), it’s one of the ways we work to balance user experience and privacy. Too inaccurate and you’re getting pizza places from a neighboring country; too accurate and you’re reducing the privacy benefits of obscuring your location.</p><p>With that in mind, we’re excited to announce two major improvements to our 1.1.1.1 + WARP apps: first, an improvement to how we ensure search results and other geographically-aware Internet activity work without compromising your privacy, and second, a larger network with more locations available to WARP+ subscribers, powering even speedier connections to our global network.</p>
    <div>
      <h3>A better Internet browsing experience for every WARP user</h3>
      <a href="#a-better-internet-browsing-experience-for-every-warp-user">
        
      </a>
    </div>
    <p>When we originally built the 1.1.1.1+ WARP mobile app, we wanted to create a consumer-friendly way to connect to our network and privacy-respecting <a href="https://1.1.1.1/">DNS resolver</a>.</p><p>What we discovered over time is that the topology of the Internet dictates a different type of experience for users in different locations. Why? Sometimes, because traffic congestion or technical issues route your traffic to a less congested part of the network. Other times, Internet Service Providers may not <a href="https://www.cloudflare.com/peering-policy/">peer with Cloudflare</a> or engage in traffic engineering to optimize their networks how they see fit, which could result in user traffic connecting to a location that doesn’t quite map to their locale or language.</p><p>Regardless of the cause, the impact is that your search results become less relevant, if not outright confusing. For example, in somewhere dense with country borders, like Europe, your traffic in Berlin could get routed to Amsterdam because your mobile operator chooses to not peer in-country, giving you results in Dutch instead of German. This can also be disruptive if you’re trying to stream content subject to licensing restrictions, such as a person in the UK trying to watch BBC iPlayer or a person in Brazil trying to watch the World Cup.</p><p>So we fixed this. We just rolled out a major update to the service that powers WARP that will give you a geographically accurate browsing experience without revealing your IP address to the websites you’re visiting. Instead, websites you visit will see a Cloudflare IP address instead, making it harder for them to track you directly.</p>
    <div>
      <h3>How it works</h3>
      <a href="#how-it-works">
        
      </a>
    </div>
    <p>Traditionally, consumer VPNs deliberately route your traffic through a server in another country, making your connection slow, and often getting blocked because of their ability to flout location-based content restrictions. We took a different approach when we first launched WARP in 2018, giving you the best possible performance by routing your traffic through the Cloudflare data center closest to you. However, because not every Internet Service Provider (ISP) peers with Cloudflare, users sometimes end up exiting the Cloudflare network from a more “random” data center – one that does not accurately represent their locale.</p><p>Websites and third party services often infer geolocation from your IP address, and now, 1.1.1.1 + WARP replaces your original IP address with one that consistently and accurately represents your approximate location.</p><p>Here’s how we did it:</p><ol><li><p>We ran an analysis on a subset of our network traffic to find a rough approximation of how many users we have per city.</p></li><li><p>We divided that amongst our egress IPs, using an anycast architecture to be efficient with the number of additional IPs we had to allocate and advertise per metro area.</p></li><li><p>We then submitted geolocation information of those IPs to various geolocation database providers, ensuring third party services associate those Cloudflare egress IPs with an accurate approximate location.</p></li></ol><p>It was important to us to provide the benefits of this location accuracy without compromising user privacy, so the app doesn’t ask for specific location permissions or log your IP address.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3RwUR1o5sBsQIUo2rPBeaH/8b6d6a0c19732e468753317c3de7e387/image1-12.png" />
            
            </figure>
    <div>
      <h3>An even bigger network for WARP+ users</h3>
      <a href="#an-even-bigger-network-for-warp-users">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/28r1F3gCyYhp0GFEkCGkkD/f63ef80ec3a2e52a9f0dee03648dac59/image2-22.png" />
            
            </figure><p>We also recently announced that we’ve expanded our network to <a href="/new-cities-april-2022-edition/">over 275 cities</a> in over 100 countries. This gave us an opportunity to revisit where we offered WARP, and how we could expand the number of locations users can connect to WARP with (in other words: an opportunity to make things faster).</p><p>From today, all WARP+ subscribers will benefit from a larger network with 20+ new cities: with no change in subscription pricing. A closer Cloudflare data center means less latency between your device and Cloudflare, which directly improves your download speed, thanks to what’s called the <a href="https://en.wikipedia.org/wiki/Bandwidth-delay_product">Bandwidth-Delay Product</a> (put simply: lower latency, higher throughput!).</p><p>As a result, sites load faster, both for those on the <a href="https://www.cloudflare.com/network/">Cloudflare network</a> and those that aren’t. As we continue to expand our network, we'll be revising this on a regular basis to ensure that all WARP and WARP+ subscribers continue to get great performance.</p>
    <div>
      <h3>Speed, privacy, and relevance</h3>
      <a href="#speed-privacy-and-relevance">
        
      </a>
    </div>
    <p>Beyond being able to find pizza on a Saturday night, we believe everyone should be able to browse the Internet freely – and not have to sacrifice the speed, privacy, or relevance of their search results in order to do so.</p><p>In the near future, we’ll be investing in features to bring even more of the benefits of Cloudflare infrastructure to every 1.1.1.1 + WARP user. Stay tuned!</p> ]]></content:encoded>
            <category><![CDATA[WARP]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[1.1.1.1]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">54jbK4S6bmo5g5eovyu5Rb</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Matt Silverlock</dc:creator>
        </item>
        <item>
            <title><![CDATA[How Cloudflare verifies the code WhatsApp Web serves to users]]></title>
            <link>https://blog.cloudflare.com/cloudflare-verifies-code-whatsapp-web-serves-users/</link>
            <pubDate>Thu, 10 Mar 2022 18:30:01 GMT</pubDate>
            <description><![CDATA[ Understand how Cloudflare is helping WhatsApp verify the code they’re using for secure messaging hasn’t been tampered with ]]></description>
            <content:encoded><![CDATA[ <p></p><p>How do you know the code your web browser downloads when visiting a website is the code the website intended you to run? In contrast to a mobile app downloaded from a trusted app store, the web doesn’t provide the same degree of assurance that the code hasn’t been tampered with. Today, <a href="https://engineering.fb.com/2022/03/10/security/code-verify/">we’re excited to be partnering with WhatsApp</a> to provide a system that assures users that the code run when they visit WhatsApp on the web is the code that WhatsApp intended.</p><p>With WhatsApp usage in the browser growing, and the increasing number of at-risk users — including journalists, activists, and human rights defenders — WhatsApp wanted to take steps to provide assurances to browser-based users. They approached us to help dramatically raise the bar for third-parties looking to compromise or otherwise tamper with the code responsible for end-to-end encryption of messages between WhatsApp users.</p><p>So how will this work? Cloudflare holds a hash of the code that WhatsApp users should be running. When users run WhatsApp in their browser, the WhatsApp Code Verify extension compares a hash of that code that is executing in their browser with the hash that Cloudflare has — enabling them to easily see whether the code that is executing is the code that should be.</p><p>The idea itself — comparing hashes to detect tampering or even corrupted files — isn’t new, but automating it, deploying it at scale, and making sure it “just works” for WhatsApp users is. Given the reach of WhatsApp and the implicit trust put into Cloudflare, we want to provide more detail on how this system actually works from a technical perspective.</p><p>Before we dive in, there's one important thing to explicitly note: Cloudflare is providing a trusted audit endpoint to support Code Verify. Messages, chats or other traffic between WhatsApp users are never sent to Cloudflare; those stay private and end-to-end encrypted. Messages or media do not traverse <a href="https://www.cloudflare.com/network/">Cloudflare’s network</a> as part of this system, an important property from Cloudflare’s perspective in our role as a trusted third party.</p>
    <div>
      <h3>Making verification easier</h3>
      <a href="#making-verification-easier">
        
      </a>
    </div>
    <p>Hark back to 2003: Fedora, a popular Linux distribution based on Red Hat, has just been launched. You’re keen to download it, but want to make sure you have the “real” Fedora, and that the download isn’t a “fake” version that siphons off your passwords or logs your keystrokes. You head to the download page, kick off the download, and see an MD5 hash (considered secure at the time) next to the download. After the download is complete, you run <code>md5 fedora-download.iso</code> and compare the hash output to the hash on the page. They match, life is good, and you proceed to installing Fedora onto your machine.</p><p>But hold on a second: if the same website providing the download is also providing the hash, couldn’t a malicious actor replace both the download and the hash with their own values? The <code>md5</code> check we ran above would still pass, but there’s no guarantee that we have the “real” (untampered) version of the software we intended to download.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6dgKR5431UkYjRzHyN9WgY/1925fb13127679c9f3ef1596bf9e7c6c/image2-6.png" />
            
            </figure><p>Hosting the hash on the same server as the software is still common in 2022.</p><p>There are other approaches that attempt to improve upon this — providing signed signatures that users can verify were signed with “well known” public keys hosted elsewhere. Hosting those signatures (or “hashes”) with a trusted third party dramatically raises the bar when it comes to tampering, but now we require the user to know who to trust, and require them to learn tools like <a href="https://www.debian.org/CD/verify">GnuPG</a>. That doesn’t help us trust and verify software at the scale of the modern Internet.</p><p>This is where the <a href="https://chrome.google.com/webstore/detail/code-verify/llohflklppcaghdpehpbklhlfebooeog/">Code Verify extension</a> and Cloudflare come in. The Code Verify extension, published by Meta Open Source, automates this: locally computing the cryptographic hash of the libraries used by WhatsApp Web <i>and</i> comparing that hash to one from a trusted third-party source (Cloudflare, in this case).</p><p>We’ve illustrated this to make how it works a little clearer, showing how each of the three parties — the user, WhatsApp and Cloudflare — interact with each other.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5RshV8E1rSCsZh7Mms0eBF/c287591348f5964965f72bc2bf5097f8/image1-5.png" />
            
            </figure><p>Broken down, there are four major steps to verifying the code hasn’t been tampered with:</p><ol><li><p>WhatsApp publishes the latest version of their JavaScript libraries to their servers, and the corresponding hash for that version to Cloudflare’s audit endpoint.</p></li><li><p>A WhatsApp web client fetches the latest libraries from WhatsApp.</p></li><li><p>The Code Verify browser extension subsequently fetches the hash for that version from Cloudflare over a separate, secure connection.</p></li><li><p>Code Verify compares the “known good” hash from Cloudflare with the hash of the libraries it locally computed.</p></li></ol><p>If the hashes match, as they should under almost any circumstance, the code is “verified” from the perspective of the extension. If the hashes <i>don’t</i> match, it indicates that the code running on the user's browser is different from the code WhatsApp intended to run on all its user's browsers.</p>
    <div>
      <h3>Security needs to be convenient</h3>
      <a href="#security-needs-to-be-convenient">
        
      </a>
    </div>
    <p>It’s this process — and the fact that is automated on behalf of the user — that helps provide transparency in a scalable way. If users had to manually fetch, compute and compare the hashes themselves, detecting tampering would only be for the small fraction of technical users. For a service as large as WhatsApp, that wouldn’t have been a particularly accessible or user-friendly approach.</p><p>This approach also has parallels to a number of technologies in use today. One of them is <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">Subresource Integrity</a> in web browsers: when you fetch a third-party asset (such as a script or stylesheet), the browser validates that the returned asset matches the hash described. If it doesn’t, it refuses to load that asset, preventing potentially compromised scripts from siphoning off user data. Another is <a href="https://certificate.transparency.dev/">Certificate Transparency</a> and the related <a href="https://binary.transparency.dev/">Binary Transparency</a> projects. Both of these provide publicly auditable transparency for critical assets, including WebPKI certificates and other binary blobs. The system described in this post doesn’t scale to arbitrary assets – yet – but we are exploring ways in which we could extend this offering for something more general and usable like Binary Transparency.</p><p>Our collaboration with the team at WhatsApp is just the beginning of the work we’re doing to help improve privacy and <a href="https://www.cloudflare.com/application-security/">security on the web</a>.  We’re aiming to help other organizations verify the code delivered to users is the code they’re meant to be running. Protecting Internet users at scale and enabling privacy are core tenets of what we do at Cloudflare, and we look forward to continuing this work throughout 2022.</p> ]]></content:encoded>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">jlSaroOBMo7kYf9WfiLBS</guid>
            <dc:creator>Matt Silverlock</dc:creator>
            <dc:creator>James Allworth</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
    </channel>
</rss>