<?xml version="1.0" encoding="utf-8"?>
<rss
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:media="http://search.yahoo.com/mrss/"
  xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
  xmlns:webfeeds="http://webfeeds.org/rss/1.0">

  <channel>
    <title>CertKit SSL Certificate Management</title>
    <link>https://www.certkit.io</link>
    <atom:link href="https://www.certkit.io/feed.xml" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Thu, 05 Mar 2026 01:42:19 +0000</lastBuildDate>
    <pubDate>Thu, 05 Mar 2026 01:42:19 +0000</pubDate>
    <description>CertKit SSL Certificate Management automates the discovery, lifecycle, distribution, and monitoring of PKI Certificates.</description>
    <language>en-US</language>
    <copyright>2013-2026 TrackJS LLC. All rights reserved.</copyright>
    <category>Cybersecurity</category>
    <category>WebPKI</category>
    <category>Certificate Management</category>

    <webfeeds:cover image="https://www.certkit.io/assets/images/brand/certkit-share-image.png" />
    <webfeeds:icon>https://www.certkit.io/assets/images/brand/certkit-icon.png</webfeeds:icon>
    <webfeeds:logo>https://www.certkit.io/assets/images/brand/certkit-icon.svg</webfeeds:logo>
    <webfeeds:accentColor>047878</webfeeds:accentColor>

    <image>
      <url>https://www.certkit.io/assets/images/brand/certkit-icon.png</url>
      <title>CertKit SSL Certificate Management</title>
      <width>512</width>
      <height>512</height>
    </image>

    
    
    
    
    
    <item>
      <title>User management, MFA, SSO, and weekly summaries are live</title>
      <link>https://www.certkit.io/blog/user-management</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/user-management</guid>
      <pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/user-management#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/user-management/user-management.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/user-management/user-management.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[Cybersecurity]]>
      </category>
      <description>
        <![CDATA[CertKit now supports team accounts with role-based access, multi-factor authentication, SAML single sign-on, and a weekly email digest. Here&#39;s what shipped and why it matters.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/user-management/user-management.png" alt="User management, MFA, SSO, and weekly summaries are live" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>We’ve got a boatload of features to show off this week. We knocked out some of the most common requests, user management, single-sign on, and my personal favorite: the weekly email summary.</p>

<h2 id="user-management-and-roles">User management and roles</h2>

<p>You can now invite other users to your CertKit account. <strong>Administrators</strong> get full access. <strong>Regular Users</strong> get access to one or more application groups, so you can scope what each person can see and manage.</p>

<p>This pairs directly with the <a href="https://www.certkit.io/blog/application-management">Applications feature we shipped in January</a>. If you’ve organized your certificates into application groups already, you can now hand off management of specific groups to the right people without giving everyone the keys to everything.</p>

<p>Users also have a profile page where they can update their name and manage email preferences.</p>

<p>Plus, users can set up <strong>Multi-factor authentication</strong> with any TOTP authenticator app.</p>

<h2 id="saml-single-sign-on">SAML single sign-on</h2>

<p>If your organization runs an identity provider, you can now connect it to CertKit. Upload the metadata XML from your IdP and we’ll handle the rest. Your users authenticate through your existing SSO and you manage access from one place.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/user-management/sso-config.png" loading="lazy" alt="CertKit SSO configuration screen showing ACS URL and Entity ID fields" width="1200" height="547" />
</picture>

<h2 id="weekly-email-summary">Weekly email summary</h2>

<p>Every week, CertKit will send you a digest of your full account status: certificates, domain monitors, and agents, all in one view.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/user-management/email.png" loading="lazy" alt="CertKit weekly summary email showing domain, certificate, and agent status" width="1200" height="1071" />
</picture>

<p>It’s the thing you’d build yourself if you had time. A quick look each week to make sure nothing is quietly heading toward expiration or already broken. Red means something needs attention. Green means you can move on.</p>

<hr />

<p>All of these features are live now. If you’re on the beta, you’ll find them in your account settings. <a href="https://app.certkit.io/signup">Sign up for CertKit</a> to try it free, or <a href="https://www.certkit.io/book">book a demo</a> if you want a walkthrough.</p>

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> so you can stop worrying about who owns the renewal process.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Last call on 398-day certificates</title>
      <link>https://www.certkit.io/blog/last-call-on-398-day-certificates</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/last-call-on-398-day-certificates</guid>
      <pubDate>Mon, 02 Mar 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/last-call-on-398-day-certificates#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/last-call-on-398-day-certificates.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/last-call-on-398-day-certificates.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category>
      <description>
        <![CDATA[The bar closes March 15. After that, no CA can serve you a 398-day certificate. If you&#39;re still managing commercial SSL certs manually, you have two weeks to grab one last round of full-year runway before the 200-day era begins.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/last-call-on-398-day-certificates.png" alt="Last call on 398-day certificates" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>The bell rings. Last call for 398-day certificates is March 15.</p>

<p>After that, every CA is required to cut you off at 200 days. Some have already stopped serving them early. The rest follow in two weeks.</p>

<p>The irony of good certificate management is that when it works, nobody notices. No alerts, no outages, no 2am pages. The only time it gets attention is when something expires. Which means the teams doing it well rarely have the budget or the political capital to fix the process before it breaks.</p>

<p>March 15 is your excuse to fix it anyway. Here’s what to do before closing time.</p>

<h2 id="the-200-day-certificate-deadline">The 200-day certificate deadline</h2>

<p>A certificate issued this week gets you to early 2027, roughly 13 extra months compared to anything issued after the deadline. That’s one fewer renewal cycle to deal with right now, and enough time to get automation in place before the 100-day era arrives in March 2027. This isn’t about avoiding automation forever. It’s about doing it on your schedule instead of in a panic.</p>

<p>Here’s the schedule the CA/Browser Forum set with <a href="https://cabforum.org/working-groups/server/baseline-requirements/ballots/sc-081-introduce-schedule-of-reducing-validity-and-data-reuse-periods/">Ballot SC-081</a>:</p>

<ul>
  <li>March 15, 2026: 200-day maximum</li>
  <li>March 15, 2027: 100-day maximum</li>
  <li>March 15, 2029: 47-day maximum</li>
</ul>

<p>A certificate issued <em>after</em> March 15 gets 200 days. The deadline is based on when the certificate is issued, not when you place the order.</p>

<h2 id="the-math-on-doing-nothing">The math on doing nothing</h2>

<p>Here’s what manual certificate management looks like at each stage of the schedule. These are <em>minimum</em> renewals per certificate per year, assuming you renew right at expiration.</p>

<table>
  <thead>
    <tr>
      <th>Validity period</th>
      <th>Renewals per year</th>
      <th>For 10 certs</th>
      <th>For 50 certs</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>398 days (today)</td>
      <td>~1</td>
      <td>~10</td>
      <td>~50</td>
    </tr>
    <tr>
      <td>200 days (March 2026)</td>
      <td>~2</td>
      <td>~20</td>
      <td>~100</td>
    </tr>
    <tr>
      <td>100 days (March 2027)</td>
      <td>~4</td>
      <td>~40</td>
      <td>~200</td>
    </tr>
    <tr>
      <td>47 days (March 2029)</td>
      <td>~8</td>
      <td>~80</td>
      <td>~400</td>
    </tr>
  </tbody>
</table>

<p>If you have 50 certificates and you’re still handling renewals manually in 2029, that’s 400 renewal events a year. That’s not a process anymore, that’s a fulltime job.</p>

<h2 id="what-are-you-going-to-do-about-it">What are you going to do about it?</h2>

<p>Go renew any commercial certificates you have. <strong>Right now</strong>, before March 15 jumps up at you. Even if certs aren’t close to expiring. This buys you time to figure out what to do next.</p>

<p><strong>Do a search for certs you’ve forgotten about.</strong>  <a href="https://www.certkit.io/tools/ct-logs/">A certificate discovery scan</a> will show you the staging servers, internal tools, and other things you might have forgotten about. Go renew those certificates too.</p>

<p><strong>Use the runway to fix the process.</strong> With your new certs, you have until 2027 to figure this out. Get started on a project plan. Figure out the budget you need. You need to figure this out before 100-day certs drop on March 2027.</p>

<hr />

<p><em><a href="https://www.certkit.io">CertKit</a> can show you every certificate in your infrastructure, what’s expiring, and what you still have time to renew before March 15. Free during beta.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>CertKit Agent update: RRAS support, deploy windows, and agent locking</title>
      <link>https://www.certkit.io/blog/agent-1.6</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/agent-1.6</guid>
      <pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/agent-1.6#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/agent-1.6/agent-1.6.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/agent-1.6/agent-1.6.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[The CertKit Agent now supports Microsoft RRAS for VPN certificate management. We also added deploy windows so you can control when certificate updates happen, and agent locking to protect your infrastructure even if CertKit itself were ever compromised.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/agent-1.6/agent-1.6.png" alt="CertKit Agent update: RRAS support, deploy windows, and agent locking" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>The <a href="https://github.com/certkit-io/certkit-agent">CertKit Agent 1.6</a> is out. Three things in this release, all of them coming from the same underlying problem: the shorter certificate lifespans get, the more certificate deployment has to behave like real software deployments.</p>

<h2 id="microsoft-rras">Microsoft RRAS</h2>

<p>The CertKit Agent now supports Microsoft Routing and Remote Access Service (RRAS), which a lot of organizations use for point-to-point VPN.</p>

<p>RRAS is one of those things that’s been running quietly in the background for years, and nobody thinks about it until the certificate expires. At one-year validity that was annoying but manageable. At 47 days it becomes a recurring operations problem.</p>

<p>The wrinkle with RRAS is that it interrupts active connections when a certificate is updated. That’s fine when you’re renewing once a year. It’s a bigger deal when renewals are happening every six weeks.</p>

<p>Which brings us to the next feature.</p>

<h2 id="deploy-windows">Deploy windows</h2>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/agent-1.6/deploy-window.png" loading="lazy" alt="CertKit Agent deploy window configuration" width="1200" height="395" />
</picture>

<p>Deploy windows let you tell the agent when it’s allowed to renew certificates and run update commands on a given host. You pick the days and a time window. Renewals that happen outside that window will wait until the next allowed slot.</p>

<p>For RRAS and anything else that causes a service interruption during deployment, this means you can confine that disruption to a maintenance window. 2am Tuesday, Saturday morning, whatever fits your environment.</p>

<p>This works at the per-config level, so you can have different windows for different software, even on the same server.</p>

<h2 id="agent-locking">Agent locking</h2>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/agent-1.6/agent-lock.png" loading="lazy" alt="CertKit Agent locked state" width="1136" height="564" />
</picture>

<p>This one is a security feature, and it’s worth explaining why we built it.</p>

<p>The CertKit Agent can run arbitrary commands on your servers. That’s the whole point. You configure a restart command, the agent runs it. It’s convenient, and it’s what makes automated deployment work.</p>

<p>But it also means that if CertKit were ever compromised, an attacker could modify that command through our UI and use the agent as a foothold into your infrastructure. We don’t plan on getting compromised, but “we haven’t been hacked yet” is not a security model.</p>

<p>Agent locking addresses this. Once your agent is configured and working, you can lock it. A locked agent will continue to renew and deploy certificates, but its configuration cannot be changed from the CertKit UI. To make configuration changes, someone needs local admin access to the server to remove the lock file.</p>

<p>This means the blast radius of a CertKit compromise is limited to certificate delivery, not command execution. Your restart commands are frozen in place. We can push a new cert, but we can’t change what happens with it.</p>

<p>If you’re running the agent on production infrastructure, we recommend locking it once setup is complete.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> so you can stop thinking about SSL certificates.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>How likely is a man-in-the-middle attack?</title>
      <link>https://www.certkit.io/blog/man-in-the-middle</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/man-in-the-middle</guid>
      <pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/man-in-the-middle#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/man-in-the-middle.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/man-in-the-middle.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category>
      <description>
        <![CDATA[A stolen TLS private key sounds catastrophic. But thanks to forward secrecy, it can&#39;t decrypt recorded traffic. The only thing left is server impersonation, and that requires network position that ranges from &quot;be in the same room&quot; to &quot;be a nation-state.&quot; We looked at the data on how often this actually happens.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/man-in-the-middle.png" alt="How likely is a man-in-the-middle attack?" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>Security vendors love the man-in-the-middle attack. It’s the boogeyman of every TLS marketing page. Some shadowy figure intercepting your traffic, reading your secrets, stealing your data.</p>

<p class="aside">A <strong>man-in-the-middle</strong> attack is when an attacker positions themselves between two parties on a network to intercept the traffic flowing between them. In the context of TLS, that means an attacker who can present a valid certificate can read everything in plaintext and proxy it on to the real server.</p>

<p>But when was the last time you actually heard about one happening? Not a phishing attack. Not malware. Not credential stuffing. An actual man-in-the-middle interception of a TLS connection in the wild.</p>

<p>The Verizon <a href="https://www.verizon.com/business/resources/reports/dbir/">2025 Data Breach Investigations Report</a> analyzed over 22,000 security incidents. Credential abuse accounted for 22%. Ransomware showed up in 44% of breaches. Phishing was in 16%. The “Adversary-in-the-Middle” is less than 4% of incidents, and the vast majority of those are real-time phishing proxies like Evilginx, not someone intercepting TLS connections with stolen certificates.</p>

<p>The attack everyone worries about is the one that almost never happens.</p>

<h2 id="a-stolen-private-key-doesnt-get-you-very-far">A stolen private key doesn’t get you very far</h2>

<p>Let’s say the worst happens. An attacker steals a server’s TLS private key. Maybe they exploited a vulnerability. Maybe they found it in a git repo (please don’t do this). What can they actually do with it?</p>

<p>If you’re running any modern TLS configuration, less than you’d think. <a href="https://www.certkit.io/blog/perfect-forward-secrecy">Perfect Forward Secrecy</a> means <strong>a stolen private key can’t decrypt recorded traffic</strong>. Not past sessions or any future sessions. The “record now, decrypt later” scenario is dead for any connection using forward secrecy, which is now <a href="https://www.ssllabs.com/ssl-pulse/">about 94% of the web</a>. At least until quantum computing becomes a reality.</p>

<p>What a stolen key <em>can</em> do is let an attacker impersonate your server. They can present your real certificate, complete a valid TLS handshake, and proxy traffic onward to the real server, without any browser warnings.</p>

<p>But there’s a massive catch: To impersonate your server, the attacker has to intercept the connection before it reaches you. They need a man-in-the-middle network position.</p>

<h2 id="getting-in-the-middle-is-the-hard-part">Getting ‘in the middle’ is the hard part</h2>

<p>The difficulty of getting “in the middle” of a TLS connection varies enormously depending on where the attacker is and who they’re targeting. The spectrum runs from trivially easy to requiring the resources of an intelligence agency.</p>

<p><strong>On a local network,</strong> it’s embarrassingly simple. ARP spoofing requires nothing more than a laptop on the same network and a free tool like Bettercap. One command redirects all traffic on that LAN through the attacker’s machine.</p>

<p>Evil twin Wi-Fi attacks are just as easy. A $200 pineapple device or a Linux laptop running hostapd can clone any network name and force nearby devices to connect. In 2024, <a href="https://www.theguardian.com/technology/article/2024/jun/28/wa-man-fake-free-wifi-airports-data-theft-ntwnfb">Australian police arrested a man</a> who ran fake Wi-Fi networks on commercial airline flights, harvesting credentials from passengers.</p>

<p>These attacks are real, but their <em>scope is measured in meters, not miles</em>. The attacker has to be physically present, on the same network, within radio range of their targets. That’s not a scalable attack against your production infrastructure.</p>

<p><strong>DNS hijacking.</strong> Compromise a domain’s registrar account and you can redirect DNS queries to attacker-controlled servers. The most notable campaign, <a href="https://blog.talosintelligence.com/seaturtle/">Sea Turtle</a>, hit over 40 organizations across 13 countries by going after DNS registries directly. Cisco Talos assessed it as nation-state backed. They didn’t bother stealing private keys. They didn’t need to. They hijacked DNS and got fresh certificates from public CAs.</p>

<p><strong>BGP hijacking.</strong> BGP is how internet routers decide where to send traffic. It runs on trust, with no built-in authentication. If an attacker controls a router at an ISP or hosting provider, they can announce false routes and reroute traffic through their own infrastructure. In <a href="https://www.thousandeyes.com/blog/amazon-route-53-dns-and-bgp-hijack">2018</a>, attackers compromised a small Ohio ISP, hijacked Amazon Route 53 address space, and redirected MyEtherWallet users to a phishing server for two hours. They stole $150,000 in crypto. The attackers’ wallet already held $27 million. Not a casual operation.</p>

<p><strong>Physical backbone taps are pure nation-state.</strong> GCHQ’s TEMPORA program <a href="https://www.theguardian.com/uk-news/2013/jun/21/gchq-cables-secret-world-communications-nsa">tapped over 200 submarine cables</a>. Hundreds of millions of dollars. Cooperation from telecom providers. You’re not defending against this.</p>

<p>James Mickens put it best in his essay <a href="https://www.usenix.org/system/files/1401_08-12_mickens.pdf">This World of Ours</a>:</p>

<blockquote>
  <p>you’re either dealing with Mossad or not-Mossad. If you’re not-Mossad, good passwords and basic hygiene will keep you safe. If you are the Mossad, “the Mossad is not intimidated by the fact that you employ https://.”</p>
</blockquote>

<h2 id="what-actually-compromises-your-tls-connections">What actually compromises your TLS connections</h2>

<p>The attacks that <em>actually</em> compromise TLS connections happen at the endpoints.</p>

<p>In 2015, Lenovo shipped consumer laptops with <a href="https://www.eff.org/deeplinks/2015/02/further-evidence-lenovo-breaking-https-security-its-laptops">Superfish</a>, a pre-installed root CA that intercepted all HTTPS traffic to inject ads. Every affected laptop shared the same private key, protected by the trivially extracted password “komodia.” Once that key leaked, anyone on the same Wi-Fi as a Lenovo owner could silently intercept their banking, email, everything. Dell did the same thing months later with eDellRoot. A root certificate, bundled with its private key, that would reinstall itself if you deleted it.</p>

<p>This is the threat model that actually matters for most organizations. If an attacker compromises a user’s endpoint through malware, phishing, or a supply chain attack, they can install whatever root certificates they want. They don’t need your server’s private key. They don’t need network position. They own the device, so they own the TLS trust chain on that device.</p>

<p>The Verizon DBIR data backs this up. For small and medium businesses, <a href="https://www.verizon.com/business/resources/infographics/2025-dbir-smb-snapshot.pdf">88% of breaches involve ransomware</a>. System intrusion, social engineering, and basic web application attacks dominate the landscape. Stolen-key MITM doesn’t make the list.</p>

<h2 id="so-i-dont-need-to-protect-my-private-keys">“So I don’t need to protect my private keys?”</h2>

<p>Of course you do. They’re still secret, just not life-or-death important.</p>

<p>A compromised key can’t decrypt past traffic, but it could be used for targeted network impersonation. That’s a real risk, just not the five-alarm emergency.</p>

<p>The right response is proportional security. Encrypt keys at rest. Limit who and what can access them. Rotate them regularly. Use short-lived certificates so a compromised key has a smaller window of usefulness.</p>

<p>That’s exactly how we approach it at CertKit. Private keys in our database are encrypted using a key stored in our credential system combined with a salt compiled into the application. Decrypting them requires compromising both, independently. Agent communication is protected by agent-specific keypairs negotiated during authorization on top of TLS 1.3. No shared secrets between agents.</p>

<p>And for organizations that don’t want private keys leaving their network at all, we’re building the <a href="https://www.certkit.io/roadmap">CertKit Gateway</a>. Gateway runs on a server or container inside your infrastructure. It generates private keys locally and sends only the CSR to CertKit for validation and signing. The private key never leaves your network.</p>

<h2 id="spend-your-security-budget-on-the-threats-that-actually-happen">Spend your security budget on the threats that actually happen</h2>

<p>If you’re running a mid-sized business, the honest threat assessment is that this is a minor risk. The chance of someone stealing your TLS private keys and then executing a man-in-the-middle attack against your users is vanishingly small. Not zero. But small enough that it should sit well below credential hygiene, endpoint protection, phishing training, and ransomware preparedness on your priority list.</p>

<p>If you’re running critical infrastructure or a high-value financial target, the risk is real enough to invest in dedicated monitoring, RPKI deployment, hardware security modules, and aggressive key rotation. <a href="https://www.certkit.io/roadmap">CertKit Gateway is coming soon</a> for exactly this reason.</p>

<p>For everyone else? Automate your certificates so they don’t expire. Use short-lived certificates so a compromised key has a smaller window of usefulness. And spend your remaining security budget on the attacks that actually happen.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management. Start monitoring your certificates for free, or talk to us about CertKit Gateway for on-premises key management.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>BygoneSSL happened to us</title>
      <link>https://www.certkit.io/blog/bygonessl-happened-to-us</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/bygonessl-happened-to-us</guid>
      <pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/bygonessl-happened-to-us#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/bygonessl-happened-to-us.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/bygonessl-happened-to-us.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category>
      <description>
        <![CDATA[We wrote about BygoneSSL and the 1.5 million domains with certificates owned by someone else. Then we bought certkit.dev and found one on our own domain. A DigiCert certificate, still valid for 98 days, issued to whoever owned this domain before us. Here&#39;s what we found, what we tried to do about it, and what happened when we tried to revoke it.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/bygonessl-happened-to-us.png" alt="BygoneSSL happened to us" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>A few months ago I wrote about <a href="https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die">BygoneSSL and the 1.5 million domains with valid certificates owned by someone else</a>. Domains change hands but certificates don’t know. The old owner keeps their private key, and the certificate keeps working.</p>

<p>It’s an industry problem, but it turns out it’s our problem too.</p>

<p>We purchased <code class="language-plaintext highlighter-rouge">certkit.dev</code> for internal development and demos. I randomly used it as an example for our <a href="https://www.certkit.io/tools/ct-logs/">Certificate Transparency log search</a> and found a valid certificate issued by DigiCert.</p>

<p><a href="https://www.certkit.io/tools/ct-logs/certificate?serial=429b0800d695ddc654bb19bff8fb4dd">Still valid for another 100 days.</a></p>

<p>Someone we’ve never met holds a private key for one of our domains.</p>

<h2 id="how-worried-should-we-be">How worried should we be?</h2>

<p>Honestly? Not very. At least not in this case.</p>

<p>For someone to actually exploit this, they’d <a href="https://www.certkit.io/blog/man-in-the-middle">need to man-in-the-middle our traffic</a> with this old certificate. We weren’t running anything sensitive on <code class="language-plaintext highlighter-rouge">certkit.dev</code>. It’s a dev domain. And thanks to <a href="https://www.certkit.io/blog/perfect-forward-secrecy">Perfect Forward Secrecy</a>, even if someone had the private key, they couldn’t decrypt any previously captured traffic. The key only helps you impersonate, not eavesdrop on the past.</p>

<p>The realistic risk to us is close to zero.</p>

<p>But that’s for a small dev domain nobody’s targeting. Now imagine this is your payment processor, like Stripe. The original BygoneSSL research found this exact situation on <code class="language-plaintext highlighter-rouge">stripe.com</code>, where someone held a valid certificate for a payment processing domain for over a year after the sale. Same vulnerability, very different stakes.</p>

<p>The uncomfortable truth is that this is incredibly common. <a href="https://zanema.com/papers/imc23_stale_certs.pdf">The research found that 7% of all domains have valid certificates owned by previous owners</a>.</p>

<h2 id="trying-to-get-it-revoked">Trying to get it revoked</h2>

<p>So we have a BygoneSSL problem. Now what?</p>

<p>I didn’t issue this certificate and I don’t have a DigiCert account. I have no relationship with whoever owned <code class="language-plaintext highlighter-rouge">certkit.dev</code> before us. But I do own the domain now, and there’s a certificate out there that I’d like to not exist.</p>

<p>DigiCert’s documentation has an email address for exactly this situation: <code class="language-plaintext highlighter-rouge">revoke@digicert.com</code>. I sent them a clear request with the SHA256 fingerprint and serial number, explained that the organization no longer owns this domain, and asked what validation they’d need from me.</p>

<p>The first response came two hours later, addressed to “Tobb”, asking me to add a note under “this Order” so they could revoke the certificate.</p>

<p>What order? I don’t have an account. I didn’t place an order. That’s the entire point of this email. Someone <em>else</em> ordered this certificate for <em>my</em> domain.</p>

<p>I wrote back explaining the situation. This time DigiCert understood and gave me steps to validate that I owned the domain. Once complete, they said it would be revoked “shortly”.</p>

<p>From first email to revocation approval: about 4 hours across 6 emails. Not terrible once a human understood what I was asking. But the first response was a support agent reading from a script that assumed I was the certificate holder, not the domain owner. If I hadn’t known exactly what to ask for, or had given up after being told to log into an account that doesn’t exist, that certificate would still be sitting there untouched.</p>

<h2 id="certificate-revoked-in-theory">Certificate revoked, in theory</h2>

<p>DigiCert said the certificate would be revoked “shortly.” So I checked.</p>

<p>It took about 24 hours for the certificate to be <a href="https://crt.sh/?id=18583295353&amp;opt=ocsp">revoked on the Digicert’s OCSP and CRL</a>. But as of this writing (72 hours later), the certificate is still trusted by every browser on the planet.</p>

<p>This is <a href="https://www.certkit.io/blog/certificate-revocation-is-broken">certificate revocation</a> in practice. You can do everything right. Find the stale certificate. Contact the CA. Prove you own the domain. Get confirmation that revocation is happening. And the certificate keeps working anyway because the revocation infrastructure is held together with duct tape and good intentions.</p>

<p>Even when revocation eventually propagates to the CRLs, Chrome still only checks its own curated CRLSet covering a fraction of revoked certificates. Firefox’s CRLite updates on a delay. Safari does its own thing. Whether any given browser actually rejects this certificate after revocation depends on which browser, which revocation list, and when they last updated.</p>

<h2 id="this-is-why-certificate-lifetimes-are-shortening">This is why certificate lifetimes are shortening</h2>

<p>The industry knows this problem exists. <a href="https://www.certkit.io/blog/certificate-revocation-is-broken">Revocation has been broken for years</a> and nobody has a realistic plan to fix it. Their answer is shorter certificates. Under the <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">47-day certificate timeline</a> coming in 2029, maximum exposure from a domain ownership change drops from over a year to weeks.</p>

<p>Under 47-day lifetimes, our <code class="language-plaintext highlighter-rouge">certkit.dev</code> certificate would have expired before I even finished the domain purchase. Instead I spent an evening emailing back and forth with a CA, proved I own my own domain, got a confirmation, and the certificate is <em>still valid in every browser</em>.</p>

<p>47-day certificates won’t fix revocation. But they’ll make it matter a lot less.</p>

<h2 id="what-to-do-when-you-buy-a-domain">What to do when you buy a domain</h2>

<p>If you’re acquiring a domain, don’t assume it comes clean. Here’s what we’d recommend.</p>

<p>Search <a href="https://www.certkit.io/tools/ct-logs/">Certificate Transparency logs</a> for the domain before or immediately after purchase. You’ll see every certificate ever issued. If there’s something current that you didn’t request, you know you have a BygoneSSL situation.</p>

<p>Set CAA records on your DNS right away. CAA (Certificate Authority Authorization) records tell CAs which authorities are allowed to issue certificates for your domain. This won’t kill existing certificates, but it prevents new ones from being issued by unauthorized CAs.</p>

<p>File revocation requests with any CA that has outstanding certificates you didn’t authorize. Be prepared for this to be slow and confusing. If it’s a Let’s Encrypt certificate, you can revoke it yourself by proving domain control through ACME. Commercial CAs will make you work for it.</p>

<p>Set up <a href="https://www.certkit.io/">CT log monitoring</a> so you’ll know if anyone issues a new certificate for your domain in the future. This is the one thing you can actually stay on top of.</p>

<p>None of this is hard. But none of it is something anyone thinks about when buying a domain. The registrar doesn’t warn you. The CA doesn’t notify you. You have to go looking, and most people don’t.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management. Search your domain’s certificates for free with our <a href="https://www.certkit.io/tools/ct-logs/">CT Log Search</a> tool.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Introducing the CertKit Agent</title>
      <link>https://www.certkit.io/blog/certkit-agent</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/certkit-agent</guid>
      <pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/certkit-agent#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/certkit-agent/certkit-agent.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/certkit-agent/certkit-agent.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[CertKit can now deploy certificates directly to your servers. The CertKit Agent is a lightweight service for Linux, Windows, and Docker that detects your software, writes certificates where they need to go, and restarts your services automatically.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/certkit-agent/certkit-agent.png" alt="Introducing the CertKit Agent" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>Getting a certificate is the easy part. Getting it onto every server that needs it, in the right format, with the right permissions, and restarting the right services? That’s the part where things fall apart.</p>

<p>The CertKit Agent closes that gap, just released from our <a href="https://www.certkit.io/roadmap">product roadmap</a>.</p>

<h2 id="issue-deploy-verify">Issue, deploy, verify</h2>

<p>I wrote recently about the <a href="https://www.certkit.io/blog/issuance-automation-vs-certificate-automation">certificate automation loop</a>: <strong>issue → deploy → verify</strong>. Most tools only handle issuance. They get the cert signed and drop a file somewhere. Deployment is your problem.</p>

<p>The agent is how CertKit solves deployment. Install the agent on a host, tell it which certificates that host needs, and it handles the rest. When a certificate is renewed, the agent downloads it, writes the files in the correct format, sets ownership and permissions, and runs the restart command for your software. Pair it with CertKit’s domain monitoring and you have the complete certificate automation.</p>

<p>Here’s how it works:</p>

<div class="include blog-post-video">
  <lite-youtube videoid="u6ys6hUJLtA" videotitle="Installing the CertKit Agent for Certificate Automation on Linux" params="color=white&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0">
  </lite-youtube>
  <script src="/assets/vendor/lite-youtube/lite-youtube.min.js" defer=""></script>
</div>

<h2 id="how-it-works">How it works</h2>

<p>The agent runs as a background service on your host. On first launch, it registers with your CertKit account using a registration key. After that, it polls CertKit for certificate configurations you’ve assigned to it.</p>

<p>When a certificate changes, the agent writes the new files to the paths you configured, then executes your restart command. <code class="language-plaintext highlighter-rouge">systemctl reload nginx</code>, <code class="language-plaintext highlighter-rouge">Restart-Service W3SVC</code>, whatever your software needs.</p>

<p>It also auto-detects common web servers so you don’t have to configure paths manually. Right now it recognizes Nginx, Apache, HAProxy, LiteSpeed, and IIS, with more coming.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/certkit-agent/certkit-agent-config.png" loading="lazy" alt="CertKit Agent configuration" width="1200" height="526" />
</picture>

<h2 id="install-it-in-one-line">Install it in one line</h2>

<p>Just copy the install snippet from the CertKit UI, which already has your registration key embedded. It looks something like this:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo env </span><span class="nv">REGISTRATION_KEY</span><span class="o">=</span><span class="s2">"your.registration_key_here"</span> <span class="se">\</span>
  bash <span class="nt">-c</span> <span class="s1">'curl -fsSL https://app.certkit.io/agent/latest/install.sh | bash'</span>
</code></pre></div></div>

<p>The service will start automatically, and you will see a pending agent for you to configure in the UI. Alternatively, you can deploy it with Ansible, set it up as a scheduled task or cron job, or interact with it via the command line.</p>

<h2 id="open-source">Open source</h2>

<p>The agent is MIT licensed and <a href="https://github.com/certkit-io/certkit-agent">on GitHub</a>. You can read the code, audit the security model, or contribute. We think the thing that manages your private keys should be something you can inspect.</p>

<h2 id="available-now">Available now</h2>

<p>The agent is live for all CertKit users. Head to your <a href="https://app.certkit.io">CertKit dashboard</a> to generate a registration key and deploy your first agent.</p>

<p>If your web server isn’t auto-detected yet, <a href="https://github.com/certkit-io/certkit-agent/issues">open an issue</a> or <a href="https://www.certkit.io/contact">get in touch with us</a>.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> so you can stop worrying about deployments. <a href="https://www.certkit.io/how-it-works">See how it all fits together</a>.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Issuance Automation vs Certificate Automation</title>
      <link>https://www.certkit.io/blog/issuance-automation-vs-certificate-automation</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/issuance-automation-vs-certificate-automation</guid>
      <pubDate>Mon, 09 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/issuance-automation-vs-certificate-automation#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/certificate-automation.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/certificate-automation.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[ACME]]>
      </category>
      <description>
        <![CDATA[Most teams “automate certificates” by installing an ACME client and calling it a day. Then they still ship an outage because the hard parts were never automated: knowing what exists, keeping validation safe, and verifying what’s actually being served.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/certificate-automation.png" alt="Issuance Automation vs Certificate Automation" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>You’ve deployed certificate automation with Certbot and your artisanally-crafted scripts, but you still got paged at 2am for an expired cert. You’ve discovered the difference between <strong>issuance automation</strong> and <strong>certificate automation</strong>.</p>

<h2 id="certificate-automation-is-more-than-a-cron-job">Certificate automation is more than a cron job</h2>

<p>Operational certificate lifecycle is a loop. It repeats every renewal, hostname change, or emergency replacement:</p>

<blockquote>
  <p><strong>issue → deploy → verify</strong></p>
</blockquote>

<p><strong>Issue</strong> is proving control of the domain and getting the CA to sign the keypair/CSR. This is the “ACME did its thing” moment. If you want the mechanics, I wrote up <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">how ACME automates issuance</a>.</p>

<p><strong>Deploy</strong> is the hard part. It is getting the new certificate, in the correct format, to every place that serves traffic. Web servers, mail servers, load balancers, ingress controllers, app servers, sidecars, and that one legacy box you hate touching.</p>

<p><strong>Verify</strong> is proving that the endpoint is using the certificate you think it is, for the names you intended. Not “the file exists,” but “real clients see the new cert.” Verification means running a real TLS handshake against the public hostname and checking expiry, SANs, and chain. Almost nobody does this part.</p>

<p>Then the loop starts again because <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">certificates expire, soon every 47 days</a>.</p>

<h2 id="issuance-is-easy-to-automate">Issuance is easy to automate</h2>

<p>Lots of teams are really good at automating issuance. These tools solve getting a valid cert, not getting it live everywhere, or verifying that it works.</p>

<p>You can install Certbot. You can wire up DNS plugins. You can schedule renewals.</p>

<p>But that’s it. The CA says “ok.” The client exits 0. A file got written. It’s up to you to get it where it needs to go. And none of that proves it worked end-to-end.</p>

<h2 id="from-issuance-automation-to-certificate-automation">From issuance automation to certificate automation</h2>

<p>You don’t need “more Certbot.” Your <a href="https://www.certkit.io/blog/servers-shouldnt-need-acme">servers shouldn’t need to know how ACME works</a>. You need to make deployment reliable, and monitor that it worked.</p>

<p><strong>1. Deployment should be boring</strong>
A renewed cert that isn’t deployed everywhere is just a file. Build a repeatable rollout path to the places that terminate TLS (CDN, load balancer, ingress, app servers), and standardize the bundle format so you don’t lose hours to chain weirdness.</p>

<p><strong>2. Verification is the success signal</strong>
Stop celebrating “renewal succeeded.” The loop only completes when an external check proves the public endpoint is serving the expected cert and chain. If you can’t automatically verify it, you didn’t really automate it.</p>

<p><strong>3. Don’t pass out DNS keys</strong>
If DNS is in the loop, reduce the blast radius. Prefer patterns like <a href="https://www.certkit.io/blog/delegated-dns-validation">DNS delegation</a>, keep credentials scoped and centralized, and keep the TXT record lifecycle boring (create, validate, clean up).</p>

<p>Do those three things and shrinking certificate lifetimes are no big deal. The loop just runs more often, and nobody gets paged for it.</p>

<p>That’s the whole idea behind <a href="https://www.certkit.io/">CertKit</a>, it’s the missing layer that turns “we can renew a cert” into “we can reliably deploy and verify certificates everywhere they’re used.” <a href="https://www.certkit.io/how-it-works">See how it works</a>.</p>


        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Your servers shouldn't need to know ACME</title>
      <link>https://www.certkit.io/blog/servers-shouldnt-need-acme</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/servers-shouldnt-need-acme</guid>
      <pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/servers-shouldnt-need-acme#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/servers-shouldnt-need-acme.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/servers-shouldnt-need-acme.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[ACME]]>
      </category><category>
        <![CDATA[Let's Encrypt]]>
      </category>
      <description>
        <![CDATA[Your nginx doesn&#39;t need to understand ACME. Your mail server doesn&#39;t need DNS credentials. Your VPN appliance can&#39;t even run CertBot. They just need a certificate file. CertKit handles validation centrally and lets your servers subscribe to certificates.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/servers-shouldnt-need-acme.png" alt="Your servers shouldn't need to know ACME" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>CertBot assumes every server that needs a certificate should also know how to request one, validate domain ownership, handle renewals, and manage failures.</p>

<p>This makes sense with a handful of servers. One server, one cert, done. But infrastructures grow. Now you’ve got web farms sharing wildcards, load balancers, mail servers, VPN appliances. The “every server for itself” model doesn’t scale and isn’t sustainable.</p>

<p>Even the Let’s Encrypt community knows it. When asked what would make Certbot scale better, a maintainer responded bluntly: “If someone has ‘a large number of certificates’ they should not be using Certbot… Certbot has been positioned as the ‘entry level’ and ‘swiss army knife’ of ACME clients.”</p>

<p>Entry level is not exactly a ringing endorsement for managing your production infrastructure.</p>

<h2 id="how-acme-breaks-down">How ACME breaks down</h2>

<p>With CertBot, ACME is a distributed responsibility model. Each server handles its own validation, each server manages its own renewals, and each server needs to handle its own errors.</p>

<h3 id="certificate-distribution">Certificate distribution</h3>

<p>Dozens of servers often need to <a href="https://www.certkit.io/blog/do-you-still-need-wildcard-certificates">share a wildcard certificate</a>. How do you handle that? One server requests it, then you distribute it to the others. The official CertBot guidance for this scenario is basically “figure it out yourself.”</p>

<p>So we build workarounds. Rsync cron jobs. NFS mounts. Ansible playbooks that copy certificates around. You’ve <a href="https://www.certkit.io/blog/why-you-built-your-own-certificate-management">poorly reinvented a centralized certificate manager</a>.</p>

<p>The Let’s Encrypt forums are full of confused admins trying to solve this:</p>

<blockquote>
  <p>I’ve read through a number of topics but can’t decide on the best approach to use when Let’s Encrypt is to be used with multiple servers.</p>
</blockquote>

<blockquote>
  <p>The problem arrives when I tried to introduce a load balancer and additional nodes… I’m afraid the auto renew process will fail as the challenge might be distributed to a different node.</p>
</blockquote>

<p>Nobody has a great answer.</p>

<h3 id="monitoring-a-distributed-system">Monitoring a distributed system</h3>

<p>Distributed certificate automation has two failure points: renewing the certificate, and getting the running service to use it. Both can fail silently, anywhere in your infrastructure. It’s on you to monitor every system to make sure neither breaks.</p>

<p>Epic Games had certificate monitoring. When a wildcard cert expired in April 2021, they <a href="https://www.epicgames.com/site/en-US/expiration-date-4-6-2021">identified the problem within 12 minutes</a>. Recovery still took 5.5 hours.</p>

<p>Why? The certificate was used across “hundreds of internal back-end service-to-service calls.” Renewing it was just the first step. Then they had to roll it out to every service that needed it, verify each one picked up the new cert, and deal with the cascading failures that had already started. They later admitted they “believed that we were more protected than we actually were.”</p>

<p>Knowing about the problem isn’t the same as fixing it when your certificates are scattered across infrastructure.</p>

<h3 id="the-skeleton-key-problem">The skeleton key problem</h3>

<p>Distributed validation doesn’t just create operational headaches. It creates security exposure.</p>

<p>HTTP-01 validation requires every server to expose port 80 and serve challenge files. That’s attack surface multiplied across your entire infrastructure. In January 2026, researchers disclosed a <a href="https://www.theregister.com/2026/01/20/cloudflare_fixes_acme_validation/">Cloudflare WAF bypass</a> that exploited ACME challenge paths, where security controls were deliberately relaxed to allow certificate validation.</p>

<p>DNS-01 validation is worse. <a href="https://www.certkit.io/blog/delegated-dns-validation">Every server with DNS credentials holds keys to your entire domain</a>. The EFF warns explicitly: “If the machine handling the process gets compromised, so will the DNS credentials, and this is where the real danger lies.”</p>

<p>DNS credentials don’t just issue certificates. They control email routing, traffic direction, everything. One compromised web server and an attacker can redirect your domain, issue valid certificates for it, or intercept email by modifying MX records.</p>

<h2 id="flipping-acme-on-its-head">Flipping ACME on its head</h2>

<p>The issue is that <a href="https://www.certkit.io/blog/issuance-automation-vs-certificate-automation">certificate <em>issuance</em> and certificate <em>deployment</em> are different problems</a>. CertBot conflates them.</p>

<p>Your nginx server doesn’t need to understand ACME. Your mail server doesn’t need DNS API credentials. Your VPN appliance probably can’t run CertBot.</p>

<p>They just need a certificate file.</p>

<p>CertKit separates these concerns. CertKit is the ACME client. One system handles domain validation, certificate requests, and renewals. Your servers never talk to the certificate authority. They never hold DNS credentials. They don’t need to understand ACME at all.</p>

<p>Instead of every server renewing its own certificates, CertKit lets your server subscribe to the certificates they need, and pull them automatically whenever they change. You install a lightweight agent that says “give me the cert for example.com” When the cert renews, the agent gets the new one automatically. No special ports. No DNS credentials on the box. No ACME knowledge required.</p>

<p>The certificates exist independently of your servers. Even if you never installed a single agent, CertKit would keep requesting, renewing, and storing valid certificates for your domains. Your infrastructure subscribes to certificates it needs.</p>

<h2 id="this-matters-more-every-year">This matters more every year</h2>

<p>Certificate lifespans keep shrinking. <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">47-day certificates arrive in 2029</a>. What’s merely annoying with annual renewals becomes impossible at that pace.</p>

<p>One sysadmin’s reaction to the 47-day proposal captured the frustration: “This is somewhat nightmarish. I have about 20 appliance-like services that have no support for automation.” VPN servers, load balancers, proxy servers, network gear. None of these can run CertBot.</p>

<p>But they can all receive a certificate file.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management. <a href="https://www.certkit.io/how-it-works">See how it works</a>. Currently in beta.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Let's Encrypt is moving to 45-day certificates before everyone else</title>
      <link>https://www.certkit.io/blog/45-day-certificates</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/45-day-certificates</guid>
      <pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/45-day-certificates#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/45-day-certificates.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/45-day-certificates.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Let's Encrypt]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[ACME]]>
      </category>
      <description>
        <![CDATA[The CA/Browser Forum set 47-day certificates as the target for 2029. Let&#39;s Encrypt decided to implement it a year earlier. Here&#39;s their roadmap and what it means for your automation.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/45-day-certificates.png" alt="Let's Encrypt is moving to 45-day certificates before everyone else" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>The CA/Browser Forum set <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">47-day certificates as target for 2029</a>. Let’s Encrypt decided to implement it a year earlier.</p>

<p>In December 2025, Let’s Encrypt <a href="https://letsencrypt.org/2025/12/02/from-90-to-45">announced their roadmap</a> to cut certificate lifetimes from 90 days to 45 days by February 2028, a full year ahead of the industry mandate.</p>

<p>It’s exactly what we’d expect from the CA that made automation mandatory from day one.</p>

<h2 id="the-timeline">The timeline</h2>

<p>Right now, Let’s Encrypt certificates are valid for 90 days with a 30-day authorization reuse period. That means once you prove you control a domain, you can issue certificates for it without re-validating for the next month.</p>

<p>Here’s how that’s changing:</p>

<ul>
  <li><strong>May 2026:</strong> You can opt-in to 45-day certificates for early adopters and anyone who wants to test their automation can switch now.</li>
  <li><strong>February 2027:</strong> Certificate lifetimes drop to <strong>64-days</strong> and 10-day authorization reuse.</li>
  <li><strong>February 2028:</strong> Certificate lifetimes drop to <strong>45-day</strong>  with 7-hour authorization reuse. This is the new normal.</li>
</ul>

<p>Let’s Encrypt is giving you staging environment access about a month before each production date.</p>

<h2 id="why-lets-encrypt-is-going-first">Why Let’s Encrypt is going first</h2>

<p>Let’s Encrypt was <a href="https://www.certkit.io/blog/should-you-still-pay-for-ssl-certificates">built for automation</a>. They’ve always assumed you’re not manually renewing certificates. Their entire architecture, from <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">the ACME protocol</a> to rate limits to their support model, assumes automated clients.</p>

<p>If your renewals are already automated, going from 90 days to 45 days or even 6 days is trivial detail. Your client just runs slightly more often.</p>

<p>The people who will struggle are the ones who were never really automated in the first place. The ones running certbot manually every few months. The ones with “renew certificates” as a recurring calendar reminder. <a href="https://www.certkit.io/">We can help you</a>.</p>

<h2 id="authorization-reuse-is-the-bigger-change">Authorization reuse is the bigger change</h2>

<p>Certificate lifetime gets all the headlines, but authorization reuse going from 30 days to 7 hours is arguably more disruptive.</p>

<p>Today, you can validate a domain and issue multiple certificates over the next month without re-validating. Need a cert for staging? Already validated. Spinning up a new subdomain? Already validated. That flexibility disappears.</p>

<p>With 7-hour authorization reuse, every certificate request essentially requires fresh validation. If your automation assumes you can batch certificate operations across a day, that breaks.</p>

<p>That’s why <a href="https://www.certkit.io/blog/delegated-dns-validation">delegated DNS validation</a> is important. It lets you offload the constant work updating your validation tokens to a dedicated service (like CertKit). You just set up a CNAME once, and your certificate service handles the TXT record updates without needing your DNS credentials.</p>

<p><a href="https://www.certkit.io/blog/dns-persist-01">DNS-PERSIST-01</a> makes it even easier, letting you set a single DNS record for the entire domain. The new validation method lets you authorize a CA once and skip re-validation entirely. Let’s Encrypt committed to implementing it in 2026, explicitly as an enabler for shorter certificate lifetimes.</p>

<h2 id="what-you-need-to-do">What you need to do</h2>

<p>If you’re running a modern Certbot with default settings, you’re probably fine. Certbot 4.1.0 (released June 2025) added support for ACME Renewal Information (ARI), which lets the CA tell your client when to renew. With ARI enabled, Certbot automatically adjusts to whatever certificate lifetime Let’s Encrypt issues.</p>

<p>Check your version:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>certbot <span class="nt">--version</span>
</code></pre></div></div>

<p>If you’re below 4.1.0, it’s time to upgrade. Or better yet, switch to <a href="https://www.certkit.io/">centralized certificate automation</a>.</p>

<p>The thing that will break you is hardcoded renewal intervals. If your automation says “renew every 60 days” regardless of certificate lifetime, that stops working in February 2028. A 45-day certificate renewed at 60 days is an expired certificate.</p>

<h2 id="certkit-and-the-45-day-future">CertKit and the 45-day future</h2>

<p>CertKit uses Let’s Encrypt as our preferred certificate issuer. When their timelines change, our renewal cycles adapt automatically. You won’t need to reconfigure anything.</p>

<p>We’ve added <a href="https://www.certkit.io/roadmap">ARI support to our roadmap</a> to ensure we’re renewing at exactly the right time rather than relying on static intervals. When Let’s Encrypt tells us a certificate needs early renewal (like after a revocation event), we’ll respond immediately.</p>

<p>Certificate lifetimes will keep getting shorter. That won’t matter to you. Certificates in CertKit are always automatically renewed and refreshed. That’s the whole point.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management so certificate lifetimes are someone else’s problem.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Certificate permissions with CertKit Applications</title>
      <link>https://www.certkit.io/blog/application-management</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/application-management</guid>
      <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/application-management#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/application-management/application-management.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/application-management/application-management.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[As your certificate count grows, so does the chaos. Applications let you organize certificates into logical groups with their own API keys and access controls. No more sharing credentials across your entire infrastructure.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/application-management/application-management.png" alt="Certificate permissions with CertKit Applications" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>When you’re managing a handful of certificates, one big list works fine. Add a few dozen more and things get messy. Add multiple teams or projects and you’ve got a problem.</p>

<p>Who should have access to the production certificates? What about staging? Does the contractor working on the marketing site really need to see your internal infrastructure?</p>

<p>CertKit now supports <strong>multiple applications</strong> from <a href="https://www.certkit.io/roadmap">our roadmap</a> to help you sort this out.</p>

<h2 id="what-are-applications">What are applications?</h2>

<p>Applications are independent groups of certificates, domains, and hosts. Each application has its own storage bucket and access credentials. Think of them like security boundaries for your certificate infrastructure.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2026/application-management/application-dashboard.png" loading="lazy" alt="CertKit Applications Dashboard" width="1800" height="560" />
</picture>

<p>You might create separate applications for each product you run. Or split by environment (production, staging, development). Or by team. Whatever makes sense for how you actually work.</p>

<h2 id="scoped-api-keys">Scoped API keys</h2>

<p>Access and API keys are managed at the application level.</p>

<p>Before, one API key meant access to everything in your account. Now you can generate keys scoped to specific applications. Your deployment scripts for the marketing site only touch marketing certificates. Your production automation only sees production infrastructure.</p>

<p>If a key gets compromised (or a contractor leaves), you revoke it without affecting everything else.</p>

<h2 id="available-now">Available now</h2>

<p>All CertKit users can create up to 6 applications today. If you need more, just ask and we’ll enable them for your account.</p>

<p>Head to your <a href="https://app.certkit.io">CertKit dashboard</a> to start organizing your certificates.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> so you can focus on literally anything else.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Delegated DNS validation: proving domain ownership without exposing credentials</title>
      <link>https://www.certkit.io/blog/delegated-dns-validation</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/delegated-dns-validation</guid>
      <pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/delegated-dns-validation#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/delegated-dns-validation.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/delegated-dns-validation.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[ACME]]>
      </category><category>
        <![CDATA[DNS]]>
      </category>
      <description>
        <![CDATA[Every service you onboard wants proof you control your domain. Most want your DNS credentials to automate that proof. There&#39;s a better approach: CNAME delegation lets you authorize a service once without handing over the keys to your entire zone.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/delegated-dns-validation.png" alt="Delegated DNS validation: proving domain ownership without exposing credentials" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>It seems like every service wants proof you control your domain.</p>

<p>Certificate authorities need it to issue certificates. Email platforms need it to authorize sending. Analytics needs it to gather data. Just add this magic TXT record to your DNS, wait for propagation, click verify.</p>

<p>It works fine when it’s a one-time setup, but <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">certificate lifetimes are dropping to 47 days</a>, and you won’t be able to keep up on that schedule. You’ll have to automate, and now dozens of systems are changing your DNS.</p>

<h2 id="the-credential-problem">The credential problem</h2>

<p>DNS validation works by proving you can modify records in a zone. You add a special TXT record, the service queries for it, validation complete.</p>

<p>To do that automatically, you need API credentials. And most DNS providers don’t offer fine-grained permissions. You can’t say “this token can only create TXT records at <code class="language-plaintext highlighter-rouge">_acme-challenge.example.com</code>.” You hand over credentials that can modify your entire zone.</p>

<p>Now multiply that across every system that needs DNS validation to renew its certificate. That’s a huge attack surface. Each one capable of redirecting all your traffic, intercepting all your email, or poisoning your DNS entirely.</p>

<h2 id="what-is-delegated-domain-validation">What is delegated domain validation?</h2>

<p>But there’s a better way! Instead of giving each service credentials to modify your DNS, you can delegate just the validation record to them.</p>

<p>Say a service needs to validate <code class="language-plaintext highlighter-rouge">_acme-challenge.example.com</code>. Instead of giving it DNS API access, you create a single CNAME record:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_acme-challenge.example.com.  IN  CNAME  abc123.challenges.certkit.io.
</code></pre></div></div>

<p>That’s it. One record, set one time.</p>

<p>When a service needs to complete a validation challenge, they don’t touch your DNS at all. They update a TXT record in their own zone at <code class="language-plaintext highlighter-rouge">abc123.challenges.certkit.io</code>. When the validating party queries <code class="language-plaintext highlighter-rouge">_acme-challenge.example.com</code>, DNS follows the CNAME and finds the current challenge token updated by CertKit.</p>

<p>You’ve delegated the validation, not the zone.</p>

<p>That <code class="language-plaintext highlighter-rouge">abc123</code> is a unique token that binds this delegation to your specific account. If you ever stop using the service and remove the CNAME, nobody else can claim that validation target and start issuing certificates for your domain.</p>

<p>The IETF is formalizing this pattern in an upcoming Best Current Practice document, <a href="https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-domain-verification-techniques-10">Domain Control Validation using DNS</a>.</p>

<blockquote>
  <p>Delegated domain control validation lets a User delegate the domain control validation process for their domain to an Intermediary without granting the Intermediary the ability to make changes to their domain or zone configuration.</p>
</blockquote>

<p>You’re proving control of your domain without giving anyone else control of your domain.</p>

<h2 id="why-cname-delegation-is-safer">Why CNAME delegation is safer</h2>

<p>With traditional DNS validation, your certificate service holds credentials that can modify any record in your zone. If those credentials leak, an attacker can do anything: redirect your website, intercept your email, issue fraudulent certificates for your domain.</p>

<p>With CNAME delegation, the worst case is different. If your certificate provider is compromised, an attacker can respond to validation challenges for your domain. That’s bad, but it’s bounded. They can’t redirect traffic that isn’t already going through that provider.</p>

<p class="aside">Related, the ACME working group is developing <a href="https://www.certkit.io/blog/dns-persist-01">DNS-PERSIST-01</a>, a new validation method addressing the operational and security risks of domain validation. Instead of proving control ‘right now’ with a fresh challenge, DNS-PERSIST-01 lets you set a persistent authorization record once. Combined with CNAME delegation, nothing changes on any renewal. Ever.</p>

<h2 id="how-certkit-handles-this">How CertKit handles this</h2>

<p>CertKit uses CNAME delegation for DNS validation. You point your <code class="language-plaintext highlighter-rouge">_acme-challenge</code> record to us once, and we handle every certificate validation from there.</p>

<p>You never give us credentials to your DNS provider. We can’t touch your zone. We can only respond to ACME challenges for domains you’ve explicitly delegated to us.</p>

<p>Your DNS zone stays yours. We just handle the certificates.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>What should we build next?</title>
      <link>https://www.certkit.io/blog/what-should-we-build-next</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/what-should-we-build-next</guid>
      <pubDate>Wed, 14 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/what-should-we-build-next#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/what-should-we-build-next.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/what-should-we-build-next.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[We just published our product roadmap. It&#39;s interactive. Vote on what matters to you, or tell us what we&#39;re missing entirely.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/what-should-we-build-next.png" alt="What should we build next?" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>We just published <a href="https://www.certkit.io/roadmap">the CertKit roadmap</a>.</p>

<h2 id="product-roadmap">Product roadmap</h2>

<p>Most company roadmaps are vague promises about “AI-powered synergies” and “enhanced platform capabilities” that mean absolutely nothing. Ours is different. It’s a list of features we’re actually building.</p>

<p>More importantly, it’s interactive.</p>

<p>Every feature has a vote button. Click it. Tell us if you want it or if you couldn’t care less. We’re a small team, and we’d rather build what you actually need than guess.</p>

<p>Right now we’re working on a <strong>Host Agent</strong> for distributing certificates to your infrastructure. High on the list after that: SSO, user roles, advanced alerting, and certificate tags for organizing the chaos.</p>

<p>Further out, we’ve got some ideas we’re not sure about yet. Private CA support. Other ACME issuers beyond Let’s Encrypt. A Certificate Transparency Log API for the power users. These might be brilliant or they might be solutions looking for problems. You tell us.</p>

<p>And if the feature you desperately need isn’t on the list at all? <a href="https://www.certkit.io/contact">Let us know</a>. We’ve added features based on a single email before. We’ll do it again.</p>

<p>The roadmap is at <a href="https://www.certkit.io/roadmap">certkit.io/roadmap</a>. Go vote on something.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management so you can stop thinking about SSL certificates.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Should you still pay for SSL certificates?</title>
      <link>https://www.certkit.io/blog/should-you-still-pay-for-ssl-certificates</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/should-you-still-pay-for-ssl-certificates</guid>
      <pubDate>Mon, 12 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/should-you-still-pay-for-ssl-certificates#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/pay-for-ssl-certificates.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/pay-for-ssl-certificates.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Let's Encrypt]]>
      </category><category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category>
      <description>
        <![CDATA[IT teams keep buying certificates from DigiCert and Sectigo because free feels risky. But the assumptions behind that trust are a decade old. Let&#39;s Encrypt now secures 64% of the web, is funded by Google and AWS, and uses the same encryption as your $500 certificate. The real question isn&#39;t whether free is good enough. It&#39;s whether you&#39;ve examined your objections lately.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/pay-for-ssl-certificates.png" alt="Should you still pay for SSL certificates?" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>There’s a particular flavor of skepticism that shows up whenever someone suggests using Let’s Encrypt. The security team crosses their arms. “Free certificates? For production? We’re a serious organization. We use Sectigo.”</p>

<p>I get it. You’ve been buying certificates from the same vendors for twenty years. They send you invoices, you pay them, certificates appear. It feels responsible, and free feels like a trap.</p>

<p>But is it?</p>

<h2 id="what-is-lets-encrypt">What is Let’s Encrypt?</h2>

<p><a href="https://letsencrypt.org/">Let’s Encrypt</a> is a certificate authority operated by the Internet Security Research Group, a 501(c)(3) nonprofit founded in 2013 by engineers from Mozilla. They started issuing certificates in 2015 and <a href="https://w3techs.com/technologies/history_overview/ssl_certificate/all/y">by 2026 holds 60% market share</a>. Internet infrastructure like Cloudflare, Github, and Mozilla use Let’s Encrypt.</p>

<h2 id="youre-not-paying-for-better-encryption">You’re not paying for better encryption</h2>

<p>A free Let’s Encrypt certificate uses the same encryption as that $500 Extended Validation certificate. The only difference is the paperwork that you are who you say you are. Domain Validation (DV) certificates only verify you control the domain, but it turns out that’s all anyone really cares about.</p>

<p>Organization Validation (OV) verifies your business exists. Extended Validation (EV) adds sixteen additional identity checks. That sounds important until you learn that EV and OV certificates haven’t mattered in over five years.</p>

<p>Chrome killed the green address bar in 2018 and removed company names entirely in 2019. Safari and Firefox followed. <a href="https://groups.google.com/a/chromium.org/g/security-dev/c/h1bTcoTpfeI/m/jUTk1z7VAAAJ">Google’s security team published research showing users didn’t make safer choices when EV indicators were present</a>. So they got rid of them.</p>

<p>Amazon, Google, Shopify, ChatGPT, and the IRS all use standard DV certificates. These companies have unlimited security budgets. They chose DV anyway because the other stuff doesn’t actually matter.</p>

<h2 id="lets-encrypt-is-more-sustainable-than-your-ca">Let’s Encrypt is more sustainable than your CA</h2>

<p>“But what happens when the free CA goes away? At least DigiCert will be around.”</p>

<p>Will they?</p>

<p>DigiCert is owned by Clearlake Capital, Sectigo is owned by GI Partners. Private equity ownership means the company exists to generate returns for investors. Deliver a locked-in service as cheaply as possible until you’ve extracted every penny from it. Ask Toys ‘R Us how that goes.</p>

<p>Let’s Encrypt, on the other hand, is funded by donations from organizations that depend on the CA ecosystem remaining competitive. <a href="https://www.abetterinternet.org/documents/2024-ISRG-Annual-Report.pdf">Their 2024 financials</a> show $9.56 million in revenue, $5.1 million in net assets, and 27 employees running infrastructure for 762 million websites. Sponsors include Google, Amazon Web Services, Mozilla, EFF, Cisco, IBM, and Shopify.</p>

<p>These sponsors <em>need</em> Let’s Encrypt to exist. A free CA with 60% market share gives them leverage against commercial certificate pricing. Google and AWS aren’t funding Let’s Encrypt out of charity. They’re funding it because the alternative is letting DigiCert and Sectigo set prices and dictate technology requirements.</p>

<p>That’s more sustainable than private equity.</p>

<h2 id="the-commercial-cas-have-the-worse-track-record">The commercial CAs have the worse track record</h2>

<p>Let’s Encrypt has operated since 2015 with no security breaches of CA infrastructure. In 2020, they discovered <a href="https://community.letsencrypt.org/t/2020-02-29-caa-rechecking-bug/114591">a bug in their CAA checking code that affected about 3 million certificates</a>. They disclosed it immediately, patched it within hours, and began revocations within days. Their 90-day certificate lifetime meant all remaining affected certificates expired naturally within weeks.</p>

<p>Compare that to the commercial CAs.</p>

<p>In July 2024, DigiCert discovered they’d been <a href="https://www.digicert.com/support/certificate-revocation-incident">issuing certificates with improper domain validation for five years</a>. A missing underscore prefix in their verification system. They gave customers 24 hours to replace 83,000 certificates. <a href="https://www.cisa.gov/news-events/alerts/2024/07/30/digicert-certificate-revocations">CISA issued an emergency alert</a>. Critical infrastructure operators couldn’t meet the deadline. Some customers sued.</p>

<p>That same year, Google, Apple, and Mozilla all <a href="https://security.googleblog.com/2024/06/sustaining-digital-certificate-security.html">announced they would stop trusting certificates from Entrust</a>, one of the oldest commercial CAs. Google cited “a pattern of compliance failures, unmet improvement commitments, and the absence of tangible, measurable progress” over six years. Entrust had delayed revocations, missed deadlines, and failed to meet the standards every CA agrees to follow.</p>

<p>The free nonprofit CA has a cleaner record than the paid alternatives.</p>

<h2 id="when-paying-actually-makes-sense">When paying actually makes sense</h2>

<p>I’m not going to pretend there’s never a reason to buy certificates.</p>

<p>There are <a href="https://www.eba.europa.eu/publications-and-media/press-releases/eba-publishes-opinion-use-eidas-certificates-under-psd2">some banking</a> and healthcare compliance requirements that dictate OV and EV certificates.</p>

<p>Or maybe you need contractual Service Level Agreements. If your procurement department requires a vendor agreement with guaranteed uptime commitments, Let’s Encrypt won’t sign one.</p>

<p>Or maybe you require a phone number for support. Let’s Encrypt won’t do that either, it just a support forum.</p>

<p>But maybe you should push back on that. In 2026, certificates are a <strong>standardized commodity</strong>. You don’t need a contract SLA from Lowes to buy a lightbulb. You don’t need to call McDonalds to debug your hamburger. If something’s wrong with your certificate, just generate a new one.</p>

<h2 id="the-question-you-should-actually-be-asking">The question you should actually be asking</h2>

<p>The objection to Let’s Encrypt usually comes down to “free feels risky.” But the evidence points the other way. They issue 60% of certificates, including ones at companies that sell you security tools.</p>

<p>The real question isn’t whether Let’s Encrypt is good enough for your organization. It’s whether your objections are based on current evidence or just institutional habit.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> so you can stop thinking about SSL certificates entirely.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>DNS-PERSIST-01 validates a domain once to get certificates forever</title>
      <link>https://www.certkit.io/blog/dns-persist-01</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/dns-persist-01</guid>
      <pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/dns-persist-01#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2026/dns-persist-01.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2026/dns-persist-01.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Let's Encrypt]]>
      </category><category>
        <![CDATA[ACME]]>
      </category><category>
        <![CDATA[DNS]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[A new ACME validation standard coming in 2026 lets you authorize a CA once and never touch DNS again for renewals. The security model is defensible, but even its supporters admit the optics are questionable.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2026/dns-persist-01.png" alt="DNS-PERSIST-01 validates a domain once to get certificates forever" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>With the <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">ACME protocol</a>, to issue a certificate you have to prove you control the domain. The CA gives you a challenge, you complete it, and they issue your cert.</p>

<p>The trouble is that every validation method has tradeoffs. And as certificate lifetimes get shorter, those tradeoffs will get more painful. DNS-PERSIST-01 is a new approach coming in 2026 that trades proof-of-freshness for easier operations.</p>

<h2 id="acme-validation-methods">ACME validation methods</h2>

<p><strong>HTTP-01</strong> is the easiest to understand. The CA gives you a token, you host it in a file at <code class="language-plaintext highlighter-rouge">http://example.com/.well-known/acme-challenge/</code>, and the CA fetches it. Proof of control. Done.</p>

<p>But HTTP-01 means opening port 80 to the public internet, and that can be scary. Not everyone wants their certificate validation infrastructure exposed to the world.</p>

<p><strong>DNS-01</strong> lets you hide your internal systems. Instead of serving a file, you create a DNS TXT record at <code class="language-plaintext highlighter-rouge">_acme-challenge.example.com</code>. The CA queries DNS, finds your token, and you’re validated. No open ports.</p>

<p>The problem is that changing DNS records can be unreliable at best and risky at worst. DNS is famously problematic due to its slow refresh and caching cycles. Nine times out of ten with any major outage, it comes down to DNS.</p>

<p>For your systems to create DNS validation records, they need API credentials, often with broad permissions. For better or worse, DNS has become a skeleton key can unlock everything and cause lots of trouble if compromised. I really don’t want every system in my infrastructure to have my DNS keys.</p>

<h2 id="what-is-dns-persist-01">What is DNS-PERSIST-01?</h2>

<p><strong>DNS-PERSIST-01</strong> is a new ACME challenge type that eliminates the DNS-01 “change DNS on every renewal” problems. Instead of creating a fresh TXT record for each validation, you create one persistent record that authorizes <em>a specific CA and account</em> indefinitely.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_validation-persist.example.com. IN TXT
"letsencrypt.org; accounturi=https://letsencrypt.org/acme/acct/123456; policy=wildcard"
</code></pre></div></div>

<p>That’s it. You’re telling Let’s Encrypt (or whatever CA you specify) that ACME account 123456 is authorized to get any certificate it needs for example.com. Forever, or at least until the optional <code class="language-plaintext highlighter-rouge">persistUntil</code> timestamp expires.</p>

<h2 id="the-honest-tradeoff">The honest tradeoff</h2>

<p>DNS-PERSIST-01 is a different approach to validation than the other methods. It trades real-time validation for operational efficiency.</p>

<p>Aaron Gable, an engineer at Let’s Encrypt, <a href="https://groups.google.com/a/groups.cabforum.org/g/servercert-wg/c/ctYFczlzT5Y/m/ubHePxsCAgAJ">described the tradeoff on the CAB Forum mailing list</a>:</p>

<blockquote>
  <p>The [DNS-PERSIST-01] security model is sound and has real advantages; but the ergonomics and optics are bad.</p>
</blockquote>

<p>While the spec still requires a “random value” in the traditional sense (your account URI is effectively that value), Gable admits that because it doesn’t change this feels like theater:</p>

<blockquote>
  <p>The fact that it still involves a Random Token even though checking for the presence of that random token achieves nothing feels like pulling the wool over one’s eyes.</p>
</blockquote>

<p>This is refreshingly honest for a standards discussion. The people building DNS-PERSIST-01 aren’t pretending it’s a strict improvement. It’s a tradeoff. You get massive operational simplification. You lose proof-of-freshness.</p>

<p>The security model does work. Your ACME account is cryptographically bound to a keypair. If someone compromises that keypair, they can issue certificates for any domain where you’ve set up persistent validation. But that was already true with DNS-01 if they got your DNS credentials. The attack surface is just different, not necessarily larger.</p>

<h2 id="when-is-dns-persist-01-coming">When is DNS-PERSIST-01 coming?</h2>

<p>The regulatory path for DNS-PERSIST-01 is already clear. <a href="https://cabforum.org/2025/10/09/ballot-sc-088v3-dns-txt-record-with-persistent-value-dcv-method/">CA/Browser Forum ballot SC-088v3</a> passed in October 2025 with unanimous support from 26 Certificate Authorities. Chrome, Mozilla, and Cisco all voted yes. The <a href="https://datatracker.ietf.org/doc/draft-ietf-acme-dns-persist/">IETF ACME working group formally adopted the draft</a> in October 2025.</p>

<p><a href="https://letsencrypt.org/2025/12/02/from-90-to-45">Let’s Encrypt committed to implementing DNS-PERSIST-01</a> in 2026. No specific quarter or month yet, just “2026” with “more to announce soon.” Let’s Encrypt explicitly sees this as an enabler for shorter certificate lifetimes.</p>

<p>When <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">certificate lifetimes drop to 47 days</a> (coming in 2029), you’ll be revalidating constantly. Manual DNS changes won’t cut it. Half-baked automation will break. DNS-PERSIST-01 is designed to make that future survivable.</p>

<h2 id="how-certkit-will-use-dns-persist-01">How CertKit will use DNS-PERSIST-01</h2>

<p>Right now, CertKit proxies DNS-01 validation so you don’t have to hand over your DNS credentials. DNS validation will follow CNAMEs, so we can host and update the TXT records for you. That already solves the “skeleton key” problem. But you still need to authorize each certificate request through our system.</p>

<p>With DNS-PERSIST-01, you authorize CertKit once per domain. You can point <code class="language-plaintext highlighter-rouge">_validation-persist.example.com</code> to a record we control, and we handle the TXT record on your behalf. We handle every renewal automatically. No per-certificate approval, just create certificates when you need them.</p>

<p>CertKit will support it shortly after Let’s Encrypt does.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate lifecycle management so you don’t have to.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Do you still need wildcard certificates?</title>
      <link>https://www.certkit.io/blog/do-you-still-need-wildcard-certificates</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/do-you-still-need-wildcard-certificates</guid>
      <pubDate>Mon, 22 Dec 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/do-you-still-need-wildcard-certificates#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/wildcard-certificates.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/wildcard-certificates.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[DNS]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[Certificate Transparency]]>
      </category>
      <description>
        <![CDATA[You&#39;ve been using wildcard certificates for years because they were simpler. One cert, one renewal, copy it everywhere. But now you&#39;re automating anyway. If certificate management is no longer painful, do you still need wildcards? Or are they solving a problem that no longer exists?]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/wildcard-certificates.png" alt="Do you still need wildcard certificates?" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>You’ve used wildcard certificates for years. It made your life easier. Once a year you’d renew your wildcard certificate, and copy it around to all the servers. It was way too complicated and expensive to get a unique certificate for every system.</p>

<p>But now <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">certificate lifetimes are shrinking to 47 days by 2029</a> and it’s not going to work anymore. You need to automate your certificates. Soon.</p>

<p>So here’s the question: if you’re automating certificate management, do you actually need a wildcard SSL certificate? Or is it solving a problem that no longer exists?</p>

<h2 id="what-is-a-wildcard-certificate">What is a wildcard certificate?</h2>

<p>A wildcard certificate covers a domain and all its subdomains at one level. Buy a cert for *.example.com and it works for foo.example.com, bar.example.com, baz.example.com, and anything else you need.</p>

<p>In practice, nearly every wildcard certificate is issued as a multi-SAN cert that includes both *.example.com and the apex example.com domain. So when you buy a “wildcard,” you’re really getting a SAN certificate with a wildcard entry.</p>

<p>Note that wildcards don’t cover multiple levels. A cert for *.example.com won’t secure dev.api.example.com. That needs its own certificate or another wildcard at *.api.example.com.</p>

<h2 id="what-is-a-san-certificate">What is a SAN certificate?</h2>

<p>A SAN (Subject Alternative Name) certificate lists one or more specific domains. Unlike wildcards, these are explicit like app.example.com or api.example.net.</p>

<p>CAs sometimes call these “multi-domain” or “UCC” certificates. They’ll even let you mix completely different domains on one cert. Every domain must be listed at issuance. So if you want to add a new subdomain, you have to re-issue the whole certificate.</p>

<p>Certificate authorities love selling SAN certificates. They typically charge per domain, so a 10-domain SAN costs more than a single wildcard that covers unlimited subdomains. Keep that in mind when you hear CAs recommending SANs over wildcards.</p>

<h2 id="tradeoffs-in-wildcard-vs-san-certificates">Tradeoffs in wildcard vs SAN certificates</h2>

<p>Here’s what to consider with a wildcard vs SAN certificate:</p>

<h3 id="1-flexibility-and-future-subdomains">1. Flexibility and future subdomains</h3>

<p>Wildcards cover subdomains you haven’t created yet. If you spin up subdomains for projects or customers, having a wildcard can make that faster and easier. With a SAN certificate, you have to issue a new cert for every domain you need. But, if you have <a href="https://www.certkit.io/">certificate automation implemented</a>, issuing a new certificate could just be a few clicks.</p>

<h3 id="2-key-compromise-and-blast-radius">2. Key compromise and blast radius</h3>

<p>A compromised private key is always concerning, but the scope of damage depends on what that key protects. Lose a single-domain certificate’s key and one service is exposed. Lose a wildcard key and every subdomain is vulnerable. And if you’re not using <a href="https://www.certkit.io/blog/perfect-forward-secrecy">Perfect Forward Secrecy</a>, attackers could decrypt previously captured traffic too.</p>

<p>The <a href="https://media.defense.gov/2021/Oct/07/2002869955/-1/-1/0/CSI_AVOID%20DANGERS%20OF%20WILDCARD%20TLS%20CERTIFICATES%20AND%20THE%20ALPACA%20TECHNIQUE_211007.PDF">NSA warns</a> that attackers with a wildcard private key can impersonate any subdomain covered by that certificate. They lay out a scenario where a compromised staging server, steal the key, use DNS poisoning or network access to redirect traffic intended for production systems. The NSA calls these <a href="https://www.bleepingcomputer.com/news/security/nsa-warns-of-wildcard-certificate-risks-provides-mitigations/">“relatively uncommon conditions,”</a>. If the attacker is in your network and changing DNS records, you’ve got bigger problems.</p>

<h3 id="3-certificate-transparency-exposure">3. Certificate Transparency exposure</h3>

<p>Every TLS certificate is logged publicly in Certificate Transparency logs. All of them. You can <a href="https://www.certkit.io/tools/ct-logs/">search for yours right now using our CTLog search tool</a>. Anyone can watch these logs and see what domains you’re creating certificates for.</p>

<p>With single-domain certificates, your infrastructure is visible. Internal project names, customer subdomains, staging environments, or that new product you haven’t announced yet. <a href="https://media.defcon.org/DEF%20CON%2025/DEF%20CON%2025%20presentations/DEF%20CON%2025%20-%20Hanno-Boeck-Abusing-Certificate-Transparency-Logs.pdf">Hanno Böck demonstrated at DEF CON 25</a> that attackers can find new WordPress installations within 30-60 minutes of certificate issuance by watching CT logs. He estimated he could have compromised around 4,000 WordPress sites in a month.</p>

<p>Wildcard certificates hide your subdomain names. The CT log shows *.example.com, not the 15 specific subdomains you’re actually running. Some organizations choose wildcards specifically for this obscurity. It’s not perfect security (subdomains can still be discovered through DNS enumeration), but it removes one easy reconnaissance vector.</p>

<h3 id="4-validation-requirements">4. Validation requirements</h3>

<p>Wildcard certificates require DNS-01 validation. You have to create a TXT record to prove domain ownership. Single-domain certificates can use simpler HTTP-01 validation where you just drop a file on your web server.</p>

<p>This matters for automation. DNS validation requires API access to your DNS provider. HTTP validation just needs a running web server. If your DNS provider has a bad API (or no API), wildcards become painful.</p>

<p class="aside">Here’s one of the ways CertKit makes it easier. Rather than worrying about validation, you just create a CNAME record for <code class="language-plaintext highlighter-rouge">_acme-challenge.example.com</code> and point it at us. We handle all the validation from there, so you can get whatever certificates are right for you. It’s called <a href="https://www.certkit.io/blog/delegated-dns-validation">delegated domain validation</a>.</p>

<h2 id="multi-san-certificates-the-worst-of-both-worlds">Multi-SAN certificates: the worst of both worlds</h2>

<p>Multi-SAN certificates combine the downsides of both approaches.</p>

<p>You get the blast radius of a shared private key. Compromise one server, compromise every domain on that cert.</p>

<p>You get full Certificate Transparency exposure. Every domain is publicly listed.</p>

<p>You lose flexibility. Adding or removing domains requires reissuing the entire certificate. Want to sell off a side project that was on your main SAN cert? You can’t just remove it. Reissue everything.</p>

<p>And you get <a href="https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die">a unique problem called BygoneSSL</a>. If any domain on your multi-SAN certificate changes ownership (you let it lapse, you sell it, the new owner wants it back), the new owner can request revocation of the entire certificate. Researchers analyzing this found CDN certificates with 700 domains on them. One bygone domain means one person can kill service for 699 other sites with a single revocation request.</p>

<p>There are a few vendor systems that require multi-SAN certificates (looking at you Microsoft Exchange), but you should probably avoid them unless you have to. Don’t choose this architecture voluntarily.</p>

<h2 id="when-wildcards-still-make-sense">When wildcards still make sense</h2>

<p>Even with full automation, wildcard certificates have legitimate uses.</p>

<p><strong>CT log obscurity.</strong> If hiding your subdomain structure from public view matters to your threat model, wildcards are the only option. Maybe you’re working on an unannounced product. Maybe you have customer-specific subdomains you’d rather not advertise. Maybe you just don’t want to make reconnaissance easier for attackers.</p>

<p><strong>Load balancers and reverse proxies.</strong> A wildcard on your edge proxy doesn’t meaningfully expand blast radius. If someone compromises that proxy, they already have access to traffic for all your subdomains. The NSA guidance specifically calls this out as an acceptable use case.</p>

<p><strong>High-churn environments.</strong> If you’re constantly creating and destroying subdomains (dev environments, feature branches, customer sandboxes), wildcards mean one less thing to automate per deployment.</p>

<p><strong>Vendor requirements.</strong> Some systems just want a wildcard. Don’t fight it.</p>

<h2 id="automation-changes-the-question">Automation changes the question</h2>

<p>The wildcard vs SAN debate is stuck in the past. It assumes certificates cost money and management is painful, so minimizing the number of certificates matters. One is easier than fifty. Less to track, less to renew, less to screw up.</p>

<p>But with 47-day lifetimes arriving in 2029, you need automation regardless. And once you’ve automated, issuing 50 single-domain certificates takes the same effort as one wildcard.</p>

<p>The question shifts from “what’s easiest to manage?” to “what fits my security model?”</p>

<p>For most organizations, that’s single-domain certificates per service. You get isolation (compromise one key, lose one service). Independent renewal cycles (one failure doesn’t cascade). Clear inventory of what’s running where.</p>

<p>Wildcards remain useful when CT log obscurity matters.</p>

<p>Multi-SAN certificates listing explicit domains should be avoided unless a vendor specifically requires them.</p>

<p>CertKit just added multi-SAN support for the cases where you need it. But our recommendation? Single-domain certs per service when you can. Wildcards when you need obscurity. Multi-SAN only when you have no choice.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> for teams who’d rather not think about certificates. Currently in beta.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Multi-domain (multi-san) certificates and better error messages</title>
      <link>https://www.certkit.io/blog/certkit-supports-multisan</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/certkit-supports-multisan</guid>
      <pubDate>Wed, 17 Dec 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/certkit-supports-multisan#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/certkit-supports-multisan.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/certkit-supports-multisan.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[CertKit now supports multi-SAN certificates, letting you cover multiple domains with a single cert. We also improved the certificate creation flow and made error messages actually useful.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/certkit-supports-multisan.png" alt="Multi-domain (multi-san) certificates and better error messages" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>We shipped some big updates this week <a href="https://www.certkit.io/roadmap">from our roadmap</a>!</p>

<h2 id="multi-domain-certificates">Multi-domain certificates</h2>

<p>You can now create certificates that cover multiple domains. Mix and match <a href="https://www.certkit.io/blog/do-you-still-need-wildcard-certificates">wildcard certificates</a> with specific hostnames, all on a single certificate.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/multisan.png" loading="lazy" alt="CertKit multi-domain certificate form showing wildcard and single name entries" width="1800" height="1289" />
</picture>

<p>The first domain you add becomes the <strong>Common Name</strong>. The rest go into the Subject Alternative Names (SAN) list. This matters if you have systems that still check CN instead of SAN.</p>

<p>One thing to know: multi-domain certificates only renew if <em>all domains validate successfully</em>. If one domain’s DNS is misconfigured, the whole renewal fails. The UI warns you about this because we’ve been burned by it ourselves.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/validation.png" loading="lazy" alt="CertKit certificates list showing multi-domain indicator" width="1200" height="555" />
</picture>

<p>The certificates list now shows which certs have multiple domains attached so you can see what you’re dealing with at a glance.</p>

<h2 id="better-error-messages">Better error messages</h2>

<p>When certificate issuance fails, CertKit now shows you the actual ACME error instead of a generic “something went wrong” message.</p>

<picture class="include blog-post-image flex justify-center">
  <img src="https://www.certkit.io/assets/images/blog/2025/certkit-supports-multisan/error.png" loading="lazy" alt="CertKit showing detailed ACME error message" width="919" height="493" />
</picture>

<p>You can see exactly what the CA rejected and why. In this case, someone tried to get a wildcard for a domain that doesn’t exist on the public suffix list. (We also prevented this specific thing from happening again by being better at domain validation). The error tells you that, along with when we’ll retry.</p>

<p>No more guessing what went wrong or digging through logs.</p>

<h2 id="non-sequential-identifiers">Non-sequential identifiers</h2>

<p>We replaced all sequential integer IDs with SQIDs. Those short alphanumeric codes you see in URLs and the certificates list (like <code class="language-plaintext highlighter-rouge">knmy</code> and <code class="language-plaintext highlighter-rouge">b1nw</code>) are now the only identifiers exposed by the system.</p>

<p>Sequential IDs leak information. They tell attackers how many resources exist, when they were created, and provide an easy target for enumeration. Sqids look random but are still deterministic, so your bookmarks and API integrations won’t break.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> for teams who have better things to do. Try it free during our beta.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>How the ACME protocol automates certificate issuance</title>
      <link>https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance</guid>
      <pubDate>Mon, 15 Dec 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/acme-protocol.png?v2" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/acme-protocol.png?v2" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[ACME]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Let's Encrypt]]>
      </category>
      <description>
        <![CDATA[HTTPS went from 40% to over 90% of web traffic in a decade and the ACME protocol made that possible. But ACME solved certificate issuance, not certificate operations. Getting a cert is easy now. Getting it onto all your servers is still your job.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/acme-protocol.png?v2" alt="How the ACME protocol automates certificate issuance" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>In 2015, only about 40% of websites used HTTPS. Today <a href="https://transparencyreport.google.com/https/overview">HTTPS is used over 95% of the time</a>. The ACME protocol made that shift possible.</p>

<p>The <strong>Automatic Certificate Management Environment</strong> (ACME) protocol enables software to automatically prove domain control to a certificate authority without any human involvement. No more generating CSRs by hand. No more copy-pasting into web forms. No more waiting for validation emails.</p>

<p>ACME largely solved certificate issuance. But it didn’t solve certificate operations. Getting a certificate is trivially easy now, but getting that certificate onto all the servers that need it? That’s still <em>your problem</em>.</p>

<h2 id="what-is-the-acme-protocol">What is the ACME protocol?</h2>

<p>Before ACME, getting a certificate was a manual slog. The <a href="https://datatracker.ietf.org/doc/rfc8555/">RFC 8555 specification</a> itself describes the old process:</p>

<ol>
  <li>Generate a CSR using OpenSSL incantations you copied from Stack Overflow.</li>
  <li>Paste it into a CA’s web form.</li>
  <li>Prove domain ownership through some ad-hoc method (usually clicking a link in an email).</li>
  <li>Download the certificate.</li>
  <li>Figure out which format your server needs and install it manually.</li>
</ol>

<p>The spec notes that webmasters needed 1-3 hours to get a certificate installed!</p>

<p>ACME automates all of this. Here’s the ACME protocol explained step by step:</p>

<ol>
  <li>
    <p><strong>Account registration.</strong> Your ACME client generates a key pair and registers with the CA. All future requests are signed with this key, so the CA knows they’re from you.</p>
  </li>
  <li>
    <p><strong>Order creation.</strong> The client sends a JSON request to the CA’s <code class="language-plaintext highlighter-rouge">newOrder</code> endpoint listing the domain names you want on the certificate. The CA responds with an order object containing authorization URLs for each domain.</p>
  </li>
  <li>
    <p><strong>Authorization.</strong> For each domain, the client fetches the authorization object, which contains available validation methods (more on that next). The client picks a validation method and implements the expected response, then tells the CA to validate.</p>
  </li>
  <li>
    <p><strong>Finalization.</strong> Once all authorizations pass, the client submits a Certificate Signing Request to the order’s <code class="language-plaintext highlighter-rouge">finalize</code> URL. The CA issues the certificate and provides a download URL.</p>
  </li>
  <li>
    <p><strong>Download.</strong> The client fetches the certificate chain and installs it.</p>
  </li>
</ol>

<p>The whole exchange happens over HTTPS using signed JSON messages. No web forms. No emails. <strong>No humans</strong>. A certificate that used to take hours now takes seconds.</p>

<p>Every major certificate authority supports the protocol today. It’s become the standard way certificates get issued.</p>

<h3 id="acme-validation-methods">ACME validation methods</h3>

<p>The ACME protocol defines three validation methods to prove you control a domain, each with tradeoffs.</p>

<p><strong>HTTP-01</strong> is the simplest. The CA gives you a token, you put it in a file at <code class="language-plaintext highlighter-rouge">/.well-known/acme-challenge/</code> on your web server. Works great for a single web server with port 80 open to the internet.</p>

<p><strong>DNS-01</strong> requires you to create a TXT record in your domain’s DNS with a specific value. It’s the only method that <a href="https://www.certkit.io/blog/do-you-still-need-wildcard-certificates">works for wildcard certificates</a>. It also works when your server isn’t publicly accessible. But your <a href="https://www.certkit.io/blog/delegated-dns-validation">ACME client needs to modify your DNS</a>, which can be high-risk.</p>

<p><strong>TLS-ALPN-01</strong> validates over TLS on port 443 using a special ALPN protocol identifier. Useful when you can’t open port 80 but can control TLS termination.</p>

<h2 id="the-history-of-acme">The history of ACME</h2>

<p>ACME emerged from two teams who discovered they were solving the same problem.</p>

<p>At Mozilla, Josh Aas and Eric Rescorla were designing a free, automated certificate authority. At the University of Michigan and EFF, Alex Halderman and Peter Eckersley were building a protocol for automatic certificate issuance. The teams found each other and merged efforts in 2013, incorporating the Internet Security Research Group as the nonprofit that would operate Let’s Encrypt.</p>

<p>They knew they needed an automated way to issue certificates, so they approached Richard Barnes, then at Mozilla, with the idea for software to automate certificate provisioning. He wrote the first ACME specification draft and the initial Let’s Encrypt CA software (Boulder) on a flight home from an IETF meeting. Some of that original code is still running in production. Barnes shepherded ACME through the IETF standardization process, which completed in March 2019 with RFC 8555.</p>

<p>The standardization process improved the protocol significantly. The IETF discussions led to a redesign where clients request certificates first and then complete required validations, rather than the original flow of validating domains before requesting certs. This made wildcard certificate handling more natural. The community also pushed for all requests to be authenticated, leading to the POST-as-GET pattern in the current spec.</p>

<p>For the full history with interviews from the people who built it, <a href="https://blog.brocas.org/2025/12/01/ACME-a-brief-history-of-one-of-the-protocols-which-has-changed-the-Internet-Security/">Christophe Brocas wrote an excellent piece</a> worth reading.</p>

<p>A decade later, every major CA supports ACME. ZeroSSL, Google Trust Services, SSL.com, Sectigo, DigiCert. They had to. With a mechanism to automate certificates, the CA/Browser Forum voted in April 2025 to reduce <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">maximum certificate lifetimes to 47 days by March 2029</a>.</p>

<h2 id="acme-keeps-evolving">ACME keeps evolving</h2>

<p>The protocol continues to develop. <a href="https://datatracker.ietf.org/doc/rfc9773/">RFC 9773</a>, published in 2025, adds ACME Renewal Information (ARI). ARI lets certificate authorities suggest renewal windows to clients, which is critical when a CA needs to mass-revoke certificates due to compliance issues. Let’s Encrypt now lets clients who renew via ARI bypass rate limits.</p>

<p>Two new challenge types are on the way. <a href="https://www.certkit.io/blog/dns-persist-01"><strong>dns-persist-01</strong></a> will allow you to link your DNS to an ACME issuer one time, so you don’t need to rotate keys. A <a href="https://datatracker.ietf.org/doc/html/draft-ietf-acme-dns-account-label">new <strong>dns-account-01</strong> challenge addresses multi-CDN environments</a>. There’s even work on using ACME for device attestation certificates, extending the protocol well beyond its original web server use case.</p>

<p>The challenge is client-side adoption. Most ACME clients are “set and forget.” People install certbot, configure a cron job, and never touch it again. Aaron Gable, interviewed in  Brocas’ blog above, notes that even when client projects implement new features like ARI, their massive install bases don’t update. The ecosystem turns over slowly.</p>

<h2 id="what-acme-doesnt-solve">What ACME doesn’t solve</h2>

<p>ACME handles issuance, and that’s it. The protocol is a conversation between one client and one CA. What happens after the certificate arrives is outside the spec entirely.</p>

<p>Certbot, the original ACME client, works beautifully for one certificate, on one server. But you probably don’t just have one server.</p>

<p>You have a web farm. You have that legacy Windows box running a vendor application. You have staging environments and development servers. You have that one machine under someone’s desk that nobody remembers but is apparently critical to payroll. Should each of them be their own ACME client?</p>

<p>Certbot’s official guidance for multi-server deployments is essentially “figure it out yourself.” So people do. They write rsync scripts. They build Ansible playbooks. They create <a href="https://www.certkit.io/blog/why-you-built-your-own-certificate-management">one-off certificate management systems</a> that operate without monitoring or audit.</p>

<p>Each server needs to have HTTP port 80 open to the internet for validation, or worse hold credentials to update your DNS. DNS API keys scattered across your infrastructure, on every machine that might need a certificate. One compromised server and an attacker has write access to your entire DNS and take over.</p>

<p>There’s a difference between <a href="https://www.certkit.io/blog/issuance-automation-vs-certificate-automation">issuance automation and certificate automation</a>.</p>

<h2 id="how-certkit-handles-acme">How CertKit handles ACME</h2>

<p><a href="https://www.certkit.io/blog/servers-shouldnt-need-acme">CertKit is a centralized ACME client</a> that runs in one place. It talks to certificate authorities (Let’s Encrypt, Sectigo, your enterprise CA, whatever supports ACME), handles all the validation, manages renewals centrally, and then distributes certificates to wherever they need to go.</p>

<p>You don’t need to expose port 80 on every server, or pass around your DNS credentials. You create a CNAME record pointing the ACME challenge name to us, and we handle the rest. All your certificates are available in a secure file API or pushed where they need to go.</p>

<p>One place to manage ACME protocol certificates. Deployed everywhere they’re needed. Monitored so you know when something breaks before your customers tell you. We’re picking up where ACME left off, automating the rest of your <a href="https://www.certkit.io/">certificate lifecycle management</a>.</p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Perfect Forward Secrecy Made Your Private Keys Boring</title>
      <link>https://www.certkit.io/blog/perfect-forward-secrecy</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/perfect-forward-secrecy</guid>
      <pubDate>Mon, 08 Dec 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/perfect-forward-secrecy#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/perfect-forward-secrecy.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/perfect-forward-secrecy.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[We used to treat private keys like plutonium because losing one meant every encrypted conversation ever was compromised. Perfect Forward Secrecy fixed that. Now each connection gets temporary keys that vanish after use, so stolen certificates can&#39;t decrypt old traffic. It makes private keys safe to touch.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/perfect-forward-secrecy.png" alt="Perfect Forward Secrecy Made Your Private Keys Boring" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>For twenty years, a stolen private key was a disaster.</p>

<p>It meant total compromise. Every encrypted conversation, password transmitted, API call ever made was readable.</p>

<p>Traffic was being recorded all the time, “just in case” your private key leaked out. The NSA even had a name for it: “harvest now, decrypt later.” Record all the encrypted traffic today. Steal the private keys tomorrow. Decrypt everything retroactively.</p>

<p>Not a conspiracy theory, it was actual operational doctrine from the <a href="https://www.theguardian.com/world/2013/jun/06/nsa-phone-records-verizon-court-order">Snowden documents</a>.</p>

<p>This is why we used to treat <em>private keys like plutonium</em>. Hardware security modules. Rotations with change advisory boards. Full incident response when someone with access left the company. The idea of letting a vendor hold your private keys was unthinkable.</p>

<p>Then Perfect Forward Secrecy came along, and made everything safer.</p>

<h2 id="the-old-rsa-key-exchange">The old RSA key exchange</h2>

<p>Most folks think SSL/TLS encryption still works like the old RSA key exchange.</p>

<p>In RSA, the client generates a random <em>pre-master secret</em>, encrypts it with the server’s public key, and sends it. The server decrypts with its private key, and both sides derive session keys from this shared secret. The trouble is that the encrypted <em>pre-master secret</em> travels over the network, where <strong>anyone can record it</strong>. If the private key is ever compromised, that record can be decrypted to reveal the pre-master secret and derive all the session keys.</p>

<p>That’s exactly <a href="https://www.theguardian.com/world/2013/sep/05/nsa-gchq-encryption-codes-security">what the NSA did</a>! As <a href="https://blog.cryptographyengineering.com/2013/06/26/can-apple-read-your-imessages/">Matthew Green from Johns Hopkins</a> put it: “If the recording entity is powerful enough, they may simply steal the keys — or demand them under court order.”</p>

<p>Using RSA key exchange, one key compromise unravels years of secrets.</p>

<h2 id="what-is-perfect-forward-secrecy">What is Perfect Forward Secrecy?</h2>

<p>With RSA, the server certificate acted as both authentication (you are who you say you are) and authorization (you are allowed to read this data). <em>Perfect Forward Secrecy</em> (PFS) splits these apart and only uses certificates to authenticate that you are who you say you are.</p>

<p>In PFS, each connection gets its own encryption keys that exist <em>only for that session</em>. This happens during the TLS handshake through ephemeral Diffie-Hellman key exchange.</p>

<p>The client and server each generate and exchange random numbers:</p>

<ol>
  <li>Client generates random number <code class="language-plaintext highlighter-rouge">a</code> and sends server <code class="language-plaintext highlighter-rouge">g^a mod p</code>, where <code class="language-plaintext highlighter-rouge">g</code> and <code class="language-plaintext highlighter-rouge">p</code> are standard parameters defined by the cipher.</li>
  <li>Server generates random number <code class="language-plaintext highlighter-rouge">b</code> and sends client <code class="language-plaintext highlighter-rouge">g^b mod p</code>.</li>
  <li>Using their random number and the results from the other, both sides can compute <code class="language-plaintext highlighter-rouge">g^ab mod p</code>, which becomes the shared session secret.</li>
</ol>

<p>An attacker watching this exchange sees the public values but can’t derive the session key. That’s the <a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_problem">Diffie-Hellman problem</a> and nobody’s solved it in nearly 50 years of trying.</p>

<p>The server certificate signs this initial exchange to <a href="https://www.certkit.io/blog/man-in-the-middle">prevent man-in-the-middle attacks</a>, but the real session info is encrypted using the derived session key.</p>

<p>Using Perfect Forward Secrecy, a compromised private key could be used to impersonate you, but all previous traffic remains safely encrypted.</p>

<h2 id="how-to-enable-perfect-forward-secrecy-on-your-servers">How to enable Perfect Forward Secrecy on your servers</h2>

<p>Good news: If you’re running TLS 1.3, you already have Perfect Forward Secrecy. It’s mandatory, you can’t turn it off.</p>

<p><a href="https://datatracker.ietf.org/doc/html/rfc8446#section-1.2">RFC 8446</a> states: “All handshakes in TLS 1.3 provide forward secrecy.” No options. No configurations. Just PFS by default.</p>

<p>But if you’re still on TLS 1.2, you need to configure it properly.</p>

<p>TLS supports two variants: DHE (traditional Diffie-Hellman Ephemeral) and ECDHE (Elliptic Curve Diffie-Hellman Ephemeral). ECDHE is better because it’s faster and uses smaller keys for equivalent security. Look for cipher suites with <code class="language-plaintext highlighter-rouge">DHE</code> or <code class="language-plaintext highlighter-rouge">ECDHE</code> in the name. Those provide forward secrecy.</p>

<p class="aside">Note that ECDHE describes the <em>key exchange</em>, not the certificate type. Your server certificate can be RSA or ECDSA regardless of which key exchange you use.</p>

<p>For Nginx:</p>

<div data-copyable="true" class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ssl_protocols</span> <span class="s">TLSv1.2</span> <span class="s">TLSv1.3</span><span class="p">;</span>
<span class="k">ssl_ciphers</span> <span class="s">ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305</span><span class="p">;</span>
<span class="k">ssl_prefer_server_ciphers</span> <span class="no">off</span><span class="p">;</span>
<span class="k">ssl_ecdh_curve</span> <span class="s">X25519:secp384r1</span><span class="p">;</span>
</code></pre></div></div>

<p>For Apache:</p>

<div data-copyable="true" class="language-apache highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">SSLProtocol</span> -all +TLSv1.2 +TLSv1.3
<span class="nc">SSLCipherSuite</span> ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305
<span class="nc">SSLHonorCipherOrder</span> <span class="ss">off</span>
</code></pre></div></div>

<p>For IIS, you need to mess with the registry or use IIS Crypto. Because Windows.</p>

<p>Test your configuration, change <code class="language-plaintext highlighter-rouge">www.example.com</code> to your domain</p>

<div data-copyable="true" class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> | openssl s_client <span class="nt">-connect</span> www.example.com:443 <span class="nt">-tls1_2</span> 2&gt;/dev/null | <span class="nb">grep</span> <span class="s2">"Cipher"</span>
</code></pre></div></div>

<p>See “ECDHE” in there? You’re good.</p>

<p><a href="https://www.ssllabs.com/ssltest/">SSL Labs</a> will give you a detailed report. Search for “Forward Secrecy” in the results page. Should say “<strong>Yes (with most browsers)</strong>”.</p>

<h2 id="what-ec-certificates-actually-improve">What EC certificates actually improve</h2>

<p>Switching to an EC (ECDSA) certificate is a separate decision from enabling ECDHE key exchange. EC certificates don’t give you PFS, but they do give you a faster, leaner handshake.</p>

<p>A 256-bit EC key provides roughly equivalent security to a 3072-bit RSA key, so certificates are smaller and the cryptographic operations are cheaper on the server. On high-traffic systems or constrained hardware, that adds up. You get smaller payloads during the TLS handshake, lower CPU overhead on your servers, and better performance on mobile and IoT clients where compute is limited.</p>

<h2 id="why-your-certificates-are-safe-to-automate">Why your certificates are safe to automate</h2>

<p>Without PFS, certificate automation is scary. Your private keys lived on disk. In memory. In backups. Every automated system that touched certificates became a potential catastrophic breach vector.</p>

<p>With PFS, that entire threat model disappears.</p>

<p>A compromised private key can’t decrypt past traffic. Can’t even decrypt current traffic from sessions that already completed their handshake. The blast radius shrinks from “all of history” to “new connections if the attacker can man-in-the-middle, but only until we notice and <a href="https://www.certkit.io/blog/certificate-revocation-is-broken">revoke the certificate</a>.”</p>

<p>This is why <a href="https://security.googleblog.com/2011/11/protecting-data-for-long-term-with.html">Google turned on PFS in 2011</a>. Not for the marginal security improvement. For the operational freedom.</p>

<blockquote>
  <p>We can sleep better knowing that the private keys we have on our servers, if compromised, can’t be used to decrypt past sessions.</p>
</blockquote>

<p>When <a href="https://heartbleed.com/">Heartbleed</a> hit in 2014, sites with PFS had dramatically different breach notifications. Without PFS: “All traffic from the past two years may be compromised.” With PFS: “Traffic after March 2014 may be at risk until you patched.”</p>

<p>That’s a <strong>$100 million difference</strong> in breach costs according to <a href="https://www.ibm.com/security/data-breach">Ponemon Institute data</a>.</p>

<p>The risks of private key compromise from <a href="https://www.certkit.io/">Certificate automation</a> becomes reasonable with PFS.</p>

<h2 id="perfect-forward-secrecy-and-quantum-computing">Perfect forward secrecy and quantum computing</h2>

<p>Quantum computers will eventually break Perfect Forward Secrecy.</p>

<p><a href="https://en.wikipedia.org/wiki/Shor%27s_algorithm">Shor’s algorithm</a> can solve both the discrete logarithm problem (breaks Diffie-Hellman) and integer factorization (breaks RSA) when we have big enough quantum computers.</p>

<p>The <a href="https://www.schneier.com/blog/archives/2018/12/quantum_computi_1.html">NSA is probably recording traffic now</a> to decrypt later with quantum computers. They’re betting on having the capability within 10-20 years.</p>

<p>So even if you’ve already enabled ECDHE key exchange and switched to EC certificates, you’ll need to update your cipher suites again soon with quantum-safe algorithms. When post-quantum becomes mandatory (and it will), <strong>you’ll need to reissue every certificate</strong> with new cipher suites.</p>

<p>With proper <a href="https://www.certkit.io/">certificate management</a>? It’s a config update. Change your cipher preferences. Click reissue. CertKit handles the rest. Every cert gets the new algorithms on its next renewal cycle. No special migration project. No weekend work. No explaining to the CEO why you need six months to “upgrade cryptography.”</p>

<h2 id="turn-on-pfs-this-week">Turn on PFS this week</h2>

<p>Perfect Forward Secrecy has been available since 1999. TLS 1.3 made it mandatory in 2018. If you’re not using it, you’re running decades-old cryptography.</p>

<p>Check your servers:</p>

<div data-copyable="true" class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> | openssl s_client <span class="nt">-connect</span> www.example.com:443 <span class="nt">-tls1_2</span> 2&gt;/dev/null | <span class="nb">grep</span> <span class="s2">"Cipher"</span>
</code></pre></div></div>

<p>Fix the ones using RSA key exchange. Update your load balancers. Configure your CDN. Test with actual browsers.</p>

<p>Once you’ve got PFS, your private keys are a lot safer. You can automate them, or trust a vendor like CertKit to manage them for you.</p>

<p>Turn it on. This week. Before you’re explaining to the board why last year’s traffic just got decrypted.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> manages certificates in the PFS world. Where keys aren’t scary and 47-day rotation isn’t insane.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Searching Certificate Transparency Logs (Part 3)</title>
      <link>https://www.certkit.io/blog/searching-ct-logs-part-3</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/searching-ct-logs-part-3</guid>
      <pubDate>Fri, 21 Nov 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Jordan Griffin]]></dc:creator>
      <comments>https://www.certkit.io/blog/searching-ct-logs-part-3#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p3.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p3.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Transparency]]>
      </category><category>
        <![CDATA[Engineering]]>
      </category><category>
        <![CDATA[Product]]>
      </category>
      <description>
        <![CDATA[In this post we&#39;ll build a Clickhouse database schema to store billions of Certificate Transparency Log entries.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p3.png" alt="Searching Certificate Transparency Logs (Part 3)" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p><a href="https://clickhouse.com/">Clickhouse</a> is an incredible database. Here at Certkit, we’ve long worked in the world of “No SQL” databases like Elasticsearch precisely for their ability to query large amounts of data. But for every database, there’s an amount of data that’s “Too big”. Too big to query quickly or too big to store affordably. Clickhouse manages to thread the needle by efficiently storing truly ridiculous amounts of data while still providing impressive query performance.</p>

<p>Certkit is building Certificate Transparency (CT) log monitoring for our customers. In previous posts, we learned <a href="https://www.certkit.io/blog/searching-ct-logs">what CT logs are</a> and <a href="https://www.certkit.io/blog/searching-ct-logs-part-2">how to pull data from them</a>. Now, we need to store all that data in Clickhouse. This is no small task. About 100 million new certificates enter the CT logs every <strong>week</strong>!</p>

<p>This is the final post in a series on how we built a fast, reliable <a href="https://www.certkit.io/tools/ct-logs/">Certificate Transparency Search</a> for CertKit.</p>

<h2 id="what-is-clickhouse">What Is Clickhouse?</h2>
<p>In case you missed it the first time, <a href="https://clickhouse.com/">Clickhouse</a> is a remarkable database. While it is SQL based, don’t let that fool you, Clickhouse is not your father’s database. Its performance is what we’ve come to associate with No SQL databases in recent years.</p>

<h3 id="column-based">Column Based</h3>
<p>Clickhouse tables are column based as opposed to the usual row based SQL database. A “column-orientated” database simply means all data for a column is stored together, separate from other columns in the same table. Clickhouse uses this column orientation to do two big things: store data efficiently and query it quickly.</p>

<h3 id="efficient-storage">Efficient Storage</h3>
<p>A column’s data is all the same type and entries are often similar to each other. Clickhouse takes advantage of this fact to run compression over each column individually. These compression rates can range from no compression with random data up to 1000x or more with highly repetitive data.</p>

<h3 id="fast-queries-over-large-data-sets">Fast Queries Over Large Data Sets</h3>
<p>Querying a column also benefits from Clickhouse’s columnar nature. Because all the data is co-located, data can be read very efficiently. The impressive data compression often helps as well. When size on disk is so small, it’s easy to read a large number of rows with a relatively small amount of disk activity.</p>

<p>This only touches the surface of <a href="https://clickhouse.com/docs/about-us/distinctive-features">what makes Clickhouse unique</a> but suffice to say, it can hold lots of data in a small amount of space, and query it very quickly.</p>

<h2 id="goals">Goals</h2>
<p>We have three main goals for our CT monitoring. These goals greatly impact our database schema. Our database must:</p>

<h3 id="fast-search">Fast Search</h3>
<p>Both CT log alerting and searching depend on one main feature: fast domain name searches. Without fast result results, interactive searches will be too slow and alerts will be delayed or broken. Our schema needs to sell out to make search fast (Foreshadowing!).</p>

<h3 id="completeness-needed-for-alerts">Completeness Needed For Alerts</h3>
<p>We want to alert the customer when certificates are created for their domain. Completeness is important, otherwise alerts won’t sent when they should be. Therefore, we need to store any and all recently issued certificates.</p>

<h3 id="affordable">Affordable</h3>
<p>We have a unused server that would be a great start for this service. Unfortunately, it only has 2.5TB of SSD disk space. A space efficient schema is needed to fit all <a href="https://radar.cloudflare.com/certificate-transparency?dateRange=52w">3+ Billion certificates issued in the last year</a> into this small amount of space.</p>

<h2 id="using-clickhouse-to-store-every-ssl-certificate">Using Clickhouse To Store Every SSL Certificate</h2>
<p>We’d like to know about every certificate that is issued. The potential size of this dataset greatly influenced our decision to use Clickhouse.</p>

<h3 id="replacingmergetree">ReplacingMergeTree</h3>
<p>A certificate has many entries spread across different CT Log servers. These entries are purposely stored in multiple logs for redundancy. For our purposes, it is good enough to have just one reference to a CT log for every certificate. Deduplicating these entries saves on table size and query time. Both of which we care about very much.</p>

<p>Clickhouse offers an easy way to deduplicate our overly numerous log entries. The <code class="language-plaintext highlighter-rouge">ReplacingMergeTree</code> table engine deduplicates rows using the table ordering as a uniqueness key. <strong>One catch:</strong> deduplication is not guaranteed and is performed in the background or not at all, depending on the situation. This is usually a fine tradeoff, but needs to be kept in mind when writing queries.</p>

<h3 id="table-ordering">Table Ordering</h3>
<p>Table ordering determines how the ReplacingMergeTree will determine duplicates. It also has storage size implications: sorting similar rows near each other gives more opportunity for efficient compression.</p>

<p>We settled on ordering by SerialNumber and IsPrecert <code class="language-plaintext highlighter-rouge">ORDER BY (SerialNumber, SHA256)</code>.</p>

<h4 id="certificate-serial-numbers">Certificate Serial numbers</h4>
<p>Primarily sorting by SerialNumber enables fast lookups of specific certificates <strong>and</strong> increases compression ratios by placing all rows about a single certificate next to each other. It has the added bonus of letting us correlate pre-certificate and issued certificate log entries.</p>

<p>However, there is one catch: A certificate’s serial number is not guaranteed to be globally unique. It is only required to be unique for a specific issuer. From our data, serial numbers are <em>relatively</em> unique and collisions are uncommon. We can verify we’ve gotten the correct certificate by checking that the returned row has the expected issuer or SHA256 hash. This inconvenience is outweighed by the ability to associate a certificate’s pre-certificate and final certificate entries.</p>

<h4 id="sha256">SHA256</h4>
<p>Log entries come in two types: Pre-certificate and Issued certificate. Only a pre-certificate entry is guaranteed to appear in a log, but many final certificate entries also exist. We’d like to keep one example of each for every certificate. We are doing this in practice by secondarily ordering the table by <code class="language-plaintext highlighter-rouge">SHA256</code>. This ensures we keep at least one entry for the pre-certificate and issued certificate.</p>

<h3 id="partitioning-and-deletes">Partitioning and Deletes</h3>
<p>Because completeness is not one of our goals, we’re perfectly happy to save space by deleting data for old, expired certificates. Here lies a small problem: Clickhouse deletes are very expensive because rows are immutable once written. The only way to update or delete a row is to rewrite the entire file containing the row. This is very expensive and slow.</p>

<p>What <em>is</em> fast for Clickhouse is deleting an entire file containing many rows. Partitioning tells Clickhouse how rows should be divided between files. Our table is partitioned by the certificate’s expiry date (<code class="language-plaintext highlighter-rouge">PARTITION BY toYYYYMM(CertificateExpiryDate)</code>), letting us easily drop a month’s worth of certificates without thrashing the disk.</p>

<h3 id="not-storing-raw-certificates">(Not) Storing Raw Certificates</h3>
<p>TLDR: We don’t store the raw certificate bytes. This might seem odd, because the whole point is to know about every issued certificate. The problem is, certificates are HUGE.</p>

<p>A single certificate is just a few KB in size, but multiplying a few KB by 3 billion certificates results in a very large database. We avoid the storage costs by not storing the certificate at all.</p>

<h3 id="retrieving-a-certificate">Retrieving A Certificate</h3>
<p>We do need the original, raw certificate from time to time. Luckily, the full certificate is stored as part of each CT Log entry. The Leaf Index (which we DO store and is just a single integer) allows us to ask the log for the entry along with the original certificate.</p>

<h2 id="searching-every-ssl-certificate-in-clickhouse-very-quickly">Searching Every SSL Certificate In Clickhouse, Very Quickly</h2>
<p>So we’ve stored a CT log entry for every certificate, but we have not addressed how to quickly search certificates by their associated domains. Running a domain query on our large log entries table results in a full table scan. We need something much faster than that.</p>

<h3 id="skip-indexes-have-limits">Skip Indexes Have Limits</h3>
<p>Skip Indexes are Clickhouse’s solution to secondary indexes where the table sort order is not conducive to the query. We could use a <a href="https://clickhouse.com/docs/optimize/skipping-indexes">Skip Index</a> for the domain names column.  Clickhouse uses these indexes to skip blocks of data where it knows a value does not exist. Skip indexes still result in some table scanning, but it is greatly reduced. This almost works for our use case but results in unpredictable query times for large result sets. For example, <a href="https://www.certkit.io/tools/ct-logs/?query=ups.com">UPS.com has generated over 3 million certificates in the last year</a>. A query for UPS takes many times longer to complete than a domain with just a few certificates.</p>

<h3 id="a-table-optimized-for-search">A Table Optimized For Search</h3>
<p>When in doubt, make more tables. To get consistent query times, we opted for a denormalized table created specifically for domain name searching. This additional table is denormalized to a row per SAN(aka domain names) and is also ordered by SAN. That means there is often several rows in the search table for a single certificate in our main table. Ordering the entire table by domain name lets us take the most advantage of the primary table indexes.</p>

<h3 id="reversing-strings-for-performance">Reversing Strings for Performance</h3>
<p>Storing a string in reversed order increases the performance of some LIKE queries. Our search patterns generally look like: “Find all certificates where the domain is *.example.com,” or “Find all certificates ending with *.vpn.example.com. In SQL, this query looks something like <code class="language-plaintext highlighter-rouge">WHERE Domain LIKE '%example.com'</code> or <code class="language-plaintext highlighter-rouge">WHERE Domain LIKE '%vpn.example.com'</code>. Clickhouse reverts to table scanning instead of using the primary index because Clickhouse doesn’t know how the domain begins!</p>

<p>Clickhouse <em>can</em> use the primary index in <code class="language-plaintext highlighter-rouge">LIKE</code> queries when the wildcard is at the end. Storing the domains in reversed order lets us run queries where the wildcard is at the end of the string. <code class="language-plaintext highlighter-rouge">example.com</code> is stored as <code class="language-plaintext highlighter-rouge">moc.elpmaxe</code> and the query changes to: <code class="language-plaintext highlighter-rouge">WHERE Domain LIKE 'moc.elpmaxe%'</code>. To make a more readable query, Clickhouse will happily reverse the string for you: <code class="language-plaintext highlighter-rouge">WHERE Domain LIKE reverse('%example.com')</code>.</p>

<h3 id="significant-domains">Significant Domains</h3>
<p>When we search domain names, we don’t think it’s useful to match a search like “*.com”. We need to match at least the whole first “significant domain”. A simple test of whether something is a significant domain is, “Could I buy this domain at a registrar?”. <code class="language-plaintext highlighter-rouge">nyt.com</code> or <code class="language-plaintext highlighter-rouge">bbc.co.uk</code> are both significant domains even though one contains an additional level.</p>

<p>Clickhouse has a built in function to extract the significant domain. However, doing it on the fly will again effect how well we can use the table’s indexes. Saving off the significant domain into its own column lets us improve our query performance:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">cutToFirstSignificantSubdomain</span><span class="p">(</span><span class="s1">'www.nyt.com'</span><span class="p">);</span>
<span class="k">SELECT</span> <span class="n">cutToFirstSignificantSubdomain</span><span class="p">(</span><span class="s1">'www.bbc.co.uk'</span><span class="p">);</span>

<span class="c1">-- RESULT --</span>
<span class="s1">'nyt.com'</span>
<span class="s1">'bbc.co.uk'</span>
</code></pre></div></div>

<h3 id="materialized-views">Materialized Views</h3>
<p>We’d rather not change our processing code to insert every entry into two tables. Clickhouse can do it for us with <a href="https://clickhouse.com/docs/materialized-view/incremental-materialized-view">materialized views</a>. Materialized views take new data from one table and inserts it in some modified way into second table.</p>

<h2 id="conclusion">Conclusion</h2>
<p>So far, we’ve stored <strong>Billions</strong> of certificates which Clickhouse has easily handled. If anything, this amount of data is <em>small</em> by Clickhouse standards and we often see domain query times under a tenth of a second.  You can use it yourself in our <a href="https://www.certkit.io/tools/ct-logs/">free Certificate Transparency search tool</a>.</p>

<p>We built this tool as part of <a href="https://www.certkit.io/">Certkit</a>: a simple certification issuance and management tool. It’s just a small part of what makes Certkit great. Check us out if you’re tired of manually issuing certificates or fighting with Certbot.</p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Searching Certificate Transparency Logs (Part 2)</title>
      <link>https://www.certkit.io/blog/searching-ct-logs-part-2</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/searching-ct-logs-part-2</guid>
      <pubDate>Thu, 20 Nov 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Eric Brandes]]></dc:creator>
      <comments>https://www.certkit.io/blog/searching-ct-logs-part-2#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p2.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p2.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Transparency]]>
      </category><category>
        <![CDATA[Engineering]]>
      </category><category>
        <![CDATA[Product]]>
      </category>
      <description>
        <![CDATA[In this post we&#39;ll write Golang code to pull Certificate Transparency Log entries and process them at scale.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p2.png" alt="Searching Certificate Transparency Logs (Part 2)" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>In the last post we discussed <a href="https://www.certkit.io/blog/searching-ct-logs">why we’re building our own Certificate Transparency (<strong>CT</strong>) search tool</a>.  There’s good background on the CT ecosystem in that post, so check it out if you haven’t.  This post assumes a certain understanding of terminology covered previously.</p>

<p>Now that we know where the CT logs live, and the different kinds of logs, we need to start reading them.  This post will cover code examples to read log entries from both tiled and RFC 6962 logs, and discuss options for running at scale.</p>

<h2 id="golang-is-the-language-of-certificate-transparency">Golang is the language of Certificate Transparency</h2>
<p>We’re C#/.NET guys by disposition (yeah, yeah) but we’re also pragmatists.  While it’s possible to consume CT logs with any language, the guys writing the Web PKI plumbing are mostly writing in Golang (<strong>Go</strong>, from here on).</p>

<p>And if you’re willing to play in the Go sandbox, there are some nice client libraries available to consume both types of logs.</p>

<h3 id="rfc-6962-log-client">RFC 6962 Log Client</h3>
<p>For all things RFC 6962 you should check out Google’s <a href="https://github.com/google/certificate-transparency-go">certificate-transparency-go</a> library.  In addition to containing a great client for interacting with log APIs, it contains some code to handle parallel scanning for you (more on that later).</p>

<h3 id="tiled-log-client">Tiled Log Client</h3>
<p>The tiled/static-ct logs are still pretty new, and we only found a <a href="https://github.com/FiloSottile/sunlight">single client implementation</a> worth using.  It’s written by <a href="https://filippo.io/">the guy</a> who proposed the <a href="https://sunlight.dev/">tiled logs</a> in the first place, so probably as good as it gets for now.</p>

<h2 id="two-logs-two-examples-each">Two logs, two examples each</h2>
<p>Let’s start calling the CT log APIs and see what we’re working with.  Remember, there are two types of logs, and the read paths for each log are different.  So for most things there will be two code examples - one for the RFC 6962 logs (the OGs) and one for the newer tiled logs.</p>

<h2 id="rfc-6962-getting-the-signed-tree-head">RFC 6962: Getting the Signed Tree Head</h2>
<p>RFC 6962 logs publish a <strong>Signed Tree Head (STH)</strong>. This is a cryptographic snapshot of the Merkle tree root. Its purpose is to prove the tree hasn’t been tampered with, but for our puposes we primarily care about the <code class="language-plaintext highlighter-rouge">tree_size</code> value.</p>

<p>The <code class="language-plaintext highlighter-rouge">tree_size</code> is simply how large the log is currently.  How many certificates and precertificates are in it.  This is useful when scanning the logs - so if you stop or have to restart you know where you left off, and how far you are from completion.</p>

<h3 id="sth-in-the-browser">STH In the Browser</h3>
<p>You can actually get the signed tree head in the browser for most logs.  For example, here’s the STH for Google’s Argon 2026h1 log:</p>

<p><a href="https://ct.googleapis.com/logs/us1/argon2026h1/ct/v1/get-sth">https://ct.googleapis.com/logs/us1/argon2026h1/ct/v1/get-sth</a>.</p>

<h3 id="sth-using-go">STH Using Go</h3>
<p>But of course for any kind of real log scanning we’ll want to get it programmatically.  Something like this will do the trick (but yours should have actual error handling):</p>

<div data-copyable="true" class="language-golang highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">(</span>
  <span class="c">// There are ambiguous "client" packages in the library so specify</span>
  <span class="n">ctclient</span> <span class="s">"github.com/google/certificate-transparency-go/client"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">logUrl</span> <span class="o">:=</span> <span class="s">"https://ct.googleapis.com/logs/us1/argon2026h1/"</span>
  <span class="n">client</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">ctclient</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="n">logUrl</span><span class="p">,</span> <span class="n">http</span> <span class="n">DefaultClient</span><span class="p">,</span> <span class="n">jsonclient</span><span class="o">.</span><span class="n">Options</span><span class="p">{})</span>
  <span class="n">signedTreeHead</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">client</span><span class="o">.</span><span class="n">GetSTH</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>

  <span class="c">// Let's see how big the log is!</span>
  <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Tree size: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">signedTreeHead</span><span class="o">.</span><span class="n">TreeSize</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="tiled-logs-getting-the-checkpoint">Tiled Logs: Getting the Checkpoint</h2>
<p>Tiled logs don’t have a signed tree head. Instead they have a <strong>checkpoint</strong>.  It’s not quite the same thing, but for our purposes it is - since it contains the log size!</p>

<h3 id="checkpoint-in-the-browser">Checkpoint in the Browser</h3>
<p>Let’s Encrypt runs several tiled logs.  As of November 2025 they are qualified for inclusion in Chrome, which means they’re ready for primetime.  Let’s look at the checkpoint for Sycamore’s 2026h1 log:</p>

<p><a href="https://mon.sycamore.ct.letsencrypt.org/2026h1/checkpoint">https://mon.sycamore.ct.letsencrypt.org/2026h1/checkpoint</a></p>

<p>It’s also worth calling out that Sunlight logs have a little bit of UI to go with them.  Here is Sycamore’s web UI: <a href="https://log.sycamore.ct.letsencrypt.org/">https://log.sycamore.ct.letsencrypt.org/</a></p>

<p>You can add items to the log right from your browser.  There’s also helpful links to the checkpoint, and perhaps more importantly for later - the public key is also shown.</p>

<picture class="include blog-post-image flex justify-center">
  <img src="https://www.certkit.io/assets/images/blog/2025/sunlight.png" loading="lazy" alt="A sunlight log web UI" width="634" height="399" />
</picture>

<h3 id="checkpoint-using-go">Checkpoint Using Go</h3>
<p>We can get the checkpoint fairly easily in Go as well, but it’s a little more effort with the public key involved.</p>

<div data-copyable="true" class="language-golang highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">(</span>
	<span class="s">"filippo.io/sunlight"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="c">// First up, we gotta turn the base64 key in to something usable.</span>
  <span class="n">publicKey</span><span class="o">:</span> <span class="s">"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfEEe0JZknA91/c6eNl1aexgeKzuG
QUMvRCXPXg9L227O5I4Pi++Abcpq6qxlVUKPYafAJelAnMfGzv3lHCc8gA=="</span>
  <span class="n">bytes</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">base64</span><span class="o">.</span><span class="n">StdEncoding</span><span class="o">.</span><span class="n">DecodeString</span><span class="p">(</span><span class="n">publicKey</span><span class="p">)</span>
  <span class="n">key</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">x509</span><span class="o">.</span><span class="n">ParsePKIXPublicKey</span><span class="p">(</span><span class="n">bytes</span><span class="p">)</span>

  <span class="c">// Then we can make the client</span>
  <span class="c">// for many of these logs the UserAgent is not optional.</span>
  <span class="n">logMonitoringUrl</span> <span class="o">:=</span><span class="s">"https://mon.sycamore.ct.letsencrypt.org/2026h1/"</span>
  <span class="n">client</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">sunlight</span><span class="o">.</span><span class="n">NewClient</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sunlight</span><span class="o">.</span><span class="n">ClientConfig</span><span class="p">{</span>
    <span class="n">MonitoringPrefix</span><span class="o">:</span> <span class="n">logMonitoringUrl</span><span class="p">,</span>
    <span class="n">PublicKey</span><span class="o">:</span>        <span class="n">key</span><span class="p">,</span>
    <span class="n">UserAgent</span><span class="o">:</span>        <span class="s">"YourUserAgent (you@yourdomain.com, +https://yourdomain.com)"</span><span class="p">,</span>
  <span class="p">})</span>

  <span class="c">// Get the checkpoint (plumb in your context as available)</span>
  <span class="n">checkpoint</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">client</span><span class="o">.</span><span class="n">Checkpoint</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">TODO</span><span class="p">())</span>

  <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Log size: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">checkpoint</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="rfc-6962-scanning-entries">RFC 6962: Scanning Entries</h2>
<p>Now for the most important part: ripping through the log with reckless abandon, processing entries pell-mell.  While the client in the Google CT library is useful, they’ve also helpfully <a href="https://github.com/google/certificate-transparency-go/blob/master/scanner/scanner.go">included a scanner</a> that will do the heavy lifting for you.  It saves quite a bit of faffing.</p>

<h3 id="certificates-vs-precertificates">Certificates vs. Precertificates</h3>
<p>Before we see the code to scan through an RFC 6962 log, remember that there are two kinds of “things” in the logs.  Precertificates and certificates.  This distinction is important as we’ll see when scanning both kinds of logs.</p>

<h3 id="using-the-scanner-in-go">Using the Scanner in Go</h3>
<div data-copyable="true" class="language-golang highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">(</span>
  <span class="n">ctclient</span> <span class="s">"github.com/google/certificate-transparency-go/client"</span>
  <span class="s">"github.com/google/certificate-transparency-go/scanner"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span> <span class="p">()</span> <span class="p">{</span>
  <span class="n">logUrl</span> <span class="o">:=</span> <span class="s">"https://ct.googleapis.com/logs/us1/argon2026h1/"</span>
  <span class="n">client</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">ctclient</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="n">logUrl</span><span class="p">,</span> <span class="n">http</span> <span class="n">DefaultClient</span><span class="p">,</span> <span class="n">jsonclient</span><span class="o">.</span><span class="n">Options</span><span class="p">{})</span>
  <span class="n">s</span> <span class="o">:=</span> <span class="n">scanner</span><span class="o">.</span><span class="n">NewScanner</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">scanner</span><span class="o">.</span><span class="n">DefaultScannerOptions</span><span class="p">())</span>

  <span class="n">s</span><span class="o">.</span><span class="n">Scan</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">TODO</span><span class="p">(),</span> <span class="k">func</span><span class="p">(</span><span class="n">raw</span> <span class="o">*</span><span class="n">ct</span><span class="o">.</span><span class="n">RawLogEntry</span><span class="p">)</span> <span class="p">{</span>
		<span class="c">// this is the callback for certificates</span>
		<span class="n">le</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">raw</span><span class="o">.</span><span class="n">ToLogEntry</span><span class="p">()</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Cert common name: %s"</span><span class="p">,</span> <span class="n">le</span><span class="o">.</span><span class="n">X509Cert</span><span class="o">.</span><span class="n">Subject</span><span class="o">.</span><span class="n">CommonName</span><span class="p">)</span>
	<span class="p">},</span> <span class="k">func</span><span class="p">(</span><span class="n">raw</span> <span class="o">*</span><span class="n">ct</span><span class="o">.</span><span class="n">RawLogEntry</span><span class="p">)</span> <span class="p">{</span>
		<span class="c">// this is the callback for precertificates</span>
		<span class="n">le</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">raw</span><span class="o">.</span><span class="n">ToLogEntry</span><span class="p">()</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Precert common name: %s"</span><span class="p">,</span> <span class="n">le</span><span class="o">.</span><span class="n">Precert</span><span class="o">.</span><span class="n">TBSCertificate</span><span class="o">.</span><span class="n">Subject</span><span class="o">.</span><span class="n">CommonName</span><span class="p">)</span>
	<span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="processing-at-scale">Processing at Scale</h3>
<p>There are hundreds of millions (or sometimes billions) of items in large certificate transparency logs.  Unfortunately, many operators of RFC 6962 logs throttle traffic <em>heavily</em> (looking at you Google).  You can change the number of parallel threads fetching log entries in the scanner options, but in our experience you will get throttled very quickly at anything above 2 parallel threads.</p>

<p>The Cloudflare <a href="https://radar.cloudflare.com/certificate-transparency/log/nimbus2026">Nimbus logs</a> were the most performant RFC 6962 logs we found. Google and Digicert both either throttled heavily, or had very slow to respond logs.  Scanning tiled logs is an order of magnitude faster, so hopefully those become the standard (they’re a cost/performance win for log operators too!)</p>

<h2 id="tiled-logs-scanning-tiles-like-a-boss">Tiled Logs: Scanning Tiles Like a Boss</h2>
<p>The reason the read path differs for tile logs is because they’re optimized to be stored in object storage (think S3).  This makes it easy for CDNs to front these logs and allows for blazing fast (relative to RFC 6962, anyways) log retrieval.</p>

<p>Let’s see how it works.</p>

<h3 id="scanning-tiled-logs-in-go">Scanning Tiled Logs in Go</h3>

<div data-copyable="true" class="language-golang highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">(</span>
	<span class="s">"filippo.io/sunlight"</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>

  <span class="n">client</span> <span class="o">:=</span> <span class="n">GetSunlightClient</span><span class="p">()</span>
  <span class="n">checkpoint</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">client</span><span class="o">.</span><span class="n">Checkpoint</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">TODO</span><span class="p">())</span>

  <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">entry</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">client</span><span class="o">.</span><span class="n">Entries</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">TODO</span><span class="p">(),</span> <span class="n">checkpoint</span><span class="o">.</span><span class="n">Tree</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">entry</span><span class="o">.</span><span class="n">IsPrecert</span> <span class="p">{</span>
      <span class="n">cert</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">x509</span><span class="o">.</span><span class="n">ParseCertificate</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">PreCertificate</span><span class="p">)</span>
      <span class="n">isPrecert</span> <span class="o">=</span> <span class="no">true</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="n">cert</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">x509</span><span class="o">.</span><span class="n">ParseCertificate</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">Certificate</span><span class="p">)</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Log size: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">checkpoint</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">GetSunlightClient</span><span class="p">()</span> <span class="o">*</span><span class="n">sunlight</span><span class="o">.</span><span class="n">Client</span> <span class="p">{</span>
  <span class="c">// First up, we gotta turn the base64 key in to something usable.</span>
  <span class="n">publicKey</span><span class="o">:</span> <span class="s">"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfEEe0JZknA91/c6eNl1aexgeKzuG
QUMvRCXPXg9L227O5I4Pi++Abcpq6qxlVUKPYafAJelAnMfGzv3lHCc8gA=="</span>
  <span class="n">bytes</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">base64</span><span class="o">.</span><span class="n">StdEncoding</span><span class="o">.</span><span class="n">DecodeString</span><span class="p">(</span><span class="n">publicKey</span><span class="p">)</span>
  <span class="n">key</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">x509</span><span class="o">.</span><span class="n">ParsePKIXPublicKey</span><span class="p">(</span><span class="n">bytes</span><span class="p">)</span>

  <span class="c">// Then we can make the client</span>
  <span class="c">// for many of these logs the UserAgent is not optional.</span>
  <span class="n">logMonitoringUrl</span> <span class="o">:=</span><span class="s">"https://mon.sycamore.ct.letsencrypt.org/2026h1/"</span>
  <span class="n">client</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">sunlight</span><span class="o">.</span><span class="n">NewClient</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sunlight</span><span class="o">.</span><span class="n">ClientConfig</span><span class="p">{</span>
    <span class="n">MonitoringPrefix</span><span class="o">:</span> <span class="n">logMonitoringUrl</span><span class="p">,</span>
    <span class="n">PublicKey</span><span class="o">:</span>        <span class="n">key</span><span class="p">,</span>
    <span class="n">UserAgent</span><span class="o">:</span>        <span class="s">"YourUserAgent (you@yourdomain.com, +https://yourdomain.com)"</span><span class="p">,</span>
  <span class="p">})</span>

  <span class="k">return</span> <span class="n">client</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">client.Entries()</code> returns an iterator that we can just loop over to get the log entries.  As with the RFC 6962 logs, there is a distinction between certificates and precertificates.  The client itself does a decent job of multithreading.</p>

<h3 id="processing-tiled-logs-at-scale">Processing Tiled Logs at Scale</h3>
<p>We were able to process over a hundred million records from each tiled log per day.  This stands in stark contrast to the paltry low millions we could retrieve from the RFC boys.</p>

<p>There are a number of tiled log providers who are either usable or qualified in modern browsers, and Let’s Encrypt is going to switch to tiled logs exclusively at some point.  From a scanning perspective they are clearly superior!</p>

<h2 id="conclusion">Conclusion</h2>
<p>Using pre-built Go libraries, you can start scanning CT logs quickly.  Though there are billions of certificates in the logs, if you parallelize your scanning, and run multiple logs at a time, you can fairly quickly scan a reasonably comprehensive chunk of the data. You can check out how it works using our <a href="https://www.certkit.io/tools/ct-logs/">free Certificate Transparency search tool</a>.</p>

<p>In the next post <a href="https://www.certkit.io/blog/searching-ct-logs-part-3">we’ll talk about storing the certificate transparency logs in Clickhouse</a>.  Certainly we can’t enumerate every log every time there’s a search query!</p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Searching Certificate Transparency Logs (Part 1)</title>
      <link>https://www.certkit.io/blog/searching-ct-logs</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/searching-ct-logs</guid>
      <pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Eric Brandes]]></dc:creator>
      <comments>https://www.certkit.io/blog/searching-ct-logs#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p1.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p1.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Transparency]]>
      </category><category>
        <![CDATA[Engineering]]>
      </category><category>
        <![CDATA[Product]]>
      </category>
      <description>
        <![CDATA[Searching Certificate Transparency logs lets you uncover every SSL/TLS certificate ever issued for your domain. You can detect mis-issuance, unauthorized changes, or shadow infrastructure before it becomes a problem. It’s a good way to monitor your digital identity and maintain trust in your organization’s security posture.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/searching-certificate-transparency-logs-p1.png" alt="Searching Certificate Transparency Logs (Part 1)" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>Every TLS certificate issued by a root Certificate Authority (<strong>CA</strong>) ends up in one more more publicly accessible logs.  These logs, collectively, make up the <a href="https://certificate.transparency.dev/">Certificate Transparency</a> (<strong>CT</strong>) ecosystem.  Unfortunately the logs are not very searchable.  You can’t easily type in a domain and find all associated certificates.</p>

<p>At CertKit we’re building CT monitoring capabilities to notify our customers when a new certificate is issued.  For that reason, and others, we need fast and reliable CT search capabilities.</p>

<p>There <em>are</em> tools available that store the logs in a search-friendly format.  Probably the most well known is <a href="https://crt.sh">crt.sh</a>.  It’s eminently comprehensive (and free!), but does suffer from some issues.  The biggest is that searching is slow.  If your query matches many log entries, you will only get a truncated result set back.  And fairly frequently the site just fails to respond or is hard down.</p>

<p>That’s why we built our own <a href="https://www.certkit.io/tools/ct-logs/">free certificate transparency search tool</a>!</p>

<p>This series of posts focuses on how we went about building this faster, more reliable Certificate Transparency search for CertKit.</p>

<h2 id="what-is-certificate-transparency-used-for">What is Certificate Transparency used for?</h2>
<p>The primary use case is to make SSL/TLS certificate issuance visible and auditable.  Basically to hold CAs accountable and ensure they’re not mis-issuing certificates.</p>

<p>In addition, end users can find forgotten or outdated infrastructure that’s still getting certificates, see who’s issuing certificates on their behalf, and even figure out if they’re about to miss a certificate renewal by looking at historical records.</p>

<p>You might be surprised at how much the certificate transparency logs can tell you about your own applications!</p>

<p>There are some potential “off-label” uses of CT logs as well.</p>

<p>Because every publicly trusted certificate is recorded, you could also monitor when competitors launch new products, test staging environments, or stand up new services, all by watching the domains they register certificates for.  I’ve even heard people hypothesize you could use the logs as a signal when considering stock trades.</p>

<h2 id="how-did-certificate-transparency-start">How did Certificate Transparency start?</h2>
<p>In 2011 a Dutch CA named DigiNotar was compromised and the attacker issued rogue certificates for over 500 domains.  The fake certificates were used to perform <a href="https://www.certkit.io/blog/man-in-the-middle">man-in-the-middle attacks</a>.</p>

<p>Following this and other high profile CA issues, the IETF created <a href="https://datatracker.ietf.org/doc/html/rfc6962">RFC 6962</a>, which established the certificate transparency protocol (and resulting logs).</p>

<h2 id="how-does-certficate-transparency-work">How does Certficate Transparency work?</h2>
<p>There’s a <a href="https://certificate.transparency.dev/howctworks/">comprehensive explanation of the certificate transparency protocol</a> on the main CT website, but the important points are these:</p>

<ul>
  <li>Before a <em>real</em> certificate can be issued, a CA needs to submit a <strong>precertificate</strong> to at least 2 CT logs.  The precertificate contains the same data as the real cert, along with a “poison” extension that prevents it from being used.</li>
  <li>Upon submitting the precertificate to a log, the log returns a “Signed Certificate Timestamp” (<strong>SCT</strong>), which is a promise to include the certificate in the publicly accessible log.</li>
  <li>The resulting SCTs from each log are included in the final certificate.</li>
  <li>When a browser reads the certificate, it checks to make sure the included SCTs are from trusted logs before it considers it valid.</li>
</ul>

<h2 id="where-are-the-certificate-transparency-logs">Where are the Certificate Transparency logs?</h2>
<p>By design, the certificate transparency ecosystem is distributed.  The idea is to ensure there are enough folks hosting and monitoring the logs to catch any bad actors.  Many companies in the web PKI space run logs, including Let’s Encrypt, Google, Sectigo and Digicert.  As mentioned earlier, Chrome and other browsers require a minimum of 2 SCTs to consider a certificate valid.</p>

<p>Each browser vendor has a list of CT logs that it considers usable or qualified.</p>

<p>You can find them here:</p>

<ul>
  <li><a href="https://www.gstatic.com/ct/log_list/v3/log_list.json"><strong>Chrome</strong></a></li>
  <li><a href="https://valid.apple.com/ct/log_list/current_log_list.json"><strong>Safari</strong></a></li>
  <li><a href="https://searchfox.org/firefox-main/source/security/ct/CTKnownLogs.h"><strong>Firefox</strong></a> - Uses the same list as Chrome, but the link goes to the header file containing them in source.</li>
</ul>

<h3 id="log-shards">Log Shards</h3>
<p>Because there are so many certificates issued every day, the logs are broken in to shards.  The shards are broken up by date.  For example, you’ll see that Google’s Argon log has a 2026h1 and 2026h2 shard.  This roughly corresponds to the first half and second half of the year.  The <code class="language-plaintext highlighter-rouge">NotAfter</code> date of the certificate is used to decide which log it goes to.</p>

<h2 id="types-of-logs">Types of Logs</h2>
<p>There are two types of CT logs. The OG logs are called <strong>RFC 6962</strong> logs and the new logs are variously called <strong>tiled logs</strong>, <strong>static-ct logs</strong> or <strong>sunlight logs</strong>, depending on context and how old the information you’re looking at is.  Both are based on <a href="https://en.wikipedia.org/wiki/Merkle_tree">Merkle trees</a>.</p>

<p>It’s beyond the scope of this post to get in to the nitty gritty, but if you are interested you can do worse than read Russ Cox’s <a href="https://research.swtch.com/tlog">post on the subject</a>.  Let’s Encrypt also wrote a blog post <a href="https://letsencrypt.org/2024/03/14/introducing-sunlight">explaining the rationale</a> for switching to tiled logs.</p>

<p>The old RFC 6962 logs suffered from scalability issues and large hosting costs. Tiled logs are a response to those problems.  The downside is the read-path for each kind of log is different - which means different approaches are required to scan them.  (More on this in the next post)</p>

<h2 id="how-big-are-the-logs">How big are the logs?</h2>
<p>The short answer is <strong>very big</strong>.  There are billions of certificates stored in the various logs, and there will be even more when <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">certificate lifetimes fall to 47 days</a>.   You can explore the data a bit using Cloudflare’s helpful <a href="https://radar.cloudflare.com/certificate-transparency">Radar website</a>.  At the time of this writing there were 96 million unique certificates and 103 million unique precertificates issued in the last <strong>7 days</strong>.  It’s a lot of data.</p>

<h2 id="conclusion">Conclusion</h2>
<p>There’s a lot of interesting data in the Certificate Transparency logs, but it’s not stored in a very searchable format.  Our goal in the next post is to start scanning the logs and pulling the data.  Given the sheer volume of data in the logs this is not a trivial task.  The fact that there are two separate types of logs also makes things more complicated.</p>

<p>In part 2, <a href="https://www.certkit.io/blog/searching-ct-logs-part-2">we’ll write Golang code to pull Certificate Transparency Log entries and process them at scale</a>. Then in part 3, <a href="https://www.certkit.io/blog/searching-ct-logs-part-3">we’ll figure out how to store them in Clickhouse</a>.</p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Certificate revocation is broken but we pretend it works</title>
      <link>https://www.certkit.io/blog/certificate-revocation-is-broken</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/certificate-revocation-is-broken</guid>
      <pubDate>Tue, 11 Nov 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/certificate-revocation-is-broken#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/certificate-revocation-is-broken.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/certificate-revocation-is-broken.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[SSL Certificate revocation is so broken that browser vendors gave up trying to fix it. Chrome manually curates 24,000 &#39;important&#39; revocations out of 2 million. Firefox uses bloom filters that flag valid certs as revoked. Safari does something nobody can document. The industry&#39;s solution? Pretend 47-day certificates solve the problem.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/certificate-revocation-is-broken.png" alt="Certificate revocation is broken but we pretend it works" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>Last week, someone commented on <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">my post about 47-day certificates</a>:</p>

<blockquote>
  <p>users need to stop being stupid .. and revoke the certs … i mean you can go online and look at every cert issued … replace and revoke them .. that’s the users fault don’t force 45 day certs on the rest of us.</p>
</blockquote>

<p>This perfectly captures our collective delusion that SSL certificate revocation works. You click a button, the certificate stops working.</p>

<p>And why wouldn’t we believe that? Every CA has a big “Revoke Certificate” button right there in the dashboard. It must do something, right?</p>

<p>Here’s the dirty truth: <strong>most revoked certificates keep working</strong>. We’ve known this for years, but we just keep the security theater going.</p>

<h2 id="the-revoked-certificate-that-mostly-still-works">The revoked certificate that (mostly) still works</h2>

<p>Let’s say you have a website called <code class="language-plaintext highlighter-rouge">revoked.badssl.com</code>. You suspect the private keys were compromised, so you want to revoke the certificate. Easy right? There’s a command line for that:</p>

<div data-copyable="true" class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>certbot revoke <span class="nt">--cert-path</span> /path/cert.pem
</code></pre></div></div>

<p>Success! It returns “Congratulations! You have successfully revoked the certificate”. Great! Go check it. Really, go load that URL. I’ll wait.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2025/revoked-badssl.webp" loading="lazy" alt="Chrome, Firefox, and Safari loaded revoked.badssl.com" width="1200" height="895" />
</picture>

<p>Depending on which browser you’re using, you’ll see different results. Chrome shows a scary “Your connection is not private” page, but Safari and Firefox loaded it just fine.</p>

<p>This isn’t because Safari and Firefox are broken or inferior. <strong>Every browser handles revocation differently.</strong> Chrome caught this one because someone at <em>Google manually added this high-profile example to their CRLSet</em>. Firefox and Safari might catch a different revoked certificate that Chrome misses.</p>

<p>Three browsers, three different revocation systems, three different results for the same revoked certificate.</p>

<p>This isn’t some obscure edge case. This is a certificate explicitly revoked for key compromise, the most serious reason possible. And whether it gets blocked depends entirely on which browser you happen to be using and whether that particular certificate made it into that browser’s proprietary revocation list.</p>

<h2 id="a-brief-history-of-failing-at-revocation">A brief history of failing at revocation</h2>

<h3 id="crls-the-small-scale-solution">CRLs: the small-scale solution</h3>

<p>What is a certificate revocation list? Certificate Revocation Lists (CRLs) were simple. A X.509 standardized list of bad certificate serial numbers. When a certificate gets revoked, add it to the list. Browsers download the list and check if the certificate is on it. Easy.</p>

<p>This worked great when the internet only had hundreds of certificates.</p>

<p>But just a few years later, CRLs were already becoming unwieldy. Some CRLs grew to hundreds of megabytes. Imagine every browser downloading a 300MB file from every Certificate Authority, multiple times per day. On dial-up.</p>

<p>In addition to the size problem, CRLs were also constantly unavailable and hopelessly out of date as Certificate Authorities (CAs) struggled to scale their infrastructure with the exploding scope of the web.</p>

<h3 id="ocsp-the-cure-is-worse-than-the-disease">OCSP: the cure is worse than the disease</h3>

<p>In 1999, the IETF published RFC 2560 introducing OCSP (Online Certificate Status Protocol). Instead of downloading entire lists, browsers can query for specific certificates as needed. Real-time revocation checking.</p>

<p>Unfortunately, the CAs weren’t any better at keeping OCSP online than they were at CRLs. Mozilla’s reported that <a href="https://cabforum.org/uploads/13.CAB-Forum-October-2020-Mozilla-Update.pdf">nearly half of their system failures were due to OCSP service outage or malformed OCSP responses</a>. Google’s data showed median OCSP checks taking 300ms, with means approaching a second. Load a modern website with resources from 20 domains? That’s potential seconds of delay just for revocation checking.</p>

<p>OCSP was too slow and unreliable enough to count on for certificate checking. So what do we do when its offline?</p>

<ol>
  <li>
    <p><strong>Hard-fail:</strong> Block the connection. Sounds secure, except now every OCSP outage breaks the internet. One CA has an outage and millions of users can’t access sites.</p>
  </li>
  <li>
    <p><strong>Soft-fail:</strong> If OCSP doesn’t respond, allow the connection anyway. This is what browsers actually do.</p>
  </li>
</ol>

<p>That doesn’t sound so bad until you realize that the only time you really need OCSP is when you are being attacked, and the attacker can probably block OCSP requests if they are sending you an invalid certificate.</p>

<p>As <a href="https://www.imperialviolet.org/2012/02/05/crlsets.html">Google’s Adam Langley</a> said,</p>

<blockquote>
  <p>Soft-fail revocation checks are like a seat-belt that snaps when you crash. Even though it works 99% of the time, it’s worthless because it only works when you don’t need it.</p>
</blockquote>

<p>As one final nail in the OCSP coffin, the architecture has a huge privacy problem. Every OCSP query tells the CA exactly which websites you’re visiting in real-time. Your browser checking the certificate for adultwebsite.com? The CA knows. Maybe the ISP too. Get ready for some uncomfortable targeted ads.</p>

<p>The industry tried to band-aid these problems with OCSP stapling. Let the webserver fetch its own OCSP response and include it with the certificate. No more privacy leaks. No more performance hit. No more soft-fail dilemma.</p>

<p>Clever solution, except it requires server operators to actually configure it. According to <a href="https://www.netcraft.com/">Netcraft’s SSL Survey</a>, less than 5% of sites have OCSP stapling properly configured. Even when stapling is configured, it’s often broken. The stapled response expires, doesn’t get refreshed, and browsers fall back to soft-fail OCSP. We’re right back where we started.</p>

<h3 id="browsers-gave-up-on-ocsp-and-reinvented-crls">Browsers gave up on OCSP and reinvented CRLs</h3>

<p>The CRL vs OCSP debate is pointless when both proved fundamentally broken. Here’s where it gets absurd. After abandoning CRLs for being too big, then abandoning OCSP for being broken, browsers went back to… downloading lists of revoked certificates.</p>

<p>But instead of fixing the problem, they each built their own thing.</p>

<p>Chrome created <strong>CRLSets</strong>. As Adam Langley explained in the <a href="https://www.imperialviolet.org/2012/02/05/crlsets.html">announcement</a>, Chrome would crawl CRLs, compress them, and distribute updates through Chrome’s update mechanism. Except they only include “important” revocations.</p>

<p>How many is “important”? About 24,000 certificates. Meanwhile, crawling actual CRLs reveals over 2 million revoked certificates in the wild. That’s 98% of revoked certificates that Chrome simply ignores.</p>

<p>Google’s Adam Langley <a href="https://www.imperialviolet.org/2014/04/19/revchecking.html">defended this</a> saying CRLSets are “primarily a means by which Chrome can quickly block certificates in emergency situations.” Not comprehensive revocation checking. Just emergency response.</p>

<p>Firefox tried harder with <strong>CRLite</strong>, using Bloom filters to compress the full CRL dataset into about 10MB. Clever engineering, but the false positive rate means some valid certificates get flagged as revoked. The update lag means recently revoked certificates still work for <del>days</del> weeks.</p>

<p>Apple? They aggregate CRLs at the OS level. The details are fuzzy because Apple doesn’t document it, but your Mac is quietly downloading revocation lists in the background. The implementation is opaque and inconsistent.</p>

<p>Three major browsers, three different revocation approaches, three different sets of revoked certificates they’ll actually block. That certificate you revoked? Maybe it stops working in Chrome next week. Maybe Safari blocks it next month. Maybe Firefox never notices.</p>

<p>Everyone went back to CRL-style lists. Just proprietary, incompatible versions that work differently across browsers. A revoked certificate might be blocked in Chrome but work fine in Safari. Security theater at its finest.</p>

<h2 id="the-cabrowser-forum-knows-revocation-is-broken">The CA/Browser forum knows revocation is broken</h2>

<p>The best part? Everyone knows this is broken. The CA/Browser Forum discussions are filled with admissions of defeat.</p>

<p>In a <a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/i5LbJbOhGCE/m/J_5CoBgYAAAJ">2017 discussion</a>, Ryan Sleevi from Google stated bluntly: “Revocation checking doesn’t work. It’s not a matter of opinion, it’s a matter of fact demonstrated through data.”</p>

<p>The <a href="https://groups.google.com/g/mozilla.dev.security.policy">Mozilla CA policies</a> contain thread after thread of CAs reporting OCSP failures, arguing about CRL sizes, and generally acknowledging the whole system is held together with prayer and duct tape.</p>

<p>My favorite is from the <a href="https://groups.google.com/a/mozilla.org/g/dev-security-policy/c/FxDCcTVxuLo">discussion about shorter certificates</a>: “Given that revocation is fundamentally broken and we have no realistic path to fixing it, shorter certificate lifetimes are our only option.”</p>

<p>There it is. The admission. We can’t figure out how to revoke certificates, so let’s just make them expire faster.</p>

<h2 id="the-industrys-solution-just-give-up">The industry’s “solution”: just give up</h2>

<p>And that’s exactly what we’re doing. Can’t revoke certificates? Just make them expire before compromise becomes a problem.</p>

<p>The timeline tells the story:</p>
<ul>
  <li>2011: Certificates could be valid for 5+ years</li>
  <li>2015: Maximum drops to 3 years</li>
  <li>2018: Down to 2 years</li>
  <li>2020: 398 days (just over 1 year)</li>
  <li>2026: <a href="https://www.certkit.io/blog/last-call-on-398-day-certificates">200 days coming soon</a></li>
  <li>2027: 100 days</li>
  <li>2029: 47 days</li>
</ul>

<p>The <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">browsers pushed for 47-day certificates</a> because they knew they couldn’t make certificate revocation work correctly. If we can’t revoke a compromised certificate, at least it’ll expire soon. 47 days of exposure is better than a year.</p>

<p>Except now everyone needs automated renewal. The same organizations that couldn’t configure OCSP stapling now need to rotate certificates every month and a half.</p>

<h2 id="living-in-a-post-revocation-world">Living in a post-revocation world</h2>

<p>So here we are. The entire SSL certificate revocation system is broken. Everyone knows it’s broken. The browsers gave up trying to fix it. The CAs keep the infrastructure running because compliance requires it. And we all pretend it works.</p>

<p>That “Revoke Certificate” button in your CA dashboard? It updates some lists that mostly nobody checks. Your revoked certificate goes into a CRL that’s too big to download, gets flagged in OCSP that browsers ignore, and maybe, eventually, possibly, gets added to Chrome’s CRLSet if Google feels like it.</p>

<p>The one silver lining? If you’ve got <a href="https://www.certkit.io/blog/perfect-forward-secrecy">Perfect Forward Secrecy enabled</a>, at least that compromised certificate can’t decrypt your historical traffic. Broken revocation means the attacker can still impersonate you, but they can’t read last year’s secrets. Small victories.</p>

<p>This is the broken system we’re protecting with 47-day certificates. Not fixing revocation, just making certificates expire fast enough that we can pretend revocation doesn’t matter.</p>

<p>The future isn’t better certificate revocation. It’s accepting that revocation failed and building systems that assume it doesn’t exist. That’s why we built <a href="https://www.certkit.io/">CertKit</a>. If we’re stuck renewing certificates every 47 days anyway, might as well automate it properly.</p>

<p>Because the one thing worse than broken certificate revocation is manually managing certificates that expire every month and a half.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit automates certificate lifecycle management</a> for the post-revocation world. Since we can’t revoke certificates, we might as well make sure they never expire.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>BygoneSSL and the certificate that wouldn't die</title>
      <link>https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die</guid>
      <pubDate>Mon, 27 Oct 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/bygonessl-and-the-certificate.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/bygonessl-and-the-certificate.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Cybersecurity]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[When domains change hands, old certificates don&#39;t. Two researchers at DEFCON found 1.5 million domains with valid certs owned by someone else. This is the security research that killed long certificates. And why 47-day certificates aren&#39;t just browser bureaucracy. They&#39;re fixing a problem we ignored for 20 years.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/bygonessl-and-the-certificate.png" alt="BygoneSSL and the certificate that wouldn't die" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>Turns out the scariest thing about SSL certificates isn’t when they expire. It’s when they don’t.</p>

<p>I wrote about the CA/Browser fight that led to the <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">47-day certificate mandate</a>. CAs crying about lost revenue, browsers flexing their root program authority, enterprises stuck in the middle.</p>

<p>But nobody talks about the security research that started it all: <strong><a href="https://insecure.design/">BygoneSSL at DEFCON 2018</a></strong>.</p>

<p>Two researchers mining <a href="https://www.certkit.io/blog/searching-ct-logs">Certificate Transparency Logs</a> found something surprising. When domains change hands, the old owners keep their certificates. Still valid and still trusted. Over 1.5 million domains with stale “bygone” SSL certificates. <a href="https://www.certkit.io/blog/bygonessl-happened-to-us">Even one of our own certificates</a>.</p>

<p>These domains came from startups that pivoted. Projects that got sold off. Subdomains delegated to vendors. Expired domains someone else bought. All with valid certificates owned by someone else.</p>

<p>This is why we’re getting 47-day certificates. Not because browsers hate us. Because certificates that last years are fundamentally broken when domains change hands in months.</p>

<h2 id="the-stripe-problem-that-should-scare-everyone">The Stripe problem that should scare everyone</h2>

<p>Stripe (the payment processor) bought stripe.com in 2010. Started processing payments. Built the payment infrastructure for half the internet.</p>

<p>The previous owner’s certificate was valid until 2011.</p>

<p>For an entire year, someone else had a perfectly legitimate SSL certificate for Stripe’s payment processing. Trusted by every browser. No warnings. No errors. Just a valid cert for someone else’s billion-dollar payment system.</p>

<p>They didn’t use it. <em>But they could have.</em></p>

<p>This wasn’t a Stripe’s screwup. Nobody thought about old certificates when they start a new project. It wasn’t on anyone’s checklist to revoke the old certificates. BygoneSSL found them everywhere: Big companies, small companies, that side project you sold last year. All vulnerable to the same temporal trust problem.</p>

<p>Certificate validation checks if you control the domain <em>right now</em>. Not if you’ll control it next year. Or if you controlled it last year. Just now.</p>

<p>Then it gives you a certificate that lasts for years. And that’s the problem.</p>

<h2 id="what-bygonessl-actually-found">What BygoneSSL actually found</h2>

<p>Ian Foster from UC San Diego and Dylan Ayrey (now CEO of Truffle Security) did what security researchers do. They were curious about how things worked. They analyzed 3 million random domains. Just a 1% sample of the internet. The results:</p>

<ul>
  <li>
    <p><strong>0.45% had valid certificates owned by previous owners.</strong> Extrapolating that out, 1.5 million domains globally where someone else has your keys.</p>
  </li>
  <li>
    <p><strong>2.05% shared certificates with bygone domains.</strong> Those multi-domain certificates everyone uses? If one domain changes hands, the <strong>new owner can revoke the entire certificate</strong>. Seven million domains vulnerable to denial of service.</p>
  </li>
  <li>
    <p><strong>41% of these certificates were still valid.</strong> Not expired. Not revoked. Just floating around. Waiting.</p>
  </li>
</ul>

<p>CDN certificates were the worst. One cert with 700 domains. One bygone domain on that list means one person can kill service for 699 other sites. With a single revocation request. That’s a massive Denial of Service attack waiting to happen.</p>

<p>Here’s the weird part. No documented attacks. No CVEs. No breach notifications.</p>

<p>Foster and Ayrey dropped this research at DEFCON. Released detection tools immediately. CertGraph to map certificate relationships. BygoneSSL scanner to find vulnerabilities. Modified CertSpotter for continuous monitoring.</p>

<p>Free tools. Open source. Available before any bad actors could weaponize the research.</p>

<p>The security community ran with it. Started scanning. Started fixing. Started freaking out about what they found.</p>

<p>But the CAs? <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">They called it theoretical. A non-issue. Nothing to worry about</a>.</p>

<p>Right. Tell that to the 1.5 million vulnerable domains.</p>

<h2 id="why-revocation-doesnt-save-you">Why revocation doesn’t save you</h2>

<p>You might think: “Just revoke the old certificates when domains change hands.”</p>

<p>Yea, <a href="https://www.certkit.io/blog/certificate-revocation-is-broken">certificate revocation doesn’t actually work</a>. It’s been broken for years. OCSP checks fail open. Browsers cache responses for days. CRLs are too big to download. Chrome doesn’t even check revocation for most sites anymore.</p>

<p>Even if revocation worked perfectly, who’s tracking which certificates to revoke? The previous owner who sold the domain? They’re gone. The new owner? They don’t know what certificates exist. The CA? They have no idea the domain changed hands.</p>

<p>The only reliable way to kill a certificate is time. Let it expire naturally.</p>

<p>That’s why shorter certificates matter. Not for convenience. For security.</p>

<p>At least with <a href="https://www.certkit.io/blog/perfect-forward-secrecy">Perfect Forward Secrecy</a>, those bygone certificates can’t decrypt historical traffic. They can only impersonate you going forward. Small comfort, but it’s something.</p>

<p>With three-year certificates, a domain could change hands and the old owner keeps cryptographic authority for up to three years. Add domain validation reuse periods and you get 4.5 years of exposure.</p>

<p>With <a href="https://www.certkit.io/blog/last-call-on-398-day-certificates">398-day certificates</a> (what we have now), it’s better but still bad. About two years of vulnerability.</p>

<p>With 47-day certificates? Maximum exposure drops to 57 days. Domain changes hands on Monday. By the end of next month, old certificates are already dying. <a href="https://zanema.com/papers/imc23_stale_certs.pdf">Zane Ma</a> quantified this in 2024. His research showed <strong>45-day certificates would reduce domain takeover attacks by 95%</strong>.</p>

<p>That’s why we are getting 47 day certificates.</p>

<h2 id="your-certificates-are-everywhere">Your certificates are everywhere</h2>

<p>Check your Certificate Transparency logs sometime. You can use our <a href="https://www.certkit.io/tools/ct-logs/">free Certificate Transparency Log search</a>. Count how many certificates exist for your domains.</p>

<p>Now think about where they all came from:</p>

<ul>
  <li>That marketing agency you worked with two years ago</li>
  <li>The CDN you tried and abandoned</li>
  <li>Your previous hosting provider</li>
  <li>That contractor who set up your staging environment</li>
  <li>The vendor who managed your subdomain</li>
  <li>Your predecessor at the company</li>
</ul>

<p>Every one of them might still have valid certificate for your domain. Right now. Especially if you have any multi-domain certificates.</p>

<p>What if your company sold off one of those domains?</p>

<p>This isn’t paranoia. It’s the reality of how WebPKI works.</p>

<h2 id="certificate-management-is-now-a-requirement">Certificate management is now a requirement.</h2>

<p>BygoneSSL didn’t replace the old problems. It added new ones.</p>

<p>You still need to prevent downtime. Certificates still expire. Sites still go down. The CEO still notices before you do.</p>

<p>But now? Now you also need visibility into certificates you didn’t even know existed.</p>

<p>That spreadsheet tracking expiration dates? You still need something like that. But it’s not enough anymore. Doesn’t show you the certificate your former vendor still has. Or the one issued to that subdomain you forgot about. Or the 15 certificates in CT logs that you definitely didn’t request.</p>

<p>Manual processes were already failing at the basics. Now they’re completely outmatched.</p>

<p>You need automated renewal. Obviously. 47-day certificates mean monthly rotations.</p>

<p>But you also need discovery. To find certificates you didn’t issue.</p>

<p>And monitoring. For the things that go wrong.</p>

<p>Used to be you just worried about your own certificates expiring. Now you worry about everyone else’s certificates not expiring.</p>

<p>Fun times.</p>

<h2 id="what-happens-next">What happens next</h2>

<p>March 2026: Maximum certificates drop to 200 days.<br />
March 2027: 100 days.<br />
March 2029: 47 days.<br /></p>

<p>The timeline’s set. <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">Automation is mandatory now</a>. The certificate that wouldn’t die is finally getting an expiration date that matters.</p>

<p>Time to make sure you’re ready.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit</a> automates certificate management because BygoneSSL proved that manual processes are a security vulnerability. Not because we love certificates. Because ignoring them is no longer an option.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>The 47-Day Certificate Ultimatum: How Browsers Broke the CA Cartel</title>
      <link>https://www.certkit.io/blog/47-day-certificate-ultimatum</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/47-day-certificate-ultimatum</guid>
      <pubDate>Mon, 06 Oct 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/47-day-certificate-ultimatum#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/blog/2025/crying-money.gif" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/blog/2025/crying-money.gif" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Certificate Management]]>
      </category><category>
        <![CDATA[WebPKI]]>
      </category>
      <description>
        <![CDATA[For twenty years, Certificate Authorities ran the perfect protection racket. Then SHA-1 got shattered, Apple went rogue, and certificates went from lasting 3 years to 47 days. This is the story of how browsers broke the CA cartel, and why your manual certificate process is about to become your biggest problem.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/blog/2025/crying-money.gif" alt="The 47-Day Certificate Ultimatum: How Browsers Broke the CA Cartel" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>For twenty years, Certificate Authorities ran the perfect protection racket.</p>

<blockquote>
  <p>Nice website you got there. Shame if it was “Not Secure.” That’ll be $300 a year.</p>
</blockquote>

<p>The CAs had a beautiful monopoly. Browsers needed them to keep users safe. Websites needed them to look legitimate. Everyone paid up, nobody asked too many questions. Then the <a href="https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html">cryptography of most certificates (SHA-1) got shattered</a>, and the browsers realized they’d been played.</p>

<p>This is the story of how certificate lifetimes went from 3 years to 47 days, why the CAs fought every second of it, and what it means for your certificates.</p>

<h2 id="how-server-certificates-work">How server certificates work</h2>

<p>It’s called the WebPKI: the Public Key Infrastructure. Companies called “Certificate Authorities” (CA) create a Root Certificate. From that root, they sell you a certificate that proves you are who you are, and you use it to secure your website.</p>

<p>For that to work, the Root Certificate needs to be included with Chrome, Firefox, Safari, and all the other browsers and certificate consumers out there. Here’s how it works:</p>

<ol>
  <li>Joe opens mysite.com in Firefox</li>
  <li>mysite.com says, “ExampleCA said I’m cool”</li>
  <li>Firefox has the ExampleCA Root Certificate, so shows Joe that mysite.com is indeed cool</li>
</ol>

<p>For Firefox to trust the ExampleCA Root Certificate, they needs to meet a set of security and operational standards called the <strong>Baseline Requirements</strong>. This is the common rulebook that CAs are audited against for compliance.</p>

<p>The Baseline Requirements are created and maintained by the <strong><a href="https://cabforum.org/">CA/Browser Forum</a></strong>, a self-regulating organization of CAs and Browser vendors that try to improve the security of the internet through consensus votes on changes to the Baseline Requirements.</p>

<p>But here’s where it gets interesting: Each browser also maintains its own <strong>Root Program</strong> with additional requirements beyond the Baseline Requirements. Chrome has one. Apple has one. Mozilla has one. If a CA wants their root certificate trusted, they need to follow both the Baseline Requirements AND each browser’s specific rules.</p>

<p>For years, this system worked. CAs issued certificates that lasted up to three years. If something went wrong, there was supposedly a certificate revocation system (CRL), but everyone knew it was broken. Too slow, too unreliable, too privacy-invasive. <a href="https://www.certkit.io/blog/certificate-revocation-is-broken">Chrome doesn’t even check revocation lists</a>. So if a certificate was compromised, you just waited for it to expire. In three years.</p>

<p>This delicate balance held until SHA-1 showed everyone what “waiting” really cost.</p>

<h2 id="the-sha-1-betrayal">The SHA-1 Betrayal</h2>

<p>Each certificate is based on a cryptographic algorithm, and one of the most popular algorithms was SHA-1, developed by the NSA.</p>

<p>But in 2005, the first attack was published against SHA-1, showing that it could be cracked open, however it would require over $100,000 in processing power to do it.</p>

<p>The CA’s weren’t worried. “It’s only theoretical,” they said. “Too expensive to be practical.” The protection money kept flowing.</p>

<p>In 2015, the severity of the problem escalated when researchers proved that SHA-1 could be cracked in a few minutes with a $2,000 video card in an event named “The SHAppening”.</p>

<p>The response from CAs was predictable: “Our customers aren’t ready. The migration is too expensive. We need more time.”</p>

<p>Microsoft disagreed, and in one of the first major challenges to the CAB forum, <a href="https://learn.microsoft.com/en-us/security-updates/SecurityAdvisories/2016/2880823">unilaterally said that SHA-1 certificates could not be created after 2016</a>. No votes. No discussion. It was insecure for their users and they weren’t going to allow it anymore.</p>

<p>But because certificates were valid for 3 years, that meant that SHA-1 certificates could still be floating around until 2019, <em>nearly 15 years after the algorithm had first been cracked</em>.</p>

<h2 id="consensus-is-where-progress-goes-to-die">Consensus is where progress goes to die</h2>

<p>Over the next few years, various people and browser vendors tried to address the underlying problems of long certificate lifetimes, only to be met with stonewalling and frustration.</p>

<h3 id="ballot-185-googles-attempt-to-prevent-the-next-sha-1-2017">Ballot 185: Google’s attempt to prevent the next SHA-1 (2017)</h3>

<p>Fresh off the SHA-1 disaster, Google’s Ryan Sleevi proposed reducing certificate lifetimes from three years to 398 days (13 months).</p>

<p>The logic was straightforward:</p>
<ul>
  <li>Broken certificates naturally expire faster</li>
  <li>Annual renewals align with existing IT maintenance cycles</li>
  <li>Problems like SHA-1 can be fixed in one year instead of three</li>
  <li><a href="https://www.certkit.io/blog/certificate-revocation-is-broken">Since revocation doesn’t work</a>, expiration is our only reliable tool</li>
</ul>

<p>The CAs protected their turf. Only 8% of Entrust’s customers had automation—that meant 92% were still paying for manual processes and support. DigiCert worried about enterprise customers with complex approval processes. Smaller CAs argued it would drive customers to the big players who could afford automation infrastructure.</p>

<p>When <a href="https://groups.google.com/a/groups.cabforum.org/g/public/c/bvblzsjKY0M/m/f0zqMRwnAAAJ">the vote came</a>, the measure had failed due to overwhelming opposition from the CA’s.</p>

<p>Ryan’s frustration boiled over on Twitter:</p>

<blockquote>
  <p>Carefully consider the commitment to security of any CA who votes No [to Ballot 185].</p>
</blockquote>

<p>He was calling out the racket directly. The CAs weren’t protecting users—they were protecting revenue.</p>

<h3 id="ballot-sc22-the-alliance-of-browsers-2019">Ballot SC22: The alliance of browsers (2019)</h3>

<p>Two years later, Google returned with Apple and Let’s Encrypt backing them. They had new evidence:</p>

<ul>
  <li>Between certificate lifetime and domain validation re-use, stale certificates could persist for up to 4.5 years!</li>
  <li>Domains change hands frequently, but old certificates remain valid</li>
  <li>Support tickets proved customers literally forgot their renewal procedures after two years</li>
</ul>

<p>The CAs demanded evidence of real-world harm, not theoretical problems. “Show us actual incidents,” the CAs said.</p>

<p>The browsers pointed to SHA-1. That was theoretical until it wasn’t.</p>

<p>The <a href="https://github.com/cabforum/cabforum.org/blob/aed8250a6af012dc979417ce091a685f274762e9/content/posts/2019/2019-09-10-ballot-sc22-reduce-certificate-lifetimes-v2.md">vote split exactly as before</a>. Browsers: unanimous yes. CAs: overwhelming no.</p>

<p>The committee had failed twice.</p>

<h2 id="apple-changes-the-game-2020">Apple changes the game (2020)</h2>

<p>At the February 2020 CA/Browser Forum meeting in Bratislava, <a href="https://cabforum.org/uploads/11-Apple-Root-Program-Update.pdf">Apple made an announcement that changed everything</a>:</p>

<blockquote>
  <p>Effective September 1, 2020, certificates valid for more than <strong><a href="https://www.certkit.io/blog/last-call-on-398-day-certificates">398 days will not be trusted in Apple</a></strong> products.</p>
</blockquote>

<p>No vote. No consensus. Just a unilateral change to their Root Program requirements. They cited the forum’s failures to pass Ballot 185 and SC22 as reasons they needed to act alone.</p>

<p>The CAs were stunned. Chris from Entrust captured their sentiment: “The Forum was created to set these policies together. This undermines the entire process.”</p>

<p>But Mozilla and Microsoft countered: “We saw the same resistance with SHA-1. After the ballot failed, CAs didn’t move. Sometimes we have to act to protect users.”</p>

<p>Within days, Mozilla and Google signaled they would follow Apple’s lead. The 398-day limit was happening whether CAs liked it or not.</p>

<h2 id="ballot-sc31-browser-alignment-late-2020">Ballot SC31: Browser Alignment (Late 2020)</h2>

<p>The Baseline Requirements were, at this point, very different than the practical rules of the browsers’ Root Programs. To make them useful again, the browsers wanted to update the Baseline Requirements to reflect what was already happening: Apple’s 398-day limit that others were adopting, amongst other things.</p>

<p>This vote became existential. If the Forum couldn’t even update its requirements to match reality, why does the forum exist?</p>

<p>Ryan Sleevi laid out the stakes: If CAs blocked this, browsers may as well abandon the Forum entirely. Instead of one shared audit against Baseline Requirements, each browser could require its own separate audit. The cost multiplication to CAs would be devastating.</p>

<p>Faced with this reality, SC31 passed. But the power dynamic had permanently shifted. Browsers could now make unilateral changes and force the Forum to catch up.</p>

<h2 id="risks-of-stale-certificates-mount">Risks of stale certificates mount</h2>

<p>By 2024, there was mounting evidence of the dangers posed by even 398-day certificates. Certificates only represent validation at the moment they’re issued. But that validation was being cached for up to a year, and certificates issued from that cached validation lived even longer.</p>

<p>Ian Foster and Dylan Ayrey coined [this “stale certificate” problem as <strong><a href="https://www.certkit.io/blog/bygonessl-and-the-certificate-that-wouldnt-die">BygoneSSL</a></strong>. Their research showed a simple but devastating issue: domains change hands constantly (companies switch vendors, contracts end, or subsidiaries get sold) but the certificates remain valid. A fired vendor could have legitimate certificates for your subdomain for over a year after you terminated their access.</p>

<p>Then, <a href="https://zanema.com/papers/imc23_stale_certs.pdf">Zane Ma from Oregon State University presented research</a> at the October 2024 CA/Browser Forum meeting that quantified exactly how bad this was. His paper found that 7% of all certificates were stale, and that shortening certificate lifetimes to 45 days would reduce the impact of domain takeover attacks by 95%. The difference between 398 days and 45 days wasn’t incremental improvement, it was the difference between massive vulnerability and relative safety.</p>

<h2 id="the-market-proved-short-term-certificates-work-2024">The Market proved short-term certificates work (2024)</h2>

<p>But the final nail in the coffin was market data. <strong><a href="https://w3techs.com/technologies/history_overview/ssl_certificate/all/y">Let’s Encrypt grew from 0.1% market share in 2020 to 59% in 2024</a>.</strong></p>

<p>Let’s Encrypt is a non-profit CA launched in 2016, backed by Mozilla, the EFF, and other tech giants who were tired of certificates being a barrier to HTTPS adoption. Their radical idea: give away certificates for free, make the process completely automated, and only issue 90-day certificates. No upsells. No extended validation. No manual processes.</p>

<p>CAs said it would never work. Enterprises couldn’t handle 90-day certificates. The automation was too complex. Customers needed phone support. But 8 years later, Let’s Encrypt issues certificates for the majority of the encrypted web. They process millions of renewals daily. All automated. All 90-day lifetimes. And users don’t know or care about the difference between a free, short-lived cert from Let’s Encrypt and an expensive, year-long cert from Digicert.</p>

<h2 id="the-road-to-47-days-2025">The road to 47 days (2025)</h2>

<p>Spurred and shamed by Zane Ma’s research and the success of Let’s Encrypt, in January 2025, Apple, Google, and Mozilla introduced Ballot SC081 with a shocking timeline to reduce certificate lifetimes:</p>

<ul>
  <li><strong>March 2026</strong>: 200 days maximum</li>
  <li><strong>March 2027</strong>: 100 days maximum</li>
  <li><strong>March 2029</strong>: 47 days maximum</li>
</ul>

<p>The <a href="https://groups.google.com/a/groups.cabforum.org/g/servercert-wg/c/3q07n2tISkI/m/QvEQXcbLAgAJ">CAs tried to protect their turf</a>: Enterprise customers have change freezes. Government systems require extensive approvals. Legacy applications can’t automate. Please, keep 100 days as the minimum.</p>

<p>But unexpected support came from the customers themselves. Netflix joined the CAB as an “Interested Party” to share: “We need these deadlines to justify automation investment internally. Approval of this ballot is justification enough to resource this work.”</p>

<p>Even Cisco, representing the enterprise perspective, admitted that while five years would be ideal for implementation, the direction was inevitable.</p>

<p>The most telling objection came from a CA: “This proposal seems anti-competitive, giving advantage to companies with better certificate lifecycle management.” They were right, and that was exactly the point. It’s time to automate or get out of the way.</p>

<p>The vote didn’t really matter. If it didn’t pass, Apple or Google or Mozilla was going to do it anyway. <a href="https://groups.google.com/a/groups.cabforum.org/g/servercert-wg/c/bvWh5RN6tYI/m/ffUEDfhwCgAJ">But the CAs agreed and 47 day certs became reality</a>.</p>

<h2 id="what-happens-next">What happens next</h2>

<p>47 Day certificates are happening. The real question is whether your infrastructure will be ready.</p>

<p>Some companies are already there. They’ve been using Let’s Encrypt for years, renewing every 60-90 days automatically. Dropping to 47 days is just a configuration change.</p>

<p>Others are scrambling. They’re <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">evaluating ACME clients</a>, testing automation workflows, and discovering just how many random systems need certificates: that ancient Java application, network appliance, or vendor system that only accepts manual certificate uploads.</p>

<p>And many are just now realizing what’s coming. They’re still on manual processes, still treating certificate renewal as a quarterly maintenance task. They’re about to have a very bad time.</p>

<h2 id="the-new-certificate-business">The new certificate business</h2>

<p>The same CAs that insisted automation was impossible for their customers are now selling automation platforms: DigiCert CertCentral, Entrust Certificate Hub, Sectigo Certificate Manager. How much extra are they charging for these tools? Contact sales to find out, of course.</p>

<p>The irony is rich. For years, CAs said enterprises couldn’t handle 90-day certificates. Now they’re selling those same enterprises “solutions” to handle 47-day certificates. The certificates themselves? Basically free, thanks to Let’s Encrypt. The management platforms? That’s where the real money is now.</p>

<p>Instead, lots of folks build the automation themselves based on CertBot and bash scripting. But you quickly find that all the features of a <a href="https://www.certkit.io/blog/why-you-built-your-own-certificate-management">Certificate Management System are difficult to debug and maintain</a> when you have a thousand other responsibilities.</p>

<p>The CAs will charge you enterprise prices to manage the complexity they helped create. Or you can build your own solution and discover why certificate management is everyone’s least favorite infrastructure project.</p>

<p>That’s a crappy choice, and it’s <a href="https://www.certkit.io/blog/why-we-built-certkit">why we built CertKit</a>. Because we don’t have conflicting interests. We don’t sell certificates. We just want certificate management to not be your problem anymore.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit is certificate management software</a> built for the 47-day future. Currently in beta for teams who’d rather automate now than panic in 2029.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>You Built Your Own Certificate Management System - It's Already Broken</title>
      <link>https://www.certkit.io/blog/why-you-built-your-own-certificate-management</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/why-you-built-your-own-certificate-management</guid>
      <pubDate>Mon, 15 Sep 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/why-you-built-your-own-certificate-management#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/brand/certkit-share-image.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/brand/certkit-share-image.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[ACME]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[It started as 47 beautiful lines of bash. Now it&#39;s a distributed certificate system built on thousands of command line incantations nobody understands, running on every server and some of the printers. If someone looks at it the wrong way, a certificate expires.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/brand/certkit-share-image.png" alt="You Built Your Own Certificate Management System - It's Already Broken" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>You were tired of renewing all those certificates, and Certbot looked so easy. Now you have scripts thousands of lines long filled with command line incantations you have to Google every time you open it. The script is running on all the critical servers. And some of the printers.</p>

<p>If someone looks at it the wrong way, a certificate expires.</p>

<h2 id="its-just-certbot---how-hard-could-it-be">“It’s just Certbot - How Hard Could It Be?”</h2>

<p>47 lines of bash. Beautiful. Clean. Renewed the web cert, sent a Slack message. It was perfect for three whole months.</p>

<p>Then marketing needed wildcards.</p>

<p>Then security demanded monitoring. Not just “is it valid” but “what’s the cipher strength” and “who touched it last” and fifteen other things nobody looks at.</p>

<p>The CEO wanted an email if anything is going to expire soon.</p>

<p>Now it’s thousands of lines long. Running as root. Via cron jobs that fire at different times because “we don’t want to hammer Let’s Encrypt.”</p>

<p>Your script needs OpenSSL 1.1.1 exactly. Bob’s AWS credentials from line 1,847. That Jenkins job nobody remembers. Touch any of it and production goes down.</p>

<h2 id="what-proper-certificate-management-could-do">What Proper Certificate Management Could Do</h2>

<p>If only you could do it over again. You could build a <em>proper certificate management system</em>. It would do more than <a href="https://www.certkit.io/blog/servers-shouldnt-need-acme">just renew the certificates</a>. It would do useful and professional things like:</p>

<p><strong>Certificate Discovery.</strong> Scan your domains and find the certificates you forgot existed–or never knew about. Your script manages a hardcoded list in a text file. Maybe a spreadsheet if you’re fancy.</p>

<p><strong>Certificate Inventory.</strong> Proper systems would know every certificate in your infrastructure. Yours? It knows about the ones you told it about. That Jenkins server from 2019? The VPN appliance? That staging environment on Bob’s old laptop? Nobody’s tracking those.</p>

<p><strong>Certificate Transformation.</strong> Need to convert PEM to PFX for that Windows server? Your script shells out to OpenSSL with parameters you copied from Stack Overflow. Works great until someone needs PKCS#12 with specific cipher suites.</p>

<p><strong>Certificate Expiry Monitoring.</strong> The old script just checks the certificate in the filesystem–not what’s actually running. If something failed to update, you’ll know when users start complaining.</p>

<p><strong>Secure Distribution.</strong> Your script has root SSH access to everything. Security loves that. Or it’s copying private keys through a shared folder. Or that one team that uses Git for cert distribution.</p>

<h2 id="the-features-youll-never-get-around-to-building">The Features You’ll Never Get Around to Building</h2>

<p>You tell yourself you’ll add these features “next quarter.” You won’t.</p>

<p><strong>Role-based access control.</strong> Right now everyone who needs to manage certs has root access to the script server. That’s fine, right?</p>

<p><strong>Audit trails.</strong> Who renewed what when? Who knows. The script doesn’t log that. Check the bash history if it hasn’t rolled over.</p>

<p><strong>Alerting that works.</strong> Email alerts go to a distribution list that nobody reads. Slack integration? That’s on the roadmap. Has been for two years.</p>

<p><strong>Backup and recovery.</strong> The script is in Git. Probably. Someone might have committed the latest version. The certificates themselves? Hope you have backups.</p>

<p><strong>Multi-region support.</strong> Each region has its own slightly different version of the script. They diverged years ago. Nobody knows what the differences are anymore.</p>

<h2 id="its-time-to-get-help">It’s Time to Get Help</h2>

<p>Look, your homegrown system meant well. You learned what breaks. What matters. What you actually need from certificate automation.</p>

<p>Now let someone else worry about all <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">the ACME protocol</a> changes on the weekend, distribution, monitoring, and other tasks. Get back to the work that you should have been doing. That’s what we’re building with CertKit.</p>

<p>Simple, Centralized, Transparent TLS Certificate Management.</p>

<p>Not a bash script held together with hope and regular expressions.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit is certificate management</a> for companies tired of maintaining their own broken systems. Currently in beta, accepting teams who’ve learned this lesson the hard way.</em></p>

        ]]>
      </content:encoded>
    </item>
    
    
    
    
    <item>
      <title>Why We Built CertKit</title>
      <link>https://www.certkit.io/blog/why-we-built-certkit</link>
      <guid isPermaLink="true">https://www.certkit.io/blog/why-we-built-certkit</guid>
      <pubDate>Wed, 03 Sep 2025 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[Todd H. Gardner]]></dc:creator>
      <comments>https://www.certkit.io/blog/why-we-built-certkit#comments</comments>
      <enclosure url="https://www.certkit.io/assets/images/brand/certkit-share-image.png" type="image/png" />
      <media:content medium="image" url="https://www.certkit.io/assets/images/brand/certkit-share-image.png" type="image/png" width="1200" height="630" />
      <category>
        <![CDATA[Product]]>
      </category><category>
        <![CDATA[Certificate Management]]>
      </category>
      <description>
        <![CDATA[SSL certificates have always been a pain. Now Apple wants us to renew them every 47 days. We watched a DevOps team waste six hours debugging CertBot, tried every tool from Cert Manager to DigiCert, then said screw it. We built CertKit - certificate management for people with better things to do.]]>
      </description>
      <content:encoded type="html" xml:base="https://www.certkit.io/">
        <![CDATA[
          <div><img src="https://www.certkit.io/assets/images/brand/certkit-share-image.png" alt="Why We Built CertKit" width="1200" height="630" class="webfeedsFeaturedVisual" /></div>
          <p>SSL Certificates have always been a pain in the butt.</p>

<p>From the magical OpenSSL incantations to generate a CSR to the various formats that each webserver requires. Remembering what hardware needs which certificates. Managing scheduled renewals and runbooks for which file goes where.</p>

<p>Screw anything up and your site is “Not Secure”.</p>

<p>And now <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">Apple wants us to do it every 47 days</a>.</p>

<p>Remember when we had HTTP-only websites? Or when certificates lasted three years? Then one? At this rate, by 2030 we’ll be renewing certs for every request.</p>

<h2 id="our-breaking-point">Our Breaking Point</h2>

<p>Last year, I watched a perfectly competent DevOps team spend six hours debugging why their automated certificate renewal stopped working. The culprit? CertBot updated, their ancient Ubuntu install didn’t, and <a href="https://www.certkit.io/blog/how-acme-protocol-automates-certificate-issuance">the ACME protocol</a> had “opinions” about TLS versions.</p>

<p>Six. Hours.</p>

<p>That’s when we decided we needed to build something better. Not another command-line tool that works–until it doesn’t. Not an enterprise PKI suite that requires a PhD to operate. Just something that handles certificates and gets out of the way.</p>

<h2 id="we-tried-everything-else-first">We Tried Everything Else First</h2>

<p>Trust me, we didn’t want to build another tool. We tried them all.</p>

<p><strong>CertBot?</strong> Works great. For one cert on one server.</p>

<p>Need <a href="https://www.certkit.io/blog/do-you-still-need-wildcard-certificates">wildcard certificates</a> across a web farm? Now you’re writing special routing rules. Opening port 80. Praying the validation server stays up.</p>

<p>Got the cert? Cool. Now distribute it to 50 other servers. Hope you like rsync. The official CertBot solution for multiple servers is literally “figure it out yourself.”</p>

<p>I’ve seen it all. Dropbox folders full of <a href="https://www.certkit.io/blog/perfect-forward-secrecy">private keys</a>. Git repos anyone can clone. That one team using Ansible until they accidentally pushed to production instead of staging.</p>

<p>Whoops.</p>

<p><a href="https://www.certkit.io/blog/servers-shouldnt-need-acme">CertBot conflates certificate renewal with certificate distribution</a>.</p>

<p><strong>Cert Manager?</strong> Fantastic if your entire infrastructure lives in Kubernetes and you enjoy writing YAML manifestos. For the rest of us living in the real world with legacy systems, Windows servers, and that one critical app running under Bob’s desk? Not so much.</p>

<p><strong>Commercial solutions?</strong> DigiCert wants to sell you an “enterprise certificate lifecycle management platform” starting at just $call-for-pricing. What a deal!</p>

<p>So we built CertKit. Here’s what makes it different.</p>

<h3 id="transparency-that-actually-helps">Transparency That Actually Helps</h3>

<p>Every certificate management tool claims to offer “monitoring.” What they mean is an email when something expires. Maybe a dashboard if you’re lucky.</p>

<p>CertKit shows you everything. Which certificates are where. When they were last checked. What’s about to expire. What already expired but nobody noticed because it’s on that staging server everyone forgot about. Realtime <a href="https://www.certkit.io/blog/searching-ct-logs">monitoring the Certificate Transparency logs</a> to know everything happening. Real monitoring means knowing about problems before they become problems.</p>

<p>And alerts? They go where you actually look. Email, Slack, Teams (if we have to).</p>

<h3 id="a-gui-that-doesnt-suck">A GUI That Doesn’t Suck</h3>

<p>I know, I know. Real sysadmins prefer their certificate management artisanal. Hand-crafted bash scripts. Locally-sourced cron jobs. Small-batch OpenSSL commands passed down through generations.</p>

<p>But you know what? Sometimes I just want to click a button and add a certificate without writing a config file. Sometimes the new junior admin needs to provision a cert without learning the entire ACME RFC.</p>

<picture class="include blog-post-image flex justify-center" data-enlargeable="">
  <img src="https://www.certkit.io/assets/images/blog/2025/certkit-dashboard.png" loading="lazy" alt="CertKit Dashboard" width="1800" height="960" />
</picture>

<p>CertKit has a dashboard that actually makes sense. Add certificates, remove them, see what’s happening. No need to SSH into three different boxes to figure out why something’s broken.</p>

<h3 id="the-ssl-certificates-you-forgot-about">The SSL Certificates You Forgot About</h3>

<p>That Jenkins server from 2018. The VPN appliance. The marketing WordPress site. CertKit discovers certificates across your infrastructure automatically. No more surprise expirations from forgotten systems.</p>

<h3 id="it-just-works">It Just Works™</h3>

<p>This is the part where I’m supposed to say “robust enterprise-grade reliability” or some nonsense you’d find in a whitepaper.</p>

<p>Here’s what I mean: CertKit doesn’t break when your Linux distro updates. Or when Let’s Encrypt changes their API. It handles the edge cases because someone’s actually paying attention.</p>

<p>Unlike the bash script Terry wrote in 2019 before he left for a “better opportunity”, someone’s maintaining it. We’re fixing it before you even know it’s broken.</p>

<h3 id="centralized-without-the-single-point-of-failure">Centralized Without the Single Point of Failure</h3>

<p>“But what if your service goes down?”</p>

<p>Fair question. But CertKit isn’t in the critical path. We push certificates to your infrastructure. If we go down, your sites keep running with their current certs. You’ve got time to fix things.</p>

<p>Compare that to distributed setups where every server runs its own renewal process. One fails, you might not notice until customers complain.</p>

<h3 id="dns-without-the-security-nightmare">DNS Without the Security Nightmare</h3>

<p>Want wildcard certificates? Every tool makes you hand over your DNS API keys. Full access to your entire domain. What could go wrong?</p>

<p>CertKit uses <a href="https://www.certkit.io/blog/delegated-dns-validation">delegated DNS validation</a>. We only touch TXT records for ACME challenges. Can’t accidentally delete your MX records. Can’t redirect your domain to a crypto scam–even if it’s going to the moon. Just the minimum access needed for certificate validation.</p>

<p>This will be even easier when the new <a href="https://www.certkit.io/blog/dns-persist-01">DNS-PERSIST-01 validation method</a> launches.</p>

<h2 id="the-futures-getting-worse">The Future’s Getting Worse</h2>

<p>How long can digital certificates be valid? If you ask Google, not very long. Right now you can get a 1 year certificate. Next March, you’ll only get 200 days.</p>

<p>March 2027? 100 days.</p>

<p>We’re on the way to <a href="https://www.certkit.io/blog/47-day-certificate-ultimatum">47 day certificates</a>.</p>

<p>Some people are seriously discussing daily certificate rotation.</p>

<p>Daily.</p>

<p>Your full-time job is renewing certificates now.</p>

<p>Manual processes won’t cut it. Half-baked automation will break constantly. You need something built for this insane future we’re heading toward.</p>

<p>That’s why we built CertKit. Not because we love certificates. Because we’re tired of them.</p>

<h2 id="let-us-worry-about-ssl-certificates">Let Us Worry About SSL Certificates</h2>

<p>Look, I’m not going to pretend CertKit’s perfect. Nothing is. But it’s better than what you’re doing now. And it’s <a href="https://www.certkit.io/roadmap">getting better with every release from our roadmap</a>.</p>

<p><a href="https://www.certkit.io/blog/why-you-built-your-own-certificate-management">Stop maintaining your own certificate infrastructure</a>. Stop debugging renewal failures. Stop explaining to management why the certificate expired.</p>

<p>Just let CertKit handle it. Your future self will thank you.</p>

<hr />

<p><em><a href="https://www.certkit.io/">CertKit is TLS certificate management</a> software for people who have better things to do. Currently in beta, accepting users who are tired of SSL certificate hell.</em></p>

        ]]>
      </content:encoded>
    </item>
    
  </channel>
</rss>
