{
  "version": "https://jsonfeed.org/version/1",
  "title": "Ian's Digital Garden",
  "home_page_url": "https://ianwwagner.com/",
  "feed_url": "https://ianwwagner.com//tag-cryptography.json",
  "description": "",
  "items": [
    {
      "id": "https://ianwwagner.com//reqwest-0-13-upgrade-and-webpki.html",
      "url": "https://ianwwagner.com//reqwest-0-13-upgrade-and-webpki.html",
      "title": "reqwest 0.13 Upgrade and WebPKI",
      "content_html": "<p>In case you missed the <a href=\"https://seanmonstar.com/blog/reqwest-v013-rustls-default/\">announcement</a>,\nthe <code>reqwest</code> crate has a new and very important release out!\n<code>reqwest</code> is an opinionated, high-level HTTP client for Rust,\nand the main feature of this release is that <a href=\"https://rustls.dev/\"><code>rustls</code></a>\nis now the default TLS backend.\nRead the excellent blog posts from Sean and others on why <code>rustls</code>\nsafer and often faster than native TLS.\nIt's also a lot more convenient most of the time!</p>\n<h1><a href=\"#changes-to-certificate-verification\" aria-hidden=\"true\" class=\"anchor\" id=\"changes-to-certificate-verification\"></a>Changes to certificate verification</h1>\n<p>This post is about one of the more mundane parts of the release.\nPreviously there were a lot of somewhat confusing features related to certificate verification.\nThese have been condensed down to a smaller number of feature flags.\nThe summary of these changes took a bit to &quot;click&quot; for me so here's a rephrasing in my own words.</p>\n<ul>\n<li>By default, it uses the <a href=\"https://docs.rs/rustls-platform-verifier/latest/rustls_platform_verifier/\">native platform verifier</a>,\nwhich looks for root certificates in your system store, and inherits systemwide revocations and explicit trust settings\nin addition to the &quot;baseline&quot; root CAs trusted by your OS.</li>\n<li>The feature flag to enable WebPKI bundling of roots is gone.\nWebPKI is a bundle of CA root certificates trusted and curated by Mozilla.\nIt's a reasonably standard set, and most other trust stores look pretty similar.</li>\n<li>You can merge in your own <em>additionally</em> trusted root certificates using <a href=\"https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.tls_certs_merge\"><code>tls_certs_merge</code></a>.</li>\n<li>You can be extra exclusive and use <a href=\"https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.tls_certs_only\"><code>tls_certs_only</code></a>\nto limit verification to only the certificates you specify.</li>\n</ul>\n<p>The documentation and release notes also mention that <code>tls_certs_merge</code> is not always supported.\nI frankly have no idea what conditions cause this to be supported or not.\nBut <code>tls_certs_only</code> apparently can't fail. ¯\\_(ツ)_/¯</p>\n<h1><a href=\"#what-this-means-for-containerized-applications\" aria-hidden=\"true\" class=\"anchor\" id=\"what-this-means-for-containerized-applications\"></a>What this means for containerized applications</h1>\n<p>The reason I'm interested in this in mostly because at <code>$DAYJOB</code>, just about everything is deployed in containers.\nFor reasons that I don't fully understand (something about image size maybe??),\nthe popular container images like <code>debian:trixie-slim</code> <strong>do not include any root CAs</strong>.\nYou have to <code>apt-get install</code> them yourself.\nThis is to say that most TLS applications will straight up break in the out-of-the-box config.</p>\n<p>Previously I had seen this solved in two ways.\nThe first is to install the certs from your distribution's package manager like so:</p>\n<pre><code class=\"language-dockerfile\">RUN apt-get update \\\n &amp;&amp; apt-get install -y --no-install-recommends ca-certificates \\\n &amp;&amp; rm -rf /var/lib/apt/lists/*\n</code></pre>\n<p>The second is to add the WebPKI roots to your cargo dependencies.\nThis actually requires some manual work; adding the crate isn't enough.\nYou then have to add all of the roots (e.g. via <code>tls_certs_merge</code> or <code>tls_certs_only</code>).</p>\n<h1><a href=\"#which-approach-is-better\" aria-hidden=\"true\" class=\"anchor\" id=\"which-approach-is-better\"></a>Which approach is better?</h1>\n<p>The net result is <em>approximately</em> the same, but not entirely.\nThe system-level approach is more flexible.\nPresumably you would get updates in some cases without having to rebuild your application\n(though you do <em>not</em> get these automatically; the certs are only loaded once on app startup\nby <code>rustls_platform_verifier</code>!).\nPresumably you would also get any, say, enterprise-level trust, distrust, CRLs, etc.\nthat are dictated by your corporate IT department.</p>\n<p>The WebPKI approach on the other hand is baked at build time.\nThe <a href=\"https://docs.rs/webpki-root-certs/latest/webpki_root_certs/\">crate</a>\nhas a pretty strong, if slightly obtuse warning about this:</p>\n<blockquote>\n<p>This library is suitable for use in applications that can always be recompiled and instantly deployed. For applications that are deployed to end-users and cannot be recompiled, or which need certification before deployment, consider a library that uses the platform native certificate verifier such as <code>rustls-platform-verifier</code>. This has the additional benefit of supporting OS provided CA constraints and revocation data.</p>\n</blockquote>\n<p>Attempting to read between the lines, past that &quot;instantly deployed&quot; jargon,\nI think they are really just saying &quot;if you use this, certs are baked at compile time and you <em>never</em> get automatic updates. Be careful with that.&quot;</p>\n<p>So it's clear to me you shouldn't ship, say, a static binary to users with certs baked like this.\nBut I'm building server-side software.\nAnd as of February 2026, people look at you funny if you don't deploy using containers.\nI <em>can</em> deploy sufficiently instantly,\nthough to be honest I would have no idea <em>when</em> I should.\nMost apps get deployed frequently enough that I would assume this just doesn't matter,\nand so I'm not sure the warning as-written does much to help a lot of the Rust devs I know.</p>\n<h1><a href=\"#conclusion\" aria-hidden=\"true\" class=\"anchor\" id=\"conclusion\"></a>Conclusion</h1>\n<p>My conclusion is that if you're deploying containerized apps, there is approximately no functional difference.\nYour container is a static image anyways.\nThey don't typically run background tasks of any sort.\nAnd even if they did, the library won't reload the trusted store during application.\nSo it's functionally the same (delta any minor differences between WebPKI and Debian, which should be minimal).\nSimilarly, unless you work for a large enterprises / government,\nyou probably don't have mandated, hand-picked set of CAs and CRLs.\nSo again here there really is no difference as far as I can tell.</p>\n<p>In spite of that, I decided to switch away from using WebPKI in one of our containers that I upgraded.\nThe reason is that structuring this way\n(provided that the sources are copied from a previous layer!)\nensures that every image build always has the latest certs from Debian.\n<code>cargo build</code> is a lot more deterministic,\nand will use whatever you have in the lockfile unless you explicitly run <code>cargo update</code>.</p>\n<p>And even though I'm fortunate to not have an IT apparatus dictating cert policy today,\nyou never know... this approach seems to be both more flexible and creates a &quot;pit of success&quot;\nrather than a landmine where the trust store may not see an update for a year\ndespite regular rebuilds.</p>\n<p>In other words, I think Sean made the right choice, and you should <em>probably</em> delegate to the system,\nunless you have a particular reason to do otherwise.</p>\n<p>Hope this helps; I wrote this because I didn't understand the tradeoffs initially,\nand had some trouble parsing the existing writing on the subject.</p>\n",
      "summary": "",
      "date_published": "2026-02-13T00:00:00-00:00",
      "image": "",
      "authors": [
        {
          "name": "Ian Wagner",
          "url": "https://fosstodon.org/@ianthetechie",
          "avatar": "media/avi.jpeg"
        }
      ],
      "tags": [
        "rust",
        "cryptography"
      ],
      "language": "en"
    }
  ]
}