Multi-Cloud Certificate Management: One Inventory Across AWS, Azure, and GCP
Running in one cloud is hard enough. Running in three means three certificate management models, three consoles, three sets of defaults, and three teams who each assume someone else is watching the certificates the others own.
The comforting story is that each cloud “manages certificates automatically.” The reality is that each cloud manages a slice of its own certificates automatically, and none of them see across the boundary. The certificate that takes down a service is almost always the one that lived in the gap between two clouds, owned by nobody.
This post maps how AWS, Azure, and GCP each handle certificates, where the coverage gaps hide, and how to build a single inventory that spans all three plus your on-premises estate.
AWS ACM Coverage vs. Total Certificate Estate
What ACM manages vs. what a typical enterprise actually needs
5%
Covered by ACM
95%
Needs separate management
Three Clouds, Three Different Models
The first problem is that the three providers do not agree on what “certificate management” even means. What is automated in one is manual in another.
| Capability | AWS | Azure | GCP |
|---|---|---|---|
| Managed public certs | ACM | App Service Managed Certs / Key Vault | Google-managed SSL certs |
| Auto-renewal (managed) | Yes, for ACM-issued on supported services | Partial, varies by service | Yes, for Google-managed |
| Private CA | ACM Private CA | Key Vault + integrations | Certificate Authority Service (CAS) |
| Certificate store | ACM + IAM (legacy) | Key Vault | Certificate Manager |
| Where certs attach | ALB, CloudFront, API Gateway | App Gateway, Front Door, App Service | Load Balancer, ingress |
The consequence of this table is that a team fluent in AWS ACM carries mental defaults that are simply wrong in Azure or GCP. “ACM auto-renews everything” becomes a dangerous assumption when applied to a Key Vault certificate that a human imported and nobody set to renew.
The Coverage Gap Inside a Single Cloud
Before looking across clouds, look inside one. Even within AWS, “managed” covers less than teams assume.
| Certificate Location | Managed by ACM Auto-Renewal? |
|---|---|
| ACM-issued cert on an ALB | Yes |
| ACM-issued cert on CloudFront | Yes |
| Cert imported into ACM from an external CA | No, import does not auto-renew |
| Cert installed directly on an EC2 instance | No, entirely your responsibility |
| Cert inside an EKS pod or ingress | Depends on cert-manager config |
| Cert on a Lambda custom domain | Partially, depends on setup |
The pattern repeats in every cloud. The managed service auto-renews the certificates it issued and controls. Everything else, imported certificates, certificates on compute instances, certificates inside containers, is your problem, and it does not announce itself. A team can run entirely inside AWS and still have a majority of its certificates outside ACM’s auto-renewal.
Discovering Certificates in Each Cloud
Unified inventory starts with pulling from each cloud’s APIs. Here are the queries that surface what each provider knows about.
AWS
# ACM certificates across every region (ACM is regional)
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' -o text); do
echo "=== $region ==="
aws acm list-certificates --region "$region" \
--query 'CertificateSummaryList[].{Domain:DomainName,ARN:CertificateArn,Status:Status}' \
--output table
done
# Legacy IAM server certificates (easy to forget, often expired)
aws iam list-server-certificates --output table
Azure
# Key Vault certificates across every vault
for vault in $(az keyvault list --query '[].name' -o tsv); do
echo "=== Vault: $vault ==="
az keyvault certificate list --vault-name "$vault" \
--query '[].{Name:name,Expires:attributes.expires,Enabled:attributes.enabled}' \
--output table
done
# App Service certificates
az webapp config ssl list \
--query '[].{Name:name,Expiry:expirationDate,Thumbprint:thumbprint}' \
--output table
GCP
# Google-managed and self-managed certs in Certificate Manager
gcloud certificate-manager certificates list \
--format="table(name, managed.domains, expireTime, managed.state)"
# Classic load balancer SSL certificates
gcloud compute ssl-certificates list \
--format="table(name, type, expireTime, managed.domains)"
Running these on a schedule and consolidating the output is the minimum viable multi-cloud inventory. The output is three different shapes of data, which is exactly the normalization problem the next section addresses.
Why Three Consoles Never Becomes One Picture
Even with the discovery scripts above, teams struggle to maintain a single view. The reasons are structural, not a matter of effort.
- No shared identifier. AWS uses ARNs, Azure uses thumbprints and vault URIs, GCP uses resource names. The same logical certificate on
api.example.comappears three different ways with no common key to join on. - Different renewal semantics. “Auto-renew” means different things per provider. A unified view has to normalize renewal state, not just copy a boolean field.
- Split ownership. In most organizations the AWS team, the Azure team, and the GCP team are different people. Each sees their own console and assumes the others are covered.
- The on-prem blind spot. Multi-cloud rarely means cloud-only. AD CS, load balancers, and internal services live on-premises, and none of the cloud consoles show them at all.
The result is the finding we see repeatedly: an organization believes it has good certificate coverage because each cloud team reports their own console looks clean, while the aggregate, the actual full estate, has expired certificates, orphaned imports, and owner-less certs in the seams between platforms.
Building One Inventory Across All Three
A unified inventory needs a normalization layer that ingests each cloud’s data and maps it into a common model. The essential normalized fields:
| Field | Purpose |
|---|---|
| Common name and all SANs | The logical identity, the join key across clouds |
| Serial number / fingerprint | Unique certificate identity for deduplication |
| Source platform | AWS / Azure / GCP / on-prem, and the specific service |
| Issuing CA | Public CA, cloud-managed, or private CA |
| Expiry date | Normalized to a single timezone |
| Renewal method | Managed-auto / ACME / manual / unknown |
| Owner | The human or team accountable, required for every entry |
| Deployment location | Which endpoint actually serves this certificate |
With this model, the same api.example.com certificate appearing in ACM, Key Vault, and a GCP load balancer is deduplicated by SAN and fingerprint, and you can finally answer questions no single console can: how many total certificates do we have, which ones renew automatically, and which ones has nobody claimed.
Validate From the Outside, Too
Cloud APIs tell you what each provider thinks it has. External scanning tells you what is actually being served, which is what your users experience. Run both and reconcile the difference, the gap is where surprises live.
# What is actually served, independent of which cloud owns it
while read host; do
echo | timeout 5 openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null | \
openssl x509 -noout -subject -enddate 2>/dev/null | \
sed "s|^|$host: |"
done < all-endpoints.txt
A Practical Rollout
| Step | Action | Outcome |
|---|---|---|
| 1 | Run per-cloud discovery scripts on a schedule | Raw inventory from each provider |
| 2 | Normalize into a common data model, dedupe by SAN and fingerprint | One unified certificate list |
| 3 | Assign an owner to every certificate | No orphaned certs |
| 4 | Add external scanning to catch served-but-unmanaged certs | Close the API blind spot |
| 5 | Flag every cert whose renewal method is manual or unknown | The automation backlog |
| 6 | Add unified expiry alerting across all sources | One alert stream, not three consoles |
The order matters. Discovery and normalization come first because you cannot assign ownership or alerting to certificates you have not consolidated into one list. The unified expiry alerting in the final step is the payoff: one place that watches every certificate regardless of which cloud it lives in, so no certificate falls through the gap between platforms.
What This Prevents
The multi-cloud certificate outage has a signature. A certificate on a service that spans two clouds, or sits in a cloud the on-call engineer does not usually operate, expires. The console for that cloud showed it, but the engineer was watching a different console. Nobody owned it because it lived in the seam. A unified inventory with per-certificate ownership and one alert stream is specifically the control that closes that seam.
Multi-cloud is not going away, and neither is the certificate sprawl it creates. The teams that stay online are the ones that stopped treating three clouds as three separate certificate problems and started treating them as one inventory with three sources.
FAQ
Q: Does each cloud provider not already handle certificate renewal automatically? Each provider auto-renews the certificates it issued and controls on supported services. It does not renew certificates you imported, certificates installed directly on compute instances, or certificates inside containers. Across three clouds, the un-managed portion is usually larger than teams expect.
Q: Why can I not just use each cloud’s native certificate console? Because no cloud console sees the other clouds, and none see your on-premises estate. Certificate outages in multi-cloud environments almost always involve a certificate in the gap between platforms, owned by nobody, visible in a console the on-call engineer was not watching.
Q: How do I deduplicate the same certificate appearing in multiple clouds? Join on the certificate’s SANs and its serial number or fingerprint. The provider-specific identifiers (AWS ARN, Azure thumbprint, GCP resource name) differ, but the certificate identity itself is consistent, so normalize to that.
Q: Do I need a CLM platform, or can scripts handle multi-cloud? Scripts can build a basic inventory by querying each cloud’s API on a schedule. The hard parts, normalizing three data models, deduplicating, assigning ownership, reconciling against external scans, and unified alerting, are where a CLM platform earns its place once the estate grows beyond a few hundred certificates.
Q: Should on-premises certificates be in the same inventory as cloud certificates? Yes. Multi-cloud almost always coexists with on-premises infrastructure (AD CS, load balancers, internal services). Keeping them in separate inventories recreates the exact blind spot you are trying to eliminate. One inventory should span every source.
About QCecuring
QCecuring gives enterprises a single certificate inventory across AWS, Azure, GCP, and on-premises infrastructure. Our platform connects to each cloud’s certificate APIs, normalizes and deduplicates the results, validates against external scans, assigns ownership to every certificate, and delivers one unified alert stream, so no certificate falls through the gap between clouds.
Unify your multi-cloud certificate inventory
Tags: Multi-Cloud, Certificate Lifecycle Management, CLM, AWS ACM, Azure Key Vault, GCP Certificate Manager, Certificate Discovery, Certificate Sprawl, Hybrid Cloud, Certificate Inventory, Cloud Security, PKI, Certificate Monitoring, Certificate Outage