Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 7 min read

Certificate Transparency Monitoring: Catching Unexpected Certificates for Your Domains

Someone can mint a publicly trusted certificate for your domain without ever touching your servers. Mis-issuance, a shadow IT ACME client, a forgotten staging hostname, or an attacker who briefly controlled DNSβ€”all of th

Certificate Transparency Monitoring: Catching Unexpected Certificates for Your Domains

Someone can mint a publicly trusted certificate for your domain without ever touching your servers. Mis-issuance, a shadow IT ACME client, a forgotten staging hostname, or an attacker who briefly controlled DNSβ€”all of them show up in Certificate Transparency logs if you are looking. Most teams only discover the surprise cert when a browser warning, a customer email, or a bug bounty report arrives. CT monitoring turns that into a same-day alert instead of a postmortem slide.

I wrote this with help from AI tools and checked every command and claim myself against current CT tooling. I build PixelValut, a set of free browser-based developer and network tools, and this is Part 4 of Web PKI & Certificate Forensics in Practice. Part 1 covered leaked private keys and safe rotation. Part 2 taught reading X.509 by hand. Part 3 covered revocation realities in 2026. Here we watch the public ledger of issuance.

πŸ“š Series Roadmap β€” Web PKI & Certificate Forensics in Practice

Related: Subdomain Takeover & Dangling DNS Reconnaissance

How do you monitor Certificate Transparency for unexpected certs?

Direct answer: Subscribe to CT alerts for your registered domains (and critical subdomains), baseline the CAs and ACME accounts you expect, and treat every new precertificate as an incident until proven routine. Query public CT search APIs regularly, page on unknown issuers or SANs, then rotate and revoke using the playbooks from Parts 1 and 3 when the issuance was not yours.

Printed SSL certificate document and metal padlock on a dark keyboard, AI-generated

What Certificate Transparency actually gives you

CT is an append-only log ecosystem. Public CAs submit precertificates so browsers can require proof of logging. For operators, the useful property is discoverability: if a trusted CA issued a leaf covering *.example.com or api.example.com, that issuance is searchable.

Source of surprise cert Typical signal in CT First response
Attacker with brief DNS control New leaf from unexpected CA / ACME Assume key may exist; replace + revoke
Shadow IT / forgotten staging Hostname you do not run in prod Inventory owner; tighten ACME DNS access
CDN or SaaS onboarding Expected partner CA, new SAN set Confirm ticket; add to allowlist
CA mis-issuance Domain you own, CA you never used Escalate to CA + browser programs as needed
Wildcard you forgot existed *.example.com still valid Schedule replacement; shrink scope

CT does not stop issuance. It tells you issuance happened. Pair it with DNS lock-down (CAAβ€”more below), short-lived certs from Part 3, and key-compromise response from Part 1.

Baseline before you alert

Noise kills CT programs. Spend one afternoon building an allowlist:

