<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-certificate-lifecycle-management
description: >-
  Manage the full certificate lifecycle including generation, renewal,
  rotation, revocation, and automated monitoring. Covers Let's Encrypt, ACME
  protocol, internal CA operations, and certificate inventory tracking for
  compliance and operational continuity.
domain: cybersecurity
subdomain: cryptography
tags:
  - certificates
  - pki
  - acme
  - lets-encrypt
  - certificate-rotation
  - x509
  - lifecycle
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1588.004"]
---

# Implementing Certificate Lifecycle Management

## Overview

Certificate lifecycle management (CLM) ensures every X.509 certificate in an
organization is tracked from issuance through expiration or revocation.
Unmanaged certificates cause outages (expired certs) and security incidents
(compromised keys left active). This skill covers automated issuance, renewal,
rotation, revocation, and inventory auditing.

## Prerequisites

| Requirement | Install |
|---|---|
| OpenSSL 3.x | `apt install openssl` / `brew install openssl` |
| certbot | `apt install certbot` / `brew install certbot` |
| Python 3.10+ | For agent tooling |
| step-cli | `brew install step` / see smallstep.com |

## Key Concepts

### Certificate Generation

```bash
# Generate a private key and self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
  -days 365 -nodes -subj "/CN=internal.example.com"

# Generate a CSR for CA signing
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
  -keyout server.key -out server.csr -nodes \
  -subj "/CN=api.example.com" \
  -addext "subjectAltName=DNS:api.example.com,DNS:api-int.example.com"

# Inspect a CSR before submission
openssl req -in server.csr -noout -text -verify
```

### Automated Renewal with ACME

```bash
# Issue certificate via Let's Encrypt
certbot certonly --standalone -d example.com --agree-tos -m ops@example.com

# Renew all certificates nearing expiration
certbot renew --deploy-hook "systemctl reload nginx"

# Test renewal without issuing
certbot renew --dry-run

# Check certificate expiry dates across inventory
for cert in /etc/letsencrypt/live/*/cert.pem; do
  domain=$(openssl x509 -in "$cert" -noout -subject | sed 's/.*CN = //')
  expiry=$(openssl x509 -in "$cert" -noout -enddate | cut -d= -f2)
  echo "$domain: $expiry"
done
```

### Key Rotation

```bash
# Generate new key pair for rotation
openssl ecparam -genkey -name P-256 -out new-key.pem

# Create CSR with the new key
openssl req -new -key new-key.pem -out rotation.csr \
  -subj "/CN=api.example.com"

# Verify the new certificate matches the new key
openssl x509 -in new-cert.pem -noout -modulus | openssl md5
openssl rsa -in new-key.pem -noout -modulus | openssl md5
```

### Certificate Revocation

```bash
# Revoke a certificate using the CA key
openssl ca -revoke compromised-cert.pem -keyfile ca-key.pem -cert ca-cert.pem

# Generate updated CRL
openssl ca -gencrl -keyfile ca-key.pem -cert ca-cert.pem -out updated.crl

# Revoke via certbot (Let's Encrypt)
certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem

# Verify revocation via OCSP
openssl ocsp -issuer issuer.pem -cert revoked.pem \
  -url http://ocsp.example.com -resp_text
```

### Inventory Auditing

```bash
# Scan all PEM files in a directory for expiry
find /etc/ssl/certs -name '*.pem' -exec openssl x509 -in {} -noout \
  -subject -enddate \; 2>/dev/null | paste - -

# Check remote certificate details
echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -subject -issuer -dates -serial

# Export certificate inventory to JSON via nmap
nmap --script ssl-cert -p 443 -oX cert-scan.xml 10.0.0.0/24
```

## Common Failures

| Failure | Cause | Fix |
|---|---|---|
| Certificate expired in production | No automated renewal | Deploy certbot with cron or systemd timer |
| Key-certificate mismatch | New cert issued against old CSR | Always generate fresh CSR with new key |
| Revocation not propagated | CRL not regenerated / OCSP stale | Automate CRL generation; verify OCSP freshness |
| Wildcard cert scope creep | Single wildcard across trust boundaries | Use SAN certs scoped to specific services |

## Workflow

1. **Inventory** — Discover all certificates across infrastructure
2. **Assess** — Check expiry dates, key sizes, algorithms, and issuers
3. **Automate** — Deploy ACME clients for public certs, step-ca for internal
4. **Monitor** — Continuous expiry and revocation monitoring
5. **Rotate** — Scheduled key rotation with zero-downtime deployment
6. **Audit** — Verify compliance with organizational policy and standards

## Verification

| Check | Method |
|---|---|
| All certs tracked | Certificate inventory covers 100% of endpoints |
| No expired certs | `openssl x509 -checkend` returns 0 for all certs |
| Renewal automated | Certbot or ACME client active with deploy hooks |
| Revocation working | OCSP/CRL checks return valid status |
| Key rotation policy | Keys rotated per organizational schedule |

## References

- [RFC 8555 — ACME Protocol](https://datatracker.ietf.org/doc/html/rfc8555)
- [NIST SP 800-57 — Key Management](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final)
- [Let's Encrypt Documentation](https://letsencrypt.org/docs/)
- [Smallstep step-ca](https://smallstep.com/docs/step-ca/)
