Skip to content

Certificate Rotation

Plan and execute certificate lifecycle management using CBOM Generator.


Prerequisites

  • CBOM Generator installed
  • Access to certificate authority or ACME provider
  • Root access for certificate deployment

Step 1: Identify Expiring Certificates

Run CBOM scan:

./build/cbom-generator \
    --format cyclonedx --cyclonedx-spec 1.7 \
    --no-personal-data \
    --output cert-inventory.json /etc/ssl /etc/pki

Find Certificates Expiring Soon

# Certificates expiring within 30 days
EXPIRE_DATE=$(date -d "+30 days" --iso-8601)
cat cert-inventory.json | jq --arg exp "$EXPIRE_DATE" '.components[] |
    select(.cryptoProperties?.certificateProperties?.notValidAfter < $exp) |
    select(.cryptoProperties?.certificateProperties != null) |
    {name, expires: .cryptoProperties.certificateProperties.notValidAfter,
     location: .evidence.occurrences[0].location}'

Find Already Expired Certificates

cat cert-inventory.json | jq '.components[] |
    select(.cryptoProperties?.certificateProperties?.certificateState[0]?.state == "deactivated") |
    {name, state: "EXPIRED", location: .evidence.occurrences[0].location}'

Step 2: Plan Rotation Schedule

Priority Matrix

Expiration Priority Action
< 7 days Critical Immediate rotation
7-30 days High Schedule this week
30-90 days Medium Schedule this month
> 90 days Low Plan future rotation

Export Rotation Candidates

cat cert-inventory.json | jq -r '.components[] |
    select(.cryptoProperties?.certificateProperties != null) |
    "\(.name),\(.cryptoProperties.certificateProperties.notValidAfter),\(.evidence.occurrences[0].location)"' \
    | sort -t',' -k2 > rotation-schedule.csv

Step 3: Generate New Certificates

Option A: Self-Signed (Development)

# Generate new private key
openssl genrsa -out new-server.key 2048

# Generate CSR
openssl req -new -key new-server.key -out new-server.csr \
    -subj "/CN=server.example.com"

# Self-sign (for testing)
openssl x509 -req -days 365 -in new-server.csr \
    -signkey new-server.key -out new-server.crt

Option B: ACME/Let's Encrypt

# Using certbot
sudo certbot certonly --webroot -w /var/www/html \
    -d server.example.com \
    --cert-name server

Option C: Enterprise CA

Follow your organization's certificate request process.


Step 4: Deploy New Certificates

Backup Existing Certificates

BACKUP_DIR="/etc/ssl/backup-$(date +%Y%m%d)"
sudo mkdir -p $BACKUP_DIR
sudo cp /etc/ssl/certs/server.crt $BACKUP_DIR/
sudo cp /etc/ssl/private/server.key $BACKUP_DIR/

Deploy New Certificates

sudo cp new-server.crt /etc/ssl/certs/server.crt
sudo cp new-server.key /etc/ssl/private/server.key
sudo chmod 600 /etc/ssl/private/server.key

Update Service Configurations (if needed)

Verify certificate paths in service configs:

# Nginx
grep ssl_certificate /etc/nginx/sites-enabled/*

# Apache
grep SSLCertificate /etc/apache2/sites-enabled/*

Step 5: Restart Services

# Test configurations
sudo nginx -t
sudo apachectl configtest

# Restart services
sudo systemctl restart nginx
sudo systemctl restart apache2

Step 6: Verify with CBOM Scan

Re-run inventory:

./build/cbom-generator \
    --format cyclonedx --cyclonedx-spec 1.7 \
    --no-personal-data \
    --output cert-after-rotation.json /etc/ssl /etc/pki

Verify New Certificate Detected

cat cert-after-rotation.json | jq '.components[] |
    select(.name | contains("server.example.com")) |
    {name,
     valid_from: .cryptoProperties.certificateProperties.notValidBefore,
     valid_to: .cryptoProperties.certificateProperties.notValidAfter,
     state: .cryptoProperties.certificateProperties.certificateState[0].state}'

Step 7: Verify External Connectivity

# Test TLS connection
openssl s_client -connect server.example.com:443 -servername server.example.com </dev/null 2>/dev/null | \
    openssl x509 -noout -dates

# Check certificate chain
openssl s_client -connect server.example.com:443 -servername server.example.com </dev/null 2>/dev/null | \
    openssl x509 -noout -text | grep -E "Subject:|Issuer:|Not Before:|Not After:"

Automated Monitoring

Set Up Expiration Alerts

Create a monitoring script:

#!/bin/bash
# cert-monitor.sh

./build/cbom-generator \
    --format cyclonedx --cyclonedx-spec 1.7 \
    --no-personal-data \
    --output /tmp/cert-check.json /etc/ssl /etc/pki 2>/dev/null

EXPIRE_DATE=$(date -d "+30 days" --iso-8601)
EXPIRING=$(cat /tmp/cert-check.json | jq --arg exp "$EXPIRE_DATE" \
    '[.components[] |
     select(.cryptoProperties?.certificateProperties?.notValidAfter < $exp) |
     select(.cryptoProperties?.certificateProperties != null)] | length')

if [ "$EXPIRING" -gt 0 ]; then
    echo "WARNING: $EXPIRING certificates expiring within 30 days"
    exit 1
fi

Schedule with Cron

# Run weekly
0 0 * * 0 /path/to/cert-monitor.sh

Rollback Plan

If issues occur after rotation:

# Restore from backup
sudo cp $BACKUP_DIR/server.crt /etc/ssl/certs/server.crt
sudo cp $BACKUP_DIR/server.key /etc/ssl/private/server.key

# Restart services
sudo systemctl restart nginx
sudo systemctl restart apache2

Success Criteria

  • [ ] All expiring certificates identified
  • [ ] New certificates generated with adequate validity
  • [ ] Certificates deployed to correct locations
  • [ ] Services restarted successfully
  • [ ] CBOM shows new certificates as "active"
  • [ ] External connectivity verified
  • [ ] Monitoring in place for future expirations