Certificate Transparency: A Practical Guide to Proactive Monitoring

Certificate Transparency (CT) is no longer a niche security feature; it's a fundamental, non-negotiable component of the web's trust infrastructure. For years, we relied on headers like to signal our...

Tim Henrich
October 31, 2025
8 min read
19 views

Certificate Transparency: A Practical Guide to Proactive Monitoring

Certificate Transparency (CT) is no longer a niche security feature; it's a fundamental, non-negotiable component of the web's trust infrastructure. For years, we relied on headers like Expect-CT to signal our commitment to this ecosystem. But the web has evolved. Browsers like Google Chrome now enforce CT compliance by default, rendering that header obsolete.

This shift marks a critical turning point for DevOps, security, and IT teams. The responsibility has moved from opting into enforcement to proactively consuming the data. Certificate Transparency logs are a public firehose of every TLS certificate issued by trusted Certificate Authorities (CAs). Hidden within that stream is invaluable security intelligence: mis-issued certificates, internal hostnames being accidentally exposed, and phishing attempts against your brand.

If you aren't monitoring these logs, you are effectively blind to a critical part of your organization's public attack surface. This guide will walk you through the technical details of how CT works today, why proactive monitoring is essential, and how you can implement a robust strategy to turn this stream of data into actionable security alerts.

How Certificate Transparency Works in 2024

The modern CT ecosystem is governed by RFC 9162, which standardized and improved upon the original framework. While the core goal remains the same—making all issued certificates publicly auditable—the mechanics are important for any technical professional to understand.

Here’s the step-by-step process when you request a certificate from a public CA like Let's Encrypt or DigiCert:

  1. Pre-certificate Creation: The CA first creates a "pre-certificate." This is essentially a complete, valid TLS certificate with one crucial addition: a "poison extension" (OID 1.3.6.1.4.1.11129.2.4.3). This extension ensures that no browser will ever trust the pre-certificate directly, preventing it from being used maliciously if intercepted before logging.
  2. Submission to Logs: The CA submits this pre-certificate to multiple, independent, cryptographically-secured, append-only CT logs. Browser root programs require certificates to be logged in several different logs to ensure redundancy and prevent a single log operator from having too much control.
  3. Receiving the SCT: Each log that accepts the pre-certificate cryptographically signs it and returns a Signed Certificate Timestamp (SCT). An SCT is a simple, verifiable promise from the log operator to incorporate the certificate into their public log within a specific time frame, known as the Maximum Merge Delay (MMD), which is typically 24 hours.
  4. Final Certificate Issuance: The CA gathers the required number of SCTs and issues the final, trusted certificate to you.

The final, crucial step is delivering these SCTs to the user's browser during the TLS handshake. There are three ways to do this:

  • Embedded in the Certificate (Best Practice): The CA embeds the SCTs directly into the final certificate using an X.509v3 extension. This is the most reliable method as it requires no extra configuration on your web server and has no external dependencies during the connection. All major CAs do this by default today.
  • TLS Extension: The SCTs can be delivered in the TLS handshake via the signed_certificate_timestamp extension. This requires server-side configuration and is more complex to manage.
  • OCSP Stapling: The SCTs are attached to the OCSP response that your server "staples" to the TLS handshake. This method also requires server configuration and adds a dependency on your OCSP infrastructure.

When a browser connects to your site, it checks for the presence of valid SCTs. If it doesn't find them, or if they are from untrusted logs, it will display a severe connection error, even if the certificate itself is otherwise valid.

The End of an Era: Why Expect-CT is Deprecated

For years, the Expect-CT HTTP header was a tool for site owners to tell browsers they wanted to enforce CT compliance and receive reports on failures. However, as of 2022, Chrome has deprecated and is removing this header.

This isn't a step backward for security. It's a sign that CT has won.

The web has reached a point where virtually all public CAs are logging all certificates, and all major browsers enforce this requirement. The enforcement aspect of Expect-CT is now redundant. Its reporting function, which was designed to help operators find misconfigurations, was rarely used and created extra noise.

The new paradigm is clear: browsers handle enforcement; you handle monitoring. Your job is no longer to tell browsers to check for SCTs, but to check the CT logs yourself for certificates issued for your domains.

Implementing a Proactive CT Monitoring Strategy

Monitoring CT logs allows you to answer critical questions in real-time:
* Did someone just issue a certificate for dev-api.yourcompany.com without authorization?
* Has a certificate for yourcompany-logins.com just been created for a phishing campaign?
* Did an automated script accidentally request a public certificate for an internal server like pg-primary-lon-01.internal.yourcompany.net?

Here’s how to build a monitoring system to catch these events.

Step 1: Choose Your Monitoring Tools

You can choose between using open-source libraries, free services, or comprehensive commercial platforms.

  • Free Web Services: Tools like crt.sh and Meta's Certificate Transparency Monitoring provide a simple web interface to search for certificates issued for your domains. They are excellent for manual checks and historical analysis. Meta's tool can also send you email notifications.
  • Open-Source Libraries: For automated, real-time monitoring, you can tap directly into the CT log stream. The CertStream project provides libraries for Python, Go, and JavaScript that let you listen to a live feed of all newly issued certificates.
  • Integrated Certificate Management: Comprehensive platforms like Expiring.at incorporate CT monitoring as part of a larger certificate lifecycle management strategy. This allows you to not only detect unauthorized certificates but also track the expiration and health of your entire known certificate inventory in one place.

Step 2: Set Up Real-Time Alerts with Code

Let's build a simple but powerful monitor using the Python certstream library. This script will listen to the global CT firehose and print out any certificate issued for domains related to yourcompany.com.

First, install the library:

pip install certstream

Next, create a Python script named monitor_ct.py:

import certstream
import datetime
import sys

# Define the domain we are monitoring
# Use a broad match to catch subdomains
TARGET_DOMAIN = "yourcompany.com" 

def log_certificate(message, context):
    """
    Callback function to process each certificate update from the CertStream.
    """
    if message['message_type'] == "certificate_update":
        all_domains = message['data']['leaf_cert']['all_domains']

        # Check if any domain in the certificate matches our target domain
        matching_domains = [domain for domain in all_domains if TARGET_DOMAIN in domain]

        if matching_domains:
            # We found a match, now let's print the details
            issuer = message['data']['chain'][0]['subject']['O']
            seen_at = datetime.datetime.fromtimestamp(message['data']['seen']).strftime('%Y-%m-%d %H:%M:%S')

            print(f"[{seen_at}] CERTIFICATE FOUND for {', '.join(matching_domains)}")
            print(f"  -> Issuer: {issuer}")
            print(f"  -> Serial Number: {message['data']['leaf_cert']['serial_number']}")
            print("-" * 30)
            sys.stdout.flush()

print(f"[*] Starting Certificate Transparency monitor for *.{TARGET_DOMAIN}")
print("[*] Waiting for new certificates... (This may take a moment)")

# Connect to the CertStream and register our callback
certstream.listen_for_events(log_certificate, url='wss://certstream.calidog.io/')

Run this script from your terminal:

python monitor_ct.py

The script will connect to the CertStream and immediately begin printing details for any new certificate containing yourcompany.com. This provides instant visibility. You can easily extend this script to send alerts to Slack, PagerDuty, or your SIEM.

Step 3: Tame the Noise with Smart Filtering

For a large organization, the script above will produce a lot of noise. A key part of a successful CT monitoring strategy is filtering out legitimate issuances to focus on anomalies.

Here are some best practices for reducing alert fatigue:

  • Whitelist Approved CAs: Most organizations only use one or two CAs (e.g., Let's Encrypt for public web servers, DigiCert for OV/EV certs). Configure your alerts to ignore certificates from these whitelisted issuers. An alert for a certificate from an unknown CA is a high-priority signal.
  • Whitelist Known Automation: If you use an ACME client like Certbot to automatically renew certificates for www.yourcompany.com and blog.yourcompany.com, add rules to suppress alerts for these specific hostnames when issued by Let's Encrypt.
  • Focus on High-Risk Keywords: Trigger high-priority alerts for certificates containing sensitive keywords like login, vpn, admin, internal, or sso when they are issued for new, previously unseen subdomains.
  • Monitor for Brand Impersonation: Expand your monitoring beyond your own domain. Set up alerts for typosquatted domains (yourconpany.com) or phishing domains (yourcompany-support.com). An attacker getting a valid TLS certificate is often one of the first steps in setting up a convincing phishing site.

Common Pitfalls and How to Avoid Them

As you implement CT monitoring, watch out for these common issues.

Pitfall 1: Leaking Internal Hostnames

A developer might request a publicly trusted certificate for a server like db-prod-backup.internal.yourcompany.com. Because it's logged in public CT logs, this action exposes your internal network architecture to the entire world. Attackers and security researchers constantly mine CT logs for this kind of information.

Solution:
* Policy: Establish a strict policy that public certificates are only for public-facing services.
* Private CAs: For all internal services, use a private CA. Tools like step-ca allow you to run your own internal, ACME-enabled CA, giving your developers the convenience of automation without the risk of public exposure.
* Monitoring: This is a primary use case for CT monitoring. An immediate alert for a certificate issued to a *.internal.* domain allows your security team to revoke the certificate and address the root cause before it's widely discovered.

Pitfall 2: Forgetting Wildcard Certificates

Wildcard

Share This Insight

Related Posts