Description

This rule verifies that the TLS/SSL certificates stored in your DigitalOcean account — those bound to Load Balancers and other certificate-consuming resources — are monitored for upcoming expiration, and it flags any certificate whose expiration date (the not_after field) is seven days or fewer from now.

DigitalOcean tracks each certificate's not_after timestamp and its type (lets_encrypt for platform-managed certificates or custom for certificates you upload). The rule reads not_after for every certificate and compares it to the current date, raising a finding when the remaining validity is at or below the seven-day threshold. Custom certificates are of particular concern because DigitalOcean does not renew them for you.

Remediation is to renew or replace any flagged certificate immediately, rely on Let's Encrypt managed certificates where possible so renewal is automatic, and set proactive alerting at a longer lead time (for example thirty days) so renewals never reach the seven-day window.

  • Certificates with not_after seven days or fewer from the current date.

  • Custom (uploaded) certificates approaching expiry that require manual renewal.

  • Let's Encrypt managed certificates in an error state whose automatic renewal has not completed.

Rationale

An expired certificate causes TLS handshakes to fail or browsers to present a security warning, which takes the fronted service offline for users and erodes trust the moment the certificate lapses. Because certificate expiry is a hard deadline rather than a gradual degradation, monitoring the remaining validity and acting well before the date is the only reliable defense. A seven-day threshold is a last-line alert that demands immediate action.

DigitalOcean automatically renews Let's Encrypt managed certificates, but that renewal can still fail — for example if the domain's DNS is no longer managed by DigitalOcean — and custom certificates are never renewed automatically. Explicit expiry monitoring catches both cases before an outage occurs.

  • Prevents outages and browser security warnings caused by lapsed certificates.

  • Catches failed Let's Encrypt auto-renewals that would otherwise go unnoticed.

  • Custom certificates have no automatic renewal, so monitoring is the only safeguard.

Impact

Pros:

  • Expiring certificates are surfaced while there is still time to renew.

  • Avoids service disruption and loss of user trust from an expired certificate.

  • Encourages moving to managed, auto-renewing certificates where feasible.

Cons:

  • Requires a process (or automation) to act on the alerts, not just receive them.

  • Custom certificate renewal involves obtaining and uploading a new certificate and rebinding it.

  • A seven-day window leaves little margin; longer-lead alerting should complement it.

Default Value

DigitalOcean automatically renews Let's Encrypt managed certificates on your behalf (roughly every 60 days), but custom uploaded certificates are never auto-renewed and there is no built-in expiry alert, so tracking not_after is the operator's responsibility.

Pre-Requisite

  • A DigitalOcean account role that can view certificates (Account Security / Certificates).

  • doctl authenticated with a DigitalOcean API token (or $DIGITALOCEAN_TOKEN exported).

  • For custom certificates: access to the certificate authority or issuer to obtain a renewed certificate and private key.

Remediation

Test Plan

Using the DigitalOcean Control Panel:

  1. Sign in to cloud.digitalocean.com.

  2. Open Settings, then the Security tab, and locate the Certificates section (certificates are also listed when editing a Load Balancer's HTTPS rule).

  3. Review each certificate's expiration date and type (Let's Encrypt or Custom).

  4. Identify any certificate whose expiration is seven days or fewer from today, and any Let's Encrypt certificate showing an error state.

  5. Pass: No certificate expires within seven days, and all managed certificates are in a verified state.

  6. Fail: One or more certificates expire within seven days, or a managed certificate's renewal is in an error state.

Using doctl or the API:

List certificates and compare each not_after date against the seven-day threshold.

doctl compute certificate list --format ID,Name,Type,State,NotAfter
curl -s -X GET "https://api.digitalocean.com/v2/certificates" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" | jq -r '.certificates[] | [.name, .type, .state, .not_after] | @tsv'
curl -s -X GET "https://api.digitalocean.com/v2/certificates" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" | jq --arg cutoff "$(date -u -d '+7 days' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v+7d +%Y-%m-%dT%H:%M:%SZ)" '.certificates[] | select(.not_after <= $cutoff) | {name, type, not_after}'

Pass: no certificate has a not_after value at or before seven days from now. Fail: at least one certificate's not_after is within (or already past) the seven-day window, or a lets_encrypt certificate is in an error state.

Implementation Steps

Using the DigitalOcean Control Panel:

  1. For a Let's Encrypt certificate in error, verify the domain's DNS is still managed by DigitalOcean, then delete and recreate the managed certificate so renewal can complete.

  2. For a custom certificate, obtain a renewed certificate and private key from your issuer.

  3. In Settings, then Security, then Certificates, add the renewed custom certificate (or add a new Let's Encrypt certificate).

  4. Update each Load Balancer's HTTPS forwarding rule to use the renewed certificate.

  5. Set a calendar reminder or monitoring alert at a 30-day lead time so future renewals never reach the seven-day window.

  6. Confirm the service serves the new certificate and remove the expired one once nothing references it.

Using doctl or the API:

Certificates cannot be renewed in place; create a new certificate and rebind it, then delete the old one.

doctl compute certificate create --name my-cert-renewed --type lets_encrypt --dns-names example.com
doctl compute certificate create --name my-cert-renewed --type custom --leaf-certificate-path cert.pem --private-key-path key.pem --certificate-chain-path chain.pem
doctl compute load-balancer update <load-balancer-id> --forwarding-rules "entry_protocol:https,entry_port:443,target_protocol:http,target_port:80,certificate_id:<new-certificate-id>"
doctl compute certificate delete <old-certificate-id>

Backout Plan:

  1. Before deleting the old certificate, confirm no load balancer or other resource still references its certificate_id.

  2. If the renewed certificate causes handshake errors, rebind the load balancer's forwarding rule to the previous certificate_id (as long as it has not yet expired).

  3. Keep the previous certificate in the account until the replacement is verified in production.

  4. Re-test the TLS endpoint after any rebinding.

References:

  1. DigitalOcean Certificates API reference (not_after, type, state)

  2. How to Manage SSL Certificates on DigitalOcean

  3. doctl compute certificate