Certificate Renewal Deployment Gap Gate avatar

Certificate Renewal Deployment Gap Gate

Pricing

from $10.00 / 1,000 run starteds

Go to Apify Store
Certificate Renewal Deployment Gap Gate

Certificate Renewal Deployment Gap Gate

Find the renewal that did not reach every server. For each hostname the Actor resolves every A and AAAA address, opens a TLS handshake to each address with the hostname as SNI, and compares the certificate that each address serves with the newest certific

Pricing

from $10.00 / 1,000 run starteds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Find the renewal that did not reach every server.

Automatic renewal works until it does not. A new certificate is issued, one server in the pool takes it, and one does not. The name still answers, the monitoring still says "days to expiry: 60", and one address out of four keeps serving the old certificate until it expires.

This Actor is not an expiry checker. It answers one question for each hostname: is the certificate that every address serves the newest certificate that the CA issued for this name?

How it works

For each hostname:

  1. It resolves the A and AAAA records over DNS-over-HTTPS, so it sees the whole address pool and not one cached address.
  2. It opens one TLS handshake to each address, with the hostname in the SNI extension, and reads the certificate that this one address serves.
  3. It reads the Certificate Transparency logs for the exact name and takes the newest certificate that is still valid.
  4. It compares the two and gives one verdict.

Verdicts

VerdictMeaning
currentEvery address serves the same certificate, and the CT logs hold nothing newer.
renewed-not-deployedThe CT logs hold a newer certificate than one or more addresses serve. The renewal happened and did not reach every server.
mixed-across-ipsThe addresses behind the name serve different certificates.
renewal-overdueThe certificate is past the renewal point and the CT logs hold no newer certificate. The renewal did not happen.
unreachableThe name did not resolve, every address was refused, or no address completed a handshake.

renewed-not-deployed wins over mixed-across-ips, and mixed-across-ips wins over renewal-overdue. The verdict_reasons field lists every condition that holds, so a hostname that is both mixed and behind CT shows both.

The comparison always uses the oldest certificate that any address serves. One laggard address is the whole failure that this Actor reports.

Certificate Transparency lag

A CT log shows a certificate minutes to hours after the CA issues it. A certificate that a server already serves and the log does not show yet is therefore treated as current, never as renewal-overdue. A difference below 60 seconds does not count as newer. When both CT sources fail, the run reports ct_status: failed, gives no renewed-not-deployed and no renewal-overdue verdict, and still reports mixed-across-ips.

Input

FieldTypeDefaultDescription
hostnamesarray["apify.com", "iana.org"]1 to 300 fully qualified hostnames. Add a port with a colon, for example api.example.com:8443. The default port is 443. An IP address is refused.
max_ips_per_hostnameinteger41 to 8. How many addresses of the name get a handshake.
renewal_point_fractionnumber0.33A certificate is due for renewal when less than this fraction of its lifetime is left.
alert_webhook_urlstringemptyOne public HTTPS URL. One JSON POST goes out when a run finds a gap.
request_timeout_secondsinteger15Timeout for one DNS query, one handshake, one CT query and the POST.
concurrencyinteger4How many hostnames the run checks at the same time.
max_run_secondsinteger240Wall-clock deadline for the list.

Every field has a default, so a run with an empty input works and checks the two demo hosts. The Actor needs no API key and no secret.

It reads three public sources: Cloudflare and Google for DNS-over-HTTPS, crt.sh for the CT history, and Cert Spotter when crt.sh does not answer. Cert Spotter sends no serial number, so a fallback comparison uses the validity dates.

Output

One record for each hostname

FieldDescription
target, hostname, portThe name that this record describes.
verdict, is_gap, verdict_reasonsThe verdict, whether it is billed as a gap, and every condition that holds.
reason_codeOK, DNS_EMPTY, DNS_FAIL, BLOCKED_TARGET, HANDSHAKE_FAIL, RUN_DEADLINE, CHARGE_LIMIT or INVALID_HOSTNAME.
ip_addresses_checked, ip_addresses_reachableThe addresses behind the name, and the ones that answered.
certificatesOne entry for each address: ip_address, fingerprint_sha256, serial_number, not_before, not_after, issuer, san_names, name_match, handshake_ms, error.
renewal_gap_ip_addressesThe addresses that serve a certificate older than the newest one in CT.
deployed_fingerprints, distinct_certificatesThe SHA-256 fingerprints in the pool. More than one means mixed-across-ips.
oldest_deployed_*The fingerprint, serial, dates and issuer of the laggard certificate.
remaining_lifetime_fraction, days_to_expiry, renewal_dueWhere the laggard certificate stands against the renewal point.
ct_status, ct_source, ct_entries_matchedWhether the CT lookup worked, and which source answered.
ct_serial_number, ct_not_before, ct_not_after, ct_issuerThe newest valid certificate for the exact name in the CT logs.

One summary record

gate_pass, hostnames_in_input, hostnames_checked, renewal_gaps, verdict_counts, gap_hostnames, unreachable_hostnames and alert_status.

gate_pass is true only when every hostname has the current verdict. A gap and an unreachable host both turn it off.

A failed gate, an unreachable host and an input mistake are results, not failures. The run always ends succeeded, and the verdict is in the dataset and in the run status message. Wire gate_pass into your pipeline.

Pricing: pay per event

EventPriceWhen the Actor charges it
run-startedUSD 0.01Once for each run, before the first query.
hostname-checkedUSD 0.004Once for each hostname that the run resolved, handshaked and compared with the CT logs. An unreachable hostname is charged here, because the work was done. A hostname that the input got wrong, and one that the run deadline or the charge limit cut off, are not charged.
renewal-gap-flaggedUSD 0.02Once for each hostname with a renewed-not-deployed, mixed-across-ips or renewal-overdue verdict. An unreachable hostname is never a gap.

The default maximum total charge is USD 3 for each run. When a run reaches that limit it checks fewer hostnames; a hostname that it did not check gets the CHARGE_LIMIT reason code, and a gap that the limit did not cover is counted in gaps_not_charged and still reported.

Schedule it

Run it on a daily Apify schedule. Automatic renewal runs on a cycle and each cycle can miss one server. From 2026 the CA/Browser Forum cuts the maximum certificate lifetime in steps, so there are more renewal cycles each year and more chances for one of them to go half way.

Limits

  • 1 to 300 hostnames for each run, and 1 to 8 addresses for each hostname.
  • At most 64 KB from one DNS answer and 8 MB from one CT answer.
  • The run stops at the max_run_seconds deadline.
  • Loopback, private, link-local and reserved addresses are never contacted, in the hostname list, in the DNS answers and in the webhook URL.
  • Plain HTTPS and plain TLS. No browser, no proxy, no key, no stored state.