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?
- 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.
- 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.
- 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.
- Alarm on the DaysToExpiry CloudWatch metric (AWS/CertificateManager namespace, CertificateArn dimension, published twice daily), a single days-remaining integer that reads the same for imported and ACM-issued certs, at a threshold that gives you lead time, 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.
More ACM controls
- ACM.2 An ACM RSA certificate uses a key shorter than 2048 bits