Back to Blog

Shorter TLS Certificate Lifetimes: Renewal and Monitoring for API Developers

8 min read

By OpenFinanceTools · Updated

A certificate renewal can succeed at the certificate authority while the API still serves the old certificate. As certificate lifetimes shorten, that gap becomes harder to manage manually. Your monitoring needs to observe the certificate clients actually receive, and your renewal process needs a deployment check.

This guide separates the public TLS issuance schedule from your operational alerting policy. It includes a downloadable Node.js probe, its exit-code contract, a local test strategy and a renewal runbook. Use it alongside the SSL Certificate Checker for one-off inspection.

1. Know which certificates the schedule covers

The CA/Browser Forum's TLS Baseline Requirements set these maximum validity periods for publicly trusted TLS subscriber certificates. The relevant date is issuance, not the date a developer first sees the certificate. Existing certificates are not automatically shortened by a later schedule boundary. Source: section 6.3.2.

Issued on or afterIssued beforeMaximum validity
Before March 15, 2026March 15, 2026398 days
March 15, 2026March 15, 2027200 days
March 15, 2027March 15, 2029100 days
March 15, 2029No later boundary in this schedule47 days

These are ceilings, not recommended renewal dates. The requirements also shorten domain/IP validation reuse, reaching 10 days in 2029. That is a separate limit from certificate validity. Do not automatically apply this public-server-certificate schedule to private PKI, mTLS client certificates or electronic sealing certificates; identify the applicable certificate policy first. Source: validation reuse requirements.

For an open banking integration, “the certificate” can mean several different things. The API's server certificate authenticates its hostname. Your client certificate may identify your application. A signing certificate or key serves another purpose again. Each needs an owner and a lifecycle, but they need not share the same issuer or renewal rules.

2. Inventory endpoints, termination points and owners

Start from the connections your application actually makes. Record the API hostname, port, environment and the team responsible for renewal. Then identify where TLS terminates: a load balancer, CDN, gateway, ingress controller or the application itself.

Inventory fieldWhy you need it
Hostname and portA certificate for another hostname may be returned when SNI or routing is wrong.
Environment and ownerAn alert needs a destination and an escalation path.
Certificate purpose and issuerPublic server TLS and client authentication may follow different policies.
Renewal and deployment mechanismIssuance alone does not update the live endpoint.
Served fingerprint and expiryThese help establish whether the new certificate reached the edge.
Probe locationDifferent regions or network paths can reach different infrastructure.

For example, an internal probe may reach the origin while external clients reach a gateway with a different certificate. Both checks can be green independently while one client population is still exposed to expiry. Name probes by the path they observe, and document which routes remain untested.

3. Probe the live TLS connection with Node.js

Download check-tls-expiry.mjs. It uses Node.js built-ins, connects once, verifies the peer, reports the leaf certificate and exits. The guide's local tests use Node.js 22.19.0.

node check-tls-expiry.mjs api.your-domain.example 443 30

Replace the example hostname with an endpoint you operate or are authorized to monitor. The final argument is your warning threshold in days. It is an operational choice, not a CA requirement. Start with a threshold that leaves enough time for approval, issuance, deployment and recovery, then adjust it as your automation improves.

Complete monitoring script
// A one-shot monitoring probe, not a CA policy or revocation validator.
import tls from 'node:tls';
import { isIP } from 'node:net';
import { pathToFileURL } from 'node:url';

export function checkCertificate({ host, port = 443, warningDays = 30, timeoutMs = 5000, ca }) {
  if (!host || !Number.isInteger(port) || port < 1 || port > 65535 ||
      !Number.isFinite(warningDays) || warningDays < 0 ||
      !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
    return Promise.reject(new Error('Invalid host, port, threshold or timeout'));
  }
  return new Promise((resolve, reject) => {
    // TLS verifies the chain and hostname; never disable rejectUnauthorized.
    const socket = tls.connect({
      host, port, servername: isIP(host) ? undefined : host,
      rejectUnauthorized: true, minVersion: 'TLSv1.2', ...(ca ? { ca } : {}),
    });
    const deadline = setTimeout(() => {
      socket.destroy(new Error('TLS probe timed out'));
    }, timeoutMs);
    socket.once('error', error => {
      clearTimeout(deadline);
      reject(error);
    });
    socket.once('secureConnect', () => {
      clearTimeout(deadline);
      const cert = socket.getPeerCertificate();
      const expiresAt = Date.parse(cert.valid_to);
      if (!Number.isFinite(expiresAt)) {
        socket.destroy();
        reject(new Error('Peer certificate has no readable expiry'));
        return;
      }
      const remainingMs = expiresAt - Date.now();
      const result = {
        host, port, expiresAt: new Date(expiresAt).toISOString(),
        daysRemaining: Math.floor(remainingMs / 86400000),
        fingerprint256: cert.fingerprint256,
        status: remainingMs <= warningDays * 86400000 ? 'renew-soon' : 'ok',
      };
      socket.destroy();
      resolve(result);
    });
  });
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  const [host, port = '443', warningDays = '30'] = process.argv.slice(2);
  try {
    const result = await checkCertificate({ host, port: Number(port), warningDays: Number(warningDays) });
    console.log(JSON.stringify(result, null, 2));
    process.exitCode = result.status === 'ok' ? 0 : 1;
  } catch (error) {
    console.error(JSON.stringify({ status: 'failed', message: error.message }));
    process.exitCode = 2;
  }
}

Node's TLS client performs certificate verification and hostname checking. The script sends a DNS hostname as SNI, keeps verification enabled and adds a five-second overall deadline. It does not use an HTTP response to infer whether the handshake was trusted. Source: Node.js TLS documentation.

The output below is illustrative; expiry and fingerprint depend on the server. A real successful result includes the observed SHA-256 fingerprint.

{
  "host": "api.your-domain.example",
  "port": 443,
  "expiresAt": "2026-10-05T12:00:00.000Z",
  "daysRemaining": 20,
  "fingerprint256": "EXAMPLE:REPLACE:WITH:OBSERVED:FINGERPRINT",
  "status": "renew-soon"
}
Exit codeMeaningSuggested response
0Trusted connection; expiry is beyond the thresholdRecord the result and next scheduled check.
1Trusted connection; expiry is within the thresholdOpen or update the renewal task.
2Probe failed, including invalid arguments, network or TLS errorsInvestigate availability, trust or configuration. Do not classify this as healthy.

daysRemaining is rounded down for display. The warning decision uses the remaining milliseconds, so a certificate is not classified solely by a rounded integer. An expired or untrusted certificate normally fails the handshake and produces exit code 2 rather than a reassuring expiry report.

For private PKI, configure an approved trust anchor through your runtime's trust configuration, such as NODE_EXTRA_CA_CERTS. Do not set NODE_TLS_REJECT_UNAUTHORIZED=0. The script is a local operator tool; do not expose it as an unrestricted URL-checking API without additional destination and abuse controls.

4. Test the monitor before relying on it

A green run against one public site is weak evidence. Use a local TLS server with disposable certificates so that failure scenarios are repeatable. Our automated tests exercise a trusted local certificate, the warning threshold, an untrusted chain, an expired certificate, a hostname mismatch and a handshake timeout. They also exercise invalid CLI arguments and the exit-code contract.

The local certificate fixtures are synthetic. Passing those tests establishes the probe's behavior in that environment, not coverage of every certificate authority or deployment topology. A rollout should add checks from the actual networks that matter to your users.

For a PEM file already on disk, OpenSSL provides a useful complementary expiry check:

openssl x509 -in certificate.pem -noout -dates
openssl x509 -in certificate.pem -noout -checkend 2592000

The second command checks whether expiry falls within 30 days. A nonzero exit status needs investigation; do not suppress it in automation. This file check does not prove that the certificate is deployed, that its hostname matches your endpoint or that its chain is trusted. Source: OpenSSL x509 documentation.

5. Build a runbook that ends with the served certificate

  1. Detect and assign. Route a warning to a named owner. Keep a separate signal for probe failures so an unavailable host does not disappear from reporting.
  2. Issue through the approved process. Use your CA's supported automation or internal issuance workflow. Keep credentials in the deployment secret store.
  3. Validate before rollout. Check names, key correspondence, certificate purpose, validity and required chain files. Use synthetic staging traffic where possible.
  4. Deploy to every termination point. Include secondary regions, disaster-recovery endpoints and gateways. Record the expected fingerprint.
  5. Open a new connection and verify. Compare the live probe result with the expected certificate. A reused connection can hide a failed rollout.
  6. Observe and close. Check representative client behavior, clear the warning and retain the evidence needed for the next renewal.

Make rollback a tested operation too. Keep a previous certificate only while it remains valid and appropriate to use; an expired or compromised certificate is not a safe rollback target. Test configuration reloads and permissions without exposing private keys in logs or monitoring output.

For scheduling, run the probe from your existing monitoring platform and preserve all three exit states. Define a brief retry policy for transient network failures, then escalate persistent failures. Track the monitor's own execution: a missed job should not look identical to a healthy certificate.

Renewal timing should reflect recovery time. If an organization takes several days to approve a certificate request and another day to deploy it, an alert one day before expiry is ineffective. Shorter lifetimes make those delays visible; measuring them is more useful than adopting a universal “renew X days early” rule.

What this probe does not tell you

  • It does not perform a complete revocation assessment or qualified-certificate validation.
  • It does not check mTLS client authentication, signing-certificate policy or every intermediate certificate's remaining lifetime.
  • It observes one connection and one endpoint path per run, not every load-balancer node.
  • It does not renew, deploy or automatically repair certificates.

Use the PEM Decoder for readable certificate fields, the CSR Decoder when preparing a request, and the certificate validation guide for the broader trust workflow. Keep those inspection tasks separate from your issuance and deployment controls.

Common questions

Must every certificate become 47 days long now?

No. Check the issuance date and certificate scope against the table. Do not confuse a future public TLS ceiling with today's policy for every certificate you hold.

Can I monitor by IP address?

The script accepts an IP, but a hostname-based service should generally be checked using its hostname. An IP may select a different virtual host and needs a certificate valid for that IP.

Is an expiry check enough for open banking?

No. Certificate purpose, trust, identity, client authentication and the relevant ecosystem requirements still need validation.

Method: AI-assisted drafting with a locally tested Node.js probe and disposable TLS fixtures. The schedule was checked against the CA/Browser Forum requirements on September 15, 2026. Example monitoring output is illustrative, not a measurement of a customer's endpoint.