Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · ACM

ACM.1: Certificates are close to expiry

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub ACM.1 check?

ACM.1 fires for any certificate in ACM whose NotAfter timestamp is within 30 days. It covers both ACM-issued and imported certificates, though the remediation differs: ACM-issued certs auto-renew if their validation records resolve, while imported certs are entirely your responsibility.

Why does ACM.1 matter?

The day a certificate's NotAfter passes, every TLS client — browsers, mobile apps, partner integrations, your own monitoring — rejects the handshake, and the endpoint behind it (ALB, CloudFront, API Gateway, AppSync) is not degraded but down. Auto-renew is silent in both directions: when a DNS CNAME gets deleted or a validation email bounces, you do not hear about it loudly enough, so ACM.1 is the only continuous backstop most teams have.

How do I fix ACM.1?

  1. Run acm list-certificates in every region (certs are regional, and us-east-1 is special-cased for CloudFront) and export DomainName, Type, and NotAfter.
  2. Migrate to ACM-issued certs with DNS validation wherever you control the zone — they are free and auto-renew, with the only failure mode being a deleted CNAME.
  3. For imported certs, own the renewal calendar: a runbook entry at NotAfter minus 30 days, then re-import to the same ARN so attached resources need no change.
  4. Alarm on the DaysToExpiry CloudWatch metric (45 days for imports, 14 for ACM-issued) rather than trusting the ACM email to the account root.

Remediation script · bash

# Alarm on DaysToExpiry per certificate so a stalled renewal pages someone, not the root inbox.
aws cloudwatch put-metric-alarm \
  --alarm-name acm-imported-api-example-com-expiry \
  --namespace AWS/CertificateManager \
  --metric-name DaysToExpiry \
  --dimensions Name=CertificateArn,Value=arn:aws:acm:us-east-1:123456789012:certificate/9f3a2b14 \
  --statistic Minimum --period 86400 --evaluation-periods 1 \
  --threshold 45 --comparison-operator LessThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:pagerduty-platform

# Clear expired leftovers from the IAM store after confirming nothing references them.
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
for name in $(aws iam list-server-certificates \
  --query "ServerCertificateMetadataList[?Expiration<'$NOW'].ServerCertificateName" \
  --output text); do
  # confirm not referenced by any ELB listener or CloudFront distribution first
  aws iam delete-server-certificate --server-certificate-name "$name"
  echo "deleted expired IAM certificate: $name"
done

Full walkthrough (console steps, edge cases and verification) in the lesson Manage and renew TLS certificates.

Is ACM.1 a false positive?

An ACM-issued cert with DNS validation auto-renews and clears the finding once it does — but ACM begins renewal only 60 days out, so a cert flagged at 30 days may be mid-renewal and resolve itself without action. Imported certs never auto-renew, so those findings are always real work.

Part of the learning path Encrypt everything
  • ACM.2 An ACM RSA certificate uses a key shorter than 2048 bits