This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.
Network & Monitoring

SSL Certificate Inspector

Inspect TLS certificate metadata via Certificate Transparency and edge probes - cert expiry, issuer, and chain details

Inspect TLS certificate metadata for a domain. Uses Certificate Transparency logs (crt.sh) for issuer, subject, validity, SAN list, and days-until-expiry, plus an HTTPS HEAD probe for reachability.

Features

  • GET /inspect?domain= - Certificate metadata + reachability
  • CT-based cert data - Issuer, subject, validity window, SANs
  • HTTPS probe - Confirms the domain is reachable over TLS
  • Honest limitations - Documents that full live cert chain inspection is limited in Workers

API Reference

GET /inspect

Inspect certificate metadata for a hostname.

Prop

Type

Example Request

curl "https://your-worker.workers.dev/inspect?domain=cloudflare.com"

Success Response

{
  "domain": "cloudflare.com",
  "reachable": true,
  "tlsVersion": "TLSv1.3",
  "certificate": {
    "issuer": "CN=WE1,O=Google Trust Services,C=US",
    "subject": "CN=cloudflare.com",
    "notBefore": "2025-01-01T00:00:00",
    "notAfter": "2026-01-01T00:00:00",
    "daysUntilExpiry": 180,
    "san": ["cloudflare.com", "*.cloudflare.com"],
    "serialNumber": "03:AB:CD..."
  },
  "source": "certificate-transparency",
  "note": "Certificate metadata comes from Certificate Transparency logs (crt.sh)..."
}

Error Codes

  • 400 - Invalid domain (INVALID_DOMAIN)
  • 502 - Lookup or probe failed (INSPECT_ERROR)

Workers cannot perform arbitrary live TLS certificate handshakes for any domain. This experiment uses CT logs for certificate fields and a HEAD request for reachability. For production cert monitoring, consider dedicated TLS inspection tooling.

Use Cases

  • Check certificate expiry and SAN coverage from the edge
  • Learn CT log lookup patterns for domain security audits
  • Prototype cert monitoring alerts before integrating a full scanner

Limitations

  • Certificate data comes from CT logs, not a live handshake
  • crt.sh availability and freshness affect results
  • tlsVersion on the Worker request reflects the Worker's outbound fetch, not the target's full chain

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/ssl-certificate-inspector.

DependenciesNoneBindingsNonePlatformrequest.cf, Fetch API
import type { CertificateInfo } from "../types/env";import { daysUntil, uniqueSans } from "./domain";type CrtShEntry = {  issuer_name?: string;  common_name?: string;  name_value?: string;  not_before?: string;  not_after?: string;  serial_number?: string;};export async function fetchCertificateFromCt(domain: string): Promise<CertificateInfo | null> {  const url = `https://crt.sh/?q=${encodeURIComponent(domain)}&output=json`;  const response = await fetch(url, {    headers: { "User-Agent": "cloudflare-experiments/ssl-certificate-inspector" },  });  if (!response.ok) {    throw new Error(`Certificate lookup failed with status ${response.status}`);  }  const entries = (await response.json()) as CrtShEntry[];  if (!entries.length) return null;  const latest = entries    .filter((entry) => entry.not_after)    .sort((a, b) => Date.parse(b.not_after ?? "") - Date.parse(a.not_after ?? ""))[0];  if (!latest?.not_after || !latest.not_before) return null;  const san = uniqueSans(    entries      .flatMap((entry) => (entry.name_value ?? "").split("\n"))      .filter((name) => name.includes(domain) || name.startsWith("*."))  );  return {    issuer: latest.issuer_name ?? "unknown",    subject: latest.common_name ?? domain,    notBefore: latest.not_before,    notAfter: latest.not_after,    daysUntilExpiry: daysUntil(latest.not_after),    san: san.length ? san.slice(0, 50) : [domain],    serialNumber: latest.serial_number,  };}export async function probeHttps(  domain: string): Promise<{ reachable: boolean; tlsVersion?: string }> {  try {    const response = await fetch(`https://${domain}`, {      method: "HEAD",      redirect: "follow",    });    const tlsVersion = (response as unknown as { cf?: { tlsVersion?: string } }).cf?.tlsVersion;    return { reachable: response.ok || response.status < 500, tlsVersion };  } catch {    return { reachable: false };  }}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Test your deployment

curl "https://your-worker.workers.dev/inspect?domain=cloudflare.com"

Local Development

cd apps/experiments/ssl-certificate-inspector
npm install
npm run dev
curl "http://localhost:8787/inspect?domain=example.com"

Cloudflare Features Used

  • Workers - Edge compute and outbound fetch
  • Fetch API - HTTPS reachability probe

On this page