Directory Service LDAP Certificate Expiration
Overview
This check validates that LDAPS (Secure LDAP) certificates registered with your AWS Managed Microsoft AD directories have more than 90 days remaining before expiration. LDAPS provides encrypted communication between applications and your directory, protecting sensitive authentication traffic.
Risk
If an LDAPS certificate expires:
- Service disruption: TLS handshakes will fail, breaking directory binds and queries
- Authentication failures: Applications relying on LDAPS will be unable to authenticate users
- Security downgrade: Clients may fall back to unencrypted LDAP, exposing credentials and directory data to interception
- Compliance violations: Many security frameworks require encrypted authentication traffic
Remediation Steps
Prerequisites
- Access to the AWS Console with permissions to manage Directory Service certificates
- A new TLS/SSL certificate from a trusted Certificate Authority (CA) with at least 90 days validity
- The certificate private key (if using PFX/PKCS12 format)
Required IAM permissions
Your IAM user or role needs the following permissions:
ds:RegisterCertificateds:DeregisterCertificateds:ListCertificatesds:DescribeCertificateds:DescribeDirectories
Certificate requirements
Your new certificate must meet these requirements:
- Format: PEM-encoded X.509 certificate (or PFX/PKCS12 for console upload)
- Key size: 2048-bit RSA minimum recommended
- Validity: More than 90 days from current date (ideally 1-2 years)
- Trust chain: Issued by a CA trusted by your client applications
- Subject: Should match your directory domain or use a wildcard
- Key usage: Digital signature, key encipherment
- Extended key usage: Server authentication (1.3.6.1.5.5.7.3.1)
AWS Console Method
- Open the AWS Directory Service console
- In the navigation pane, choose Directories
- Click on the Directory ID of your target directory
- Select the Networking & security tab
- Scroll down to the Secure LDAP section
- Note the current certificate expiration date to confirm it needs replacement
- Click Actions and select Register certificate (or Replace certificate if updating an existing one)
- Upload your new certificate:
- For PEM format: Paste the certificate content or upload the
.pemfile - For PFX format: Upload the
.pfxfile and enter the password
- For PEM format: Paste the certificate content or upload the
- Click Register certificate
- Wait for the certificate status to show Registered
- If replacing an old certificate, select the expired/expiring certificate and choose Deregister
AWS CLI (optional)
List current certificates
First, identify your directory and view existing certificates:
# List your directories
aws ds describe-directories \
--region us-east-1 \
--query "DirectoryDescriptions[*].[DirectoryId,Name,Type]" \
--output table
# List certificates for your directory
aws ds list-certificates \
--directory-id d-1234567890 \
--region us-east-1 \
--output table
Check certificate expiration details
aws ds describe-certificate \
--directory-id d-1234567890 \
--certificate-id c-1234567890 \
--region us-east-1 \
--query "Certificate.[CertificateId,CommonName,ExpiryDateTime,State]" \
--output table
Register a new certificate
aws ds register-certificate \
--directory-id d-1234567890 \
--certificate-data file://new-certificate.pem \
--type ClientLDAPS \
--region us-east-1
Replace:
d-1234567890with your actual directory IDnew-certificate.pemwith the path to your PEM-encoded certificate file
Deregister the old certificate (after new one is active)
aws ds deregister-certificate \
--directory-id d-1234567890 \
--certificate-id c-0987654321 \
--region us-east-1
Replace c-0987654321 with the ID of the expiring certificate.
CloudFormation (optional)
CloudFormation does not currently support direct management of Directory Service LDAPS certificates. You must use the AWS Console or CLI to register certificates.
However, you can use a CloudFormation Custom Resource with a Lambda function to automate certificate registration:
AWSTemplateFormatVersion: '2010-09-09'
Description: Custom resource for Directory Service certificate management
Parameters:
DirectoryId:
Type: String
Description: The ID of the directory (e.g., d-1234567890)
AllowedPattern: ^d-[0-9a-f]{10}$
CertificateSecretArn:
Type: String
Description: ARN of Secrets Manager secret containing the certificate PEM
Resources:
CertificateRegistrationRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: DSCertificateManagement
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ds:RegisterCertificate
- ds:DeregisterCertificate
- ds:ListCertificates
- ds:DescribeCertificate
Resource: '*'
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref CertificateSecretArn
CertificateRegistrationFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.11
Handler: index.handler
Role: !GetAtt CertificateRegistrationRole.Arn
Timeout: 300
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
ds = boto3.client('ds')
sm = boto3.client('secretsmanager')
try:
if event['RequestType'] in ['Create', 'Update']:
# Get certificate from Secrets Manager
secret = sm.get_secret_value(
SecretId=event['ResourceProperties']['CertificateSecretArn']
)
cert_data = secret['SecretString']
# Register certificate
response = ds.register_certificate(
DirectoryId=event['ResourceProperties']['DirectoryId'],
CertificateData=cert_data,
Type='ClientLDAPS'
)
cfnresponse.send(event, context, cfnresponse.SUCCESS,
{'CertificateId': response['CertificateId']},
response['CertificateId'])
elif event['RequestType'] == 'Delete':
# Deregister certificate
ds.deregister_certificate(
DirectoryId=event['ResourceProperties']['DirectoryId'],
CertificateId=event['PhysicalResourceId']
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
LDAPSCertificate:
Type: Custom::DSCertificate
Properties:
ServiceToken: !GetAtt CertificateRegistrationFunction.Arn
DirectoryId: !Ref DirectoryId
CertificateSecretArn: !Ref CertificateSecretArn
Outputs:
CertificateId:
Description: The registered certificate ID
Value: !GetAtt LDAPSCertificate.CertificateId
Note: Store your certificate PEM content in AWS Secrets Manager before deploying this template.
Terraform (optional)
Terraform does not have a native resource for Directory Service LDAPS certificates. You can use the aws_directory_service_region resource for multi-region directories, but certificate management requires a custom approach.
Use the AWS CLI via a null_resource with a local-exec provisioner:
variable "directory_id" {
description = "The ID of the AWS Directory Service directory"
type = string
# Example: d-1234567890
}
variable "certificate_path" {
description = "Path to the PEM-encoded certificate file"
type = string
}
# Store certificate in Secrets Manager for secure handling
resource "aws_secretsmanager_secret" "ldaps_cert" {
name = "directoryservice/${var.directory_id}/ldaps-certificate"
description = "LDAPS certificate for Directory Service"
}
resource "aws_secretsmanager_secret_version" "ldaps_cert" {
secret_id = aws_secretsmanager_secret.ldaps_cert.id
secret_string = file(var.certificate_path)
}
# Register certificate using AWS CLI
resource "null_resource" "register_certificate" {
triggers = {
certificate_version = aws_secretsmanager_secret_version.ldaps_cert.version_id
}
provisioner "local-exec" {
command = <<-EOT
aws ds register-certificate \
--directory-id ${var.directory_id} \
--certificate-data file://${var.certificate_path} \
--type ClientLDAPS \
--region us-east-1
EOT
}
depends_on = [aws_secretsmanager_secret_version.ldaps_cert]
}
output "certificate_secret_arn" {
description = "ARN of the Secrets Manager secret containing the certificate"
value = aws_secretsmanager_secret.ldaps_cert.arn
}
Important: This approach registers a new certificate each time it runs. For production use, implement proper state management to track certificate IDs and handle updates/deregistration.
Verification
After registering the new certificate:
- Return to the Networking & security tab of your directory
- In the Secure LDAP section, confirm the new certificate shows Registered status
- Verify the expiration date is more than 90 days in the future
- Test an LDAPS connection from a client application to confirm functionality
CLI verification commands
List all certificates and their expiration dates:
aws ds list-certificates \
--directory-id d-1234567890 \
--region us-east-1 \
--query "CertificatesInfo[*].[CertificateId,CommonName,ExpiryDateTime,State]" \
--output table
Get detailed information about a specific certificate:
aws ds describe-certificate \
--directory-id d-1234567890 \
--certificate-id c-1234567890 \
--region us-east-1
Verify the certificate has more than 90 days remaining:
# Get expiry date and calculate days remaining
EXPIRY=$(aws ds describe-certificate \
--directory-id d-1234567890 \
--certificate-id c-1234567890 \
--region us-east-1 \
--query "Certificate.ExpiryDateTime" \
--output text)
echo "Certificate expires: $EXPIRY"
Additional Resources
- Enable Secure LDAP - AWS Documentation
- Register a Certificate - AWS Directory Service API
- Directory Service Best Practices
- Certificate Lifecycle Management
Notes
- Plan for overlap: Register the new certificate before deregistering the old one to avoid service interruption.
- Client trust: Ensure client applications trust the CA that issued your new certificate before switching.
- Automation: Set up CloudWatch alarms or AWS Config rules to alert you when certificates approach expiration.
- Certificate storage: Store certificates and private keys securely in AWS Secrets Manager or AWS Certificate Manager Private CA.
- Testing: Test the new certificate with a subset of applications before full rollout.
- Monitoring: After replacement, monitor LDAPS connections for errors that might indicate trust chain issues.
- No downtime required: Certificate registration does not require directory downtime, but applications may need to reconnect.