EXPECTED
- Domains: example.com, *.example.com, api.example.com, staging.example.com
- CAs: Let's Encrypt R3/E1 (or your current intermediates), your paid EV/OV CA if any
- Issuance pattern: ACME from CI account X, renewals every 60 days
- Known partners: CDN-managed certs for www (ticket #…)

UNEXPECTED (page immediately)
- Any other CA
- SANs outside inventory
- Wildcard you thought you retired
- Same hostname from two CAs in the same week without a migration ticket

Querying CT in practice (crt.sh and friends)

The classic public search interface is crt.sh. Examples you can run today:

# Recent certificates mentioning your domain (HTML/JSON endpoints exist)
curl -sS "https://crt.sh/?q=%25.example.com&output=json" \
  | jq -r '.[].name_value' | sort -u | head

# Narrow by identity string
curl -sS "https://crt.sh/?q=api.example.com&output=json" \
  | jq -r '.[] | [.not_before,.issuer_name,.name_value] | @tsv' \
  | sort | tail -n 20

For automation, prefer authenticated CT monitoring products or your own log followers if you operate at scale; crt.sh is excellent for investigation and light polling, not as a sole production pager. When you pull a serial, inspect the leaf the same way as Part 2:

# After downloading a PEM from CT / CA
openssl x509 -in surprise.pem -noout -subject -issuer -dates -ext subjectAltName

While you triage, an SSL checker shows what your edges currently serve; a DNS lookup confirms whether the surprise hostname still resolvesβ€”and to whom. I build PixelValut; use those views as a second opinion beside OpenSSL and CT search, not as the only control.

CAA records: reduce issuance, still monitor CT

CAA tells CAs which issuers are allowed. It cuts accidental and some malicious issuance paths. It does not replace CT monitoringβ€”CAs can fail open on lookup errors, and historical leaves remain in logs.

# Check CAA
dig example.com CAA +short
# Example allow-only Let's Encrypt:
# example.com. CAA 0 issue "letsencrypt.org"
# example.com. CAA 0 issuewild "letsencrypt.org"

Operational rule: set CAA deliberately, monitor CT anyway, and alert when a logged cert's issuer is outside your CAA intent (that combination is a serious smell).

A minimal monitoring loop you can ship this week

  1. Inventory every public hostname that should ever get a cert (include wildcards).
  2. Subscribe to CT alerts (email/Slack/webhook) for those namesβ€”commercial monitors or self-hosted log watchers.
  3. Deduplicate by fingerprint/serial so renewals from the expected ACME account do not wake humans at 3 AM.
  4. Enrich alerts with issuer, SANs, notBefore, and whether the name resolves.
  5. Triage within your Sev definitions: unknown CA = high; expected CA + unknown SAN = medium; known renewal = auto-close.
  6. Respond with Part 1 rotation if private key exposure is plausible; Part 3 revoke after replacement.
  7. Feed lessons into ACME hardening (Part 5)β€”DNS-01 credentials are frequent root causes.
# Sketch: poll crt.sh JSON and diff against an allowlist file
# (production: use authenticated APIs, retries, and a real datastore)
import json, urllib.request

def names_for(domain: str) -> set[str]:
    url = f"https://crt.sh/?q=%25.{domain}&output=json"
    data = json.load(urllib.request.urlopen(url, timeout=60))
    out: set[str] = set()
    for row in data:
        for part in row.get("name_value", "").split("\n"):
            out.add(part.strip().lower())
    return out

allow = {"example.com", "www.example.com", "api.example.com"}
found = names_for("example.com")
print("unexpected:", sorted(found - allow))

Treat that sketch as a spike. Rate limits, pagination, and false positives from internal test domains will force a real pipeline quickly.

Correlating CT hits with live edges

A CT hit means a cert was logged. It does not mean every CDN POP serves it.

# What does the world see on 443 right now?
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
  | openssl x509 -noout -serial -issuer -dates -ext subjectAltName

Compare serials. During migrations you may legitimately see two CAs. Document the window. Outside a migration, dual issuance is either CDN complexity or an incident.

Privacy and ethics note

CT logs are public by design. Do not use monitoring access to harass unrelated domains. Scope alerts to names you own or are contracted to protect. Precertificates can reveal internal hostnames earlyβ€”assume attackers read the same logs.

Diagnostic checklist

  1. Do you have an inventory of every public hostname (and wildcards) that may receive a cert?
  2. Are CT alerts wired to a human-pageable channel with quiet hours + severity rules?
  3. Is there an allowlist of expected CAs and ACME identities?
  4. Do renewals auto-suppress so only novel issuances alert?
  5. Is CAA published and aligned with that allowlist?
  6. Can you pull SAN + issuer + serial from an alert within five minutes?
  7. Does triage include DNS resolution and live openssl s_client on each edge?
  8. Is the Part 1 key-compromise playbook linked from the CT runbook?
  9. Is the Part 3 revoke-after-replace sequence linked and rehearsed?
  10. Are shadow subdomains from CT feeding your takeover / dangling DNS review?

FAQ

Does CT monitoring replace CAA?

No. CAA reduces who may issue; CT tells you who did. Run both.

Will Let's Encrypt renewals flood my pager?

They will if you alert on every precertificate. Deduplicate by expected issuer + hostname pattern + timing window.

Are private / internal CA certs in CT?

Generally noβ€”CT focuses on publicly trusted logs. Internal mTLS (Part 6) needs separate inventory and monitoring.

What if crt.sh is down?

Have a second source (another CT search, a commercial monitor, or your own log follower). Incidents do not wait on one website.

Should I revoke every unexpected cert automatically?

Replace first when you control the name, then revoke. Automatic revoke bots without human triage can fight a legitimate migration. Automate detection; keep a human in the destructive loop until the playbook is battle-tested.

How fast should we respond?

Treat unknown-CA issuance like credential exposure: same-day investigation at minimum, faster if the hostname is auth-sensitive. Short-lived certs shrink the window but do not excuse slow triage.

Next in this series, Part 5 covers ACME automation failuresβ€”renewal outages, rate limits and DNS-01 pitfalls that often explain the "surprise" certs CT just showed you.

Follow & Connect

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.