Frontend Labs
⋯

Chapter 30 — PKI: certificate authorities, transparency, revocation, ACME

In one sentence

The Web PKI is the global system of ~50 trusted certificate authorities, kept mostly honest by browser root programs, public Certificate Transparency logs, and automated issuance — and it's a fragile, fascinating piece of infrastructure.

The trust store: where "trusted" comes from

   Your OS/browser ships a ROOT STORE: a few hundred CA root certificates,
   curated by ROOT PROGRAMS -- Mozilla (the de facto standard), Microsoft,
   Apple, Google, Chrome.

   To get in, a CA must pass annual audits (WebTrust / ETSI), follow the
   CA/Browser Forum "Baseline Requirements", and stay out of trouble.

   To be REMOVED (it happens): mis-issue certs, lie about it, or run sloppy
   infrastructure. DigiNotar (2011, hacked, issued fake *.google.com ->
   dead within weeks). Symantec (2017-18, years of misissuance -> entire
   root distrusted, business sold). TrustCor (2022, opaque ownership ->
   removed).

Any CA in the store can issue a cert for any domain. That's the PKI's original sin: your security depends on all ~50 CAs, not just the one you chose. The mechanisms below exist to contain that.

Certificate Transparency (CT)

Since ~2018, browsers reject certificates that aren't logged in public, append-only CT logs.

   CA issues a cert  ->  submits it to >= 2 independent CT logs
                     ->  each log returns a Signed Certificate Timestamp (SCT)
                     ->  SCTs are embedded in the cert (or stapled)
   Browser  ->  refuses the cert unless it carries enough valid SCTs

   RESULT: every publicly-trusted certificate is publicly visible.
   Domain owners (and researchers) MONITOR the logs and get alerted to
   unexpected certs for their domains -- turning silent mis-issuance into
   a loud, detectable event, usually within minutes.
   # See every cert ever logged for a domain:
   curl -s 'https://crt.sh/?q=%25.wikipedia.org&output=json' | head -c 2000
   # Set up monitoring: crt.sh RSS, or Cloudflare/Meta/Cert Spotter alerts,
   # or run your own with certstream.

CT doesn't prevent mis-issuance; it makes it undeniable and fast to catch. That's been enough to keep CAs disciplined.

Revocation: the part that doesn't really work

If a private key leaks or a cert was mis-issued, you want to revoke it. Three mechanisms, all flawed:

   CRL (Certificate Revocation List)
     A signed list of revoked serials, published by the CA. Can be huge
     (megabytes). Clients rarely fetch them in real time.

   OCSP (Online Certificate Status Protocol)
     Client asks the CA "is serial 12345 still good?" per connection.
     Problems: latency, a privacy leak (the CA learns which sites you
     visit), and -- fatally -- most clients "soft-fail": if the OCSP
     responder is unreachable, they proceed anyway. An attacker who can
     MITM can just block OCSP. So OCSP provides little real security.
     (Let's Encrypt ENDED OCSP service in 2025.)

   OCSP STAPLING
     The SERVER fetches its own OCSP response periodically and "staples"
     it into the handshake. Fixes latency and privacy. But it's optional
     unless the cert has the "must-staple" flag (rarely used).

   WHAT ACTUALLY WORKS TODAY:
     * SHORT-LIVED CERTS. 90-day (moving to 47-day by 2029, per CA/B Forum)
       and even ~7-day certs mean a leaked key is only useful briefly.
       Expiry IS the revocation strategy.
     * Browser-pushed lists: Chrome CRLSets, Mozilla CRLite -- the CA
       ecosystem's revocations, compressed and shipped with the browser.

Takeaway: don't rely on revocation catching a compromise. Rely on short lifetimes, automation, and detection.

ACME and Let's Encrypt

ACME (RFC 8555) is the protocol that automated certificate issuance and killed the "expired cert" outage as a common event.

   1. Your ACME client (certbot, acme.sh, lego, Caddy, cert-manager,
      Traefik) generates a key and a CSR.
   2. It asks the CA (Let's Encrypt, ZeroSSL, Google Trust Services...)
      for a cert for example.com.
   3. The CA issues a CHALLENGE proving you control the domain:
        HTTP-01: serve a token at http://example.com/.well-known/acme-challenge/<t>
        DNS-01:  publish a TXT record _acme-challenge.example.com = <hash>
                 (this one can do WILDCARDS)
        TLS-ALPN-01: present a special cert on a TLS connection
   4. Client completes the challenge; CA verifies from multiple network
      vantage points (multi-perspective validation, to resist BGP hijacks).
   5. CA issues a 90-day cert. Client auto-renews at ~60 days. Forever.
   # The modern easy path -- Caddy does ACME automatically:
   #   caddy reverse-proxy --from shop.example --to localhost:8080
   # or certbot:
   #   sudo certbot --nginx -d shop.example -d www.shop.example

Let's Encrypt issues for hundreds of millions of domains. It made HTTPS free and automatic — which is why the web went from ~40% to ~95%+ HTTPS in a decade (and why phishing sites have padlocks too).

CAA records: telling CAs "only these may issue for me"

   DNS:  example.com.  CAA  0 issue "letsencrypt.org"
         example.com.  CAA  0 issuewild ";"     (no wildcards for anyone)
         example.com.  CAA  0 iodef "mailto:security@example.com"

CAs are required to check CAA before issuing. It's a cheap, strong control: even a compromised or tricked CA that isn't on your list must refuse. Set it.

Practice (35 min)

cd ~/sec-lab/scratch

# 1. Certificate Transparency: every cert for a domain
curl -s 'https://crt.sh/?q=wikipedia.org&output=json' \
  | python3 -c "import json,sys; [print(r['not_before'][:10], r['issuer_name'][:40], r['name_value'][:60]) for r in json.load(sys.stdin)[:20]]"

# 2. Check a site's CAA records
dig +short CAA wikipedia.org
dig +short CAA github.com

# 3. Inspect OCSP / stapling on a real site
echo | openssl s_client -connect wikipedia.org:443 -servername wikipedia.org \
        -status 2>/dev/null | grep -A 6 "OCSP response"

# 4. Run a real ACME issuance in a container (staging environment -- no rate limits)
docker run --rm -it -p 80:80 certbot/certbot certonly --standalone \
   --staging --non-interactive --agree-tos -m you@example.com \
   -d "$(curl -s ifconfig.me).nip.io" 2>&1 | tail -20
   # (nip.io gives you a real DNS name for any IP -- handy for labs)

# 5. Look at your OS trust store
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain 2>/dev/null | grep -c "BEGIN CERT"   # macOS
# ls /etc/ssl/certs/ | head                                                    # Linux

Mini-project (45 min): CT monitor for your domain

   Build a script that:
   1. Every run, queries crt.sh (or certstream) for all certs issued for
      YOUR domain (or wikipedia.org for practice) in the last 24h.
   2. Diffs against a stored list of known/expected certs (issuer + SANs).
   3. On anything unexpected: prints a loud alert (and, optionally, sends
      a notification).
   4. Cron it hourly.

   This is exactly what real security teams run. An unexpected cert for
   your domain = someone is preparing to impersonate you, or an internal
   team went around process. Either way you want to know in minutes.

Common confusions

  • "I chose a good CA, so I'm safe." Any trusted CA can issue for your domain. CAA + CT monitoring is how you constrain and watch that.
  • "Revocation protects me if my key leaks." Mostly not — soft-fail OCSP and un-fetched CRLs. Short lifetimes + automation are the real answer.
  • "Let's Encrypt is less secure — it's free and instant." It does DV, exactly like paid DV certs, and its automation makes it more reliable. The cert's cryptographic value is identical.
  • "Self-run internal CA needs CT." No — CT is a Web PKI (public trust) requirement. Your private CA for internal services doesn't need it (but an internal transparency log is still a nice-to-have).
  • "EV certificates stop phishing." Browsers removed the EV UI because it didn't. DV + user education + phishing-resistant auth (Part 8/10) do more.

Check yourself

  1. What does it mean that "any trusted CA can issue for any domain", and which two mechanisms mitigate it?
  2. What does Certificate Transparency prevent? What does it not prevent?
  3. Why does OCSP provide little real-world security? What replaced it in practice?
  4. Walk through an ACME HTTP-01 issuance.
  5. What does a CAA record do, and who is obligated to honour it?
  6. Name two CAs that were removed from root stores and why.

Further reading

  • Site: crt.sh and certificate.transparency.dev — browse CT logs; read the CT explainer.
  • Site: letsencrypt.org/how-it-works and RFC 8555 (ACME).
  • Book: Bulletproof TLS and PKI, Ristić — the PKI, CT, and revocation chapters are the best treatment anywhere.
  • Article: "How Certificate Transparency Works" (certificate.transparency.dev) and Emily Stark's talks on the CT ecosystem.
  • Post-mortems: the DigiNotar and Symantec distrust sagas — search Mozilla's dev-security-policy archives. Sobering and educational.
  • Tool: certbot, acme.sh, lego, Caddy, and cert-manager (Kubernetes) docs.

Generated from real-life-guide.md · 8 Oct 2026 16:36