TLS certificate

Your browser opens a connection to example.com. How does it know it's really talking to example.com and not a machine pretending to be it?

The server hands over a TLS certificate. The certificate says I am example.com, here is my public key, and a CA you already trust signed this statement. The browser verifies the signature. If it matches, the connection is authenticated and traffic is encrypted with that key.

That is the job of a certificate. The rest of this page shows how it is built.

What it is

A TLS certificate is an X.509 document. The profile for the public web is RFC 5280, plus the CA/Browser Forum Baseline Requirements: the operational rules every public CA must follow. A cert is fundamentally a statement bound by a signature. Unpack it and you get a handful of fields.

Anatomy

Here is what the browser actually reads.

TLS certificateX.509 · RFC 5280
Subject
example.com

the main hostname the cert is for

Subject Alternative Names
example.com, www.example.com

every hostname this cert covers. The one that matters.

Issuer
Let's Encrypt R11

the CA that signed this cert

Valid from
2026-04-01

notBefore: do not accept this cert before this date

Valid until
2026-10-18

notAfter: 200 days, the current Baseline Requirements cap

Public key
ECDSA P-256

the key the browser uses to verify the server

Signature
SHA-256 with ECDSA

how the CA signed the cert

The three fields that matter most for correctness are Subject Alternative Names (which hostnames the cert covers), Valid until (when it stops being accepted), and Issuer (which CA signed it). The rest are cryptographic detail.

The chain

A leaf cert for example.com is not signed directly by a root. It is signed by an intermediate CA, which is signed by the root.

Chain of trust
root
ISRG Root X1
in the browser's trust store
signed by
intermediate
Let's Encrypt R11
your server must send this
signed by
leaf
example.com
your server must send this
on the wireThe server sends the leaf and the intermediate. Not the root. The browser already has the root.
trustThe browser walks the chain upward. Each signature must verify. The top must match a root it already trusts.

Two rules follow. The server must send the intermediate alongside the leaf. Without it, the browser has no way to walk up to a trusted root and will reject the connection. The server must not send the root. The browser already has it; including it just wastes handshake bytes. A common misconfiguration is sending only the leaf; the site works in curl (which is forgiving) and breaks in Firefox (which is not).

SAN matching

The cert declares the hostnames it covers in the Subject Alternative Name extension. The browser checks the hostname it dialled against this list. Exact match, or wildcard match under a specific rule.

SAN matching
the cert's SAN list
example.comwww.example.com*.api.example.com
the browser tests each hostname
example.comexact matchmatch
www.example.comexact matchmatch
EXAMPLE.COMcase-insensitivematch
api.example.comnot in SAN listno match
a.api.example.comwildcard matches one labelmatch
a.b.api.example.comwildcard matches one label onlyno match

The Common Name field used to carry the hostname. It is ignored on the modern web. Only SAN matters. A cert with example.com in CN and a SAN list that forgets www.example.com will fail when users type www. This is the most common cert bug.

Trust stores

A "CA the browser trusts" is a CA in the browser's root store. Four stores dominate the public web.

StoreWho uses itPolicy
MozillaFirefox, many Linux distros, curlRoot Store Policy
AppleSafari, iOS, macOSApple Root Certificate Program
MicrosoftEdge, WindowsTrusted Root Program
GoogleChrome, ChromeOSChrome Root Program

A CA that fails any of these audits gets distrusted. When that happens, every cert it ever issued stops working in that browser. It has happened several times: Symantec, DigiNotar, WoSign. A cert from a distrusted CA is not a bug on your side, but you will need to reissue from a trusted one fast.

Certificate Transparency

Every publicly trusted cert must be logged to two or more Certificate Transparency logs (RFC 6962). The logs are append-only and public. Browsers refuse certs that do not have signed log proofs.

What you get from this: every cert ever issued for your domain is searchable at crt.sh. Rogue issuance by a CA cannot stay hidden. A quarterly check of your own domain on crt.sh is the cheapest security review you can do.

The 47-day story

On 2025-04-11 the CA/Browser Forum approved a phased cut of the maximum certificate lifetime. Each step down makes manual renewal harder. At the end, human renewal is not a plan.

Certificate lifetime scheduleCAB Forum SC081v3
  1. before 2026-03-15398 daysthe old cap
  2. since 2026-03-15200 daysyou are here
  3. 2027-03-15100 dayssecond cut
  4. 2029-03-1547 daysfinal cap
Every step down makes manual renewal more dangerous. At 47 days, a missed renewal is an outage. Automate with ACME.

If your renewal process involves a human remembering to do something, fix it before 2027. Any ACME client (Certbot, lego, acme.sh, Caddy's built-in) turns renewal into a cron job that nobody has to think about.

Common mistakes

expired cert

Browsers refuse the connection. Catch this at 30 days remaining, not 3.

missing intermediate

Server sends only the leaf. Works in curl, fails in Firefox. The server config must include the full chain.

hostname mismatch

Cert covers example.com but not www.example.com, or the other way round. Always list both in SAN.

wildcard used for the apex

*.example.com does not cover example.com. Wildcards match one label, not zero.

manual renewal

A cron-fed ACME client is the minimum. At 47-day caps, anything else is an outage waiting for a vacation.

self-signed in prod

Nothing trusts it. Fine for local dev. Never ship to real users.


Check what your cert actually says: scan your domain. Sudory reads the live cert, walks the chain, matches the hostname, and flags anything under 30 days.