You revoked the certificate. Now what?
So a private key leaked. Maybe someone pushed it to a public GitHub repo (it happens more than anyone wants to admit). You contact your CA, fill out the revocation request, and within minutes the certificate is marked as revoked. Done, right?
Not even close.
The dirty secret of certificate revocation is that the entire system is held together by optimistic assumptions and soft failures. Most browsers won't even check if your certificate was revoked. And the ones that do? They'll usually shrug and connect anyway if the check fails. This has been the state of things for over a decade, and while there have been improvements, the fundamental problem hasn't gone away.
Two mechanisms, both flawed
There are two main ways a client can find out a certificate has been revoked: CRLs and OCSP. Both were designed in the 90s. Both carry baggage.
Certificate Revocation Lists (CRLs) are exactly what they sound like. The CA publishes a signed list of serial numbers that have been revoked. Your browser downloads the list, checks if the cert's serial number is on it. Simple concept.
The problem is scale. Let's Encrypt alone has issued billions of certificates. Even with delta CRLs (incremental updates rather than full lists), you're asking every client to download and parse potentially massive files. Some CAs had CRLs that grew to several megabytes. On a flaky mobile connection, that's a non-starter.
OCSP (Online Certificate Status Protocol) tried to fix this by making it a real-time query. Instead of downloading the whole list, your browser asks the CA's OCSP responder: "Is this specific certificate still good?" You get back a signed response saying "good", "revoked", or "unknown".
Better in theory. But now you've introduced a hard dependency on the CA's infrastructure for every single TLS connection. And CA OCSP responders go down. Regularly.
The soft-fail problem nobody talks about
Here's where it gets ugly. When Chrome circa 2012 couldn't reach an OCSP responder, it had two choices: block the connection (hard-fail) or proceed anyway (soft-fail). Google chose soft-fail, and then eventually just stopped checking OCSP altogether for most certificates.
Their reasoning wasn't crazy. If an attacker can compromise a certificate, they can probably also block your OCSP request. A network-level attacker just drops the packets to the OCSP responder, the browser soft-fails, and the revoked cert works fine. So the check only catches accidental revocations, not malicious ones. Meanwhile, it adds latency to every connection and creates a privacy leak because you're telling the CA every site you visit.
Adam Langley wrote about this back in 2012. He called OCSP checking "a seatbelt that snaps when you crash." That metaphor still holds.
OCSP Stapling: the less terrible option
OCSP stapling flips the model. Instead of the browser asking the CA, the server periodically fetches its own OCSP response and "staples" it to the TLS handshake. The response is signed by the CA, so the server can't forge it. The browser gets revocation info without a separate network request, without the privacy leak, without the latency hit.
Configuring it in Nginx looks straightforward:
server {
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/chain.pem;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
}
And Apache:
# Enable in your VirtualHost
SSLUseStapling On
SSLStaplingCache shmcb:/tmp/stapling_cache(128000)
SSLStaplingResponseMaxAge 900
But there's a catch. If the server doesn't staple a response, most browsers just... carry on without one. The OCSP Must-Staple extension was supposed to fix this. You set a flag in the certificate that tells browsers "if there's no stapled response, reject the connection." Adoption has been glacial. Most CAs don't push it, most server admins don't request it, and if your OCSP stapling breaks (which it will, eventually, because the CA's responder had an outage or your caching expired), your site goes down.
What Chrome actually does instead
Google went a different direction entirely. They created CRLSets, which are curated subsets of revoked certificates that Chrome considers high-priority. These get pushed through Chrome's update mechanism, so there's no per-connection overhead. But CRLSets only cover a tiny fraction of all revoked certificates. Google has been transparent about this: CRLSets are for emergency response (think Heartbleed-level events), not comprehensive revocation coverage.
Firefox still checks OCSP for EV certificates but soft-fails on errors. Safari does its own thing with a proprietary aggregation approach. The fragmentation is real.
So if you're relying on browser-side revocation checking to protect your users after a key compromise, you're building on sand.
CRLite: Mozilla's bet
Mozilla has been working on CRLite, and it's genuinely clever. The idea: use Certificate Transparency logs to get a complete view of all issued certificates, then use cascading Bloom filters to compress the entire revocation status of every certificate on the internet into something small enough to ship with browser updates. We're talking around 1.3 MB for the initial filter, with daily deltas of a few kilobytes.
CRLite can hard-fail because it has complete information. If the filter says a cert is revoked, it IS revoked, no network request needed. No privacy concerns. No latency. No availability dependency on CA infrastructure.
It's been in Firefox Nightly for a while. Production rollout has been slow, but this is probably the most promising approach anyone has come up with.
What you should actually do
Given all of this, what's the practical advice?
Enable OCSP stapling. Yes, it's imperfect. It's still better than nothing, and it's basically free once configured. Test it:
# Check if stapling is working
openssl s_client -connect yourdomain.com:443 -status 2>/dev/null | grep -A 5 "OCSP Response"
# You want to see "OCSP Response Status: successful"
# If you see nothing, stapling isn't working
Use short-lived certificates. This is the real answer to the revocation problem. If your certificate expires in 90 days (Let's Encrypt default), the window of exposure from a compromised key is bounded. Some organizations are moving to even shorter lifetimes, 7 days or even 24 hours, using automated issuance. At that point, revocation becomes less critical because the cert will expire before most CRLs even propagate.
Monitor Certificate Transparency logs. You can't always prevent key compromise, but you can detect unauthorized certificate issuance for your domains. Services like CertGuard watch CT logs and alert you when new certs appear for your domains. If someone gets a fraudulent cert issued, you'll know fast.
Automate everything. The number one cause of "we need to revoke this cert" situations I've seen? Certs that were manually managed, had their keys stored in shared drives or Slack channels, and nobody tracked who had access. Automate issuance with ACME, store keys in a secrets manager, rotate them on a schedule.
The uncomfortable truth
Revocation exists, but it doesn't work the way most people assume. If you revoke a certificate today, some users will still trust it tomorrow. Some will trust it next week. A few niche clients that do hard-fail OCSP checking will reject it immediately, but mainstream browsers? They'll likely keep accepting it until it naturally expires.
The industry is slowly converging on "just make certificates short-lived" as the real solution. And honestly? That's probably right. Revocation was always a patch over the fact that we were handing out certificates valid for years. When your cert lives for 90 days, or 7 days, the entire revocation question becomes a lot less terrifying.
But we're not fully there yet. Plenty of organizations still run certificates valid for 398 days. For those, understanding the gaps in revocation isn't optional. It's the difference between thinking you're secure after revoking a compromised cert and knowing that you might not be.