# SSL/TLS certificates auto-renew before expiry; certificate will not expire within 30 days

- **Pattern:** `ab-000982` (`deployment-readiness.rollback-recovery.ssl-auto-renew`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000982
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000982)

## Why it matters

An expired SSL/TLS certificate takes your entire site offline for all users instantly — browsers block access, not just warn. CWE-295 covers improper certificate validation; NIST SC-17 and PCI DSS Req-4.2.1 require maintaining valid certificates. A certificate expiring within 30 days with no auto-renewal is a timed production outage. Manual renewal requires remembering a calendar event and having the right credentials available — both fail under operational stress.

## Severity rationale

Low because most modern platforms (Vercel, Netlify, AWS) handle SSL auto-renewal automatically, so this only affects self-hosted deployments, but expiry causes immediate and total service unavailability.

## Remediation

Enable auto-renewal via Certbot for self-hosted servers. Vercel and Netlify handle this automatically — verify the platform setting if in doubt.

For Nginx with Let's Encrypt:

```bash
# Install Certbot
sudo apt-get install certbot python3-certbot-nginx

# Issue certificate
sudo certbot --nginx -d your-domain.com

# Certbot auto-installs a systemd timer; verify it
sudo systemctl status certbot.timer

# Test renewal without applying
sudo certbot renew --dry-run
```

If you prefer a cron fallback:

```bash
0 3 * * * /usr/bin/certbot renew --quiet --no-eff-email
```

Set a calendar reminder 60 days before expiry as a backstop. Document the renewal owner in `DEPLOYMENT.md`.

## Detection

- **ID:** `ssl-auto-renew`
- **Severity:** `low`
- **What to look for:** Enumerate every relevant item. Look for HTTPS configuration in deployment setup. For cloud platforms (Vercel, Netlify, AWS), check console or config for auto-renewal settings. For self-hosted or dedicated hosting, look for Let's Encrypt integration, certificate auto-renewal, or monitoring. Check certificate expiry date via SSL checker or cURL.
- **Pass criteria:** At least 1 of the following conditions is met. SSL/TLS certificate auto-renewal is enabled. Current certificate will not expire within 30 days.
- **Fail criteria:** Auto-renewal is not enabled, or certificate will expire within 30 days.
- **Skip (N/A) when:** The project is not exposed over HTTPS, or platform automatically manages SSL (most modern platforms do).
- **Detail on fail:** `"Manual SSL certificate renewal required. No auto-renewal configured."` or `"Certificate expires in 15 days without auto-renewal."`
- **Remediation:** Enable auto-renewal. For Vercel/Netlify, this is automatic. For self-hosted with Let's Encrypt:

  ```bash
  # Install Certbot
  sudo apt-get install certbot python3-certbot-nginx

  # Get initial certificate
  sudo certbot certonly --nginx -d your-domain.com

  # Auto-renewal via cron (tests renewal once per day)
  sudo certbot renew --dry-run

  # Add cron job to auto-renew
  0 12 * * * /opt/certbot/bin/certbot renew --quiet --no-eff-email
  ```

## External references

- cwe CWE-295
- nist SC-17
- pci-dss Req-4.2.1

Taxons: cryptography-and-secrets, operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-000982
