SSL/TLS Certificates
SSL/TLS certificates are the mechanism that binds a cryptographic public key to an identity (domain name, organisation, or IP address). They underpin HTTPS, mutual TLS, email signing, and code signing. Despite the name, "SSL" certificates use TLS โ SSL itself is deprecated and must not be used.
How Certificates Work
A certificate contains:
- The subject's public key
- The identity the key belongs to (domain, organisation)
- The issuer (Certificate Authority that signed it)
- A validity period (not before / not after)
- Subject Alternative Names โ the actual list of domains the cert covers
- The CA's digital signature over all of the above
When a client connects, the server presents its certificate. The client:
1. Verifies the CA signature chains to a trusted root in its trust store
2. Confirms the hostname matches a SAN in the certificate
3. Checks the certificate has not expired or been revoked (CRL / OCSP)
4. Uses the public key to complete the TLS handshake (key exchange)
The private key never leaves the server. If it does, the certificate must be revoked immediately.
Validation Levels
Certificate Authorities offer three validation levels. Higher validation requires more identity verification before issuance.
Domain Validation (DV)
The CA verifies only that the applicant controls the domain โ no identity or organisation checks.
Verification methods: DNS TXT record, HTTP file challenge, or email to domain admin contacts.
| Attribute | Value |
|---|---|
| Issuance time | Minutes to hours |
| Organisation name in cert | Not included |
| Cost | Free (Let's Encrypt) to low |
| Trust indicator | Padlock only (no organisation name) |
| Use cases | Internal tools, personal sites, APIs, CI/CD, automated renewal |
DV is appropriate for most technical use cases. The padlock indicates encrypted transport โ it says nothing about who operates the site.
Organisation Validation (OV)
The CA verifies the domain and also validates the legal existence of the organisation (via business registry, phone verification).
| Attribute | Value |
|---|---|
| Issuance time | 1โ3 business days |
| Organisation name in cert | Included in Subject O= field |
| Cost | $50โ$500/year |
| Trust indicator | Organisation details viewable in cert |
| Use cases | Public-facing corporate sites, partner portals, B2B services |
Extended Validation (EV)
Strictest vetting โ CA verifies legal entity, physical address, operational existence, and authorisation of the requester. EV certificates once triggered a green address bar in browsers; this visual indicator was removed in 2019 as it was shown to provide no measurable phishing protection benefit.
| Attribute | Value |
|---|---|
| Issuance time | 1โ5 business days |
| Cost | $150โ$1500/year |
| Trust indicator | Organisation name in cert Subject |
| Use cases | High-trust financial services, government, e-commerce; largely superseded by OV for practical purposes |
Recommendation: DV certificates issued by Let's Encrypt are appropriate for the vast majority of use cases. Reserve OV for externally visible services where your organisation's identity in the certificate adds compliance or contractual value.
Certificate Types by Coverage
Single-Domain (Dedicated) Certificates
Covers exactly one fully qualified domain name (FQDN).
Example: www.example.com
The certificate's SAN list contains one entry. Some issuers include both example.com and www.example.com as a convenience.
When to use:
- High-value, isolated services โ payment processing, authentication endpoints, admin portals. Compromise of one service's private key cannot affect others.
- Compliance requirements โ PCI DSS requires isolated certificates for the cardholder data environment in some interpretations.
- Different certificate policies โ if
api.example.comneeds a short 30-day auto-renewing cert andsecure.example.comneeds an OV cert, they must be separate. - Minimising blast radius โ if a private key is compromised or a certificate needs emergency revocation, only the single service is affected.
Advantages:
| Advantage | Detail |
|---|---|
| Contained scope | Revocation or compromise affects only one service |
| Fine-grained lifecycle | Each cert can have independent renewal, validity period, and CA |
| Easier incident response | Identify exactly which service was affected |
| Matches zero-trust principles | Each service has its own identity |
Disadvantages: Management overhead at scale โ 50 services means 50 certificates to track, renew, and rotate. Mitigated by automation (ACME / Let's Encrypt, cert-manager, Vault PKI).
Wildcard Certificates
Covers one subdomain level beneath a base domain using the * prefix.
Format: *.example.com
Scope: Matches api.example.com, www.example.com, mail.example.com โ but not example.com itself (include this as a separate SAN), and not sub.api.example.com (wildcards do not span multiple subdomain levels).
When to use:
- Large numbers of subdomains on the same service tier โ e.g.,
tenant1.app.example.com,tenant2.app.example.comfor a SaaS platform - Environments where subdomains are created dynamically and can't be enumerated in advance
- Shared load balancers or reverse proxies serving many subdomains with the same termination point
- Development and staging environments โ
*.dev.example.com,*.staging.example.com - Simplified operations โ one certificate, one renewal, deployed to many services
Where wildcards are NOT appropriate:
| Scenario | Why Not |
|---|---|
| High-security / isolated services | Single compromised service exposes the key used by all subdomains |
| PCI DSS cardholder data environment | Auditors typically require dedicated certs for CDE scope |
| Mixed trust tiers on the same second-level domain | Using *.example.com for both admin.example.com and public.example.com violates separation of privilege |
| Services on different servers or teams | The private key must be shared across all servers โ increases exposure |
Wildcard limitations:
- Only covers one level of subdomain:
*.example.comdoes not covera.b.example.com - The apex domain (
example.com) requires explicit inclusion as a SAN - Wildcard SAN certificates (combining wildcard + explicit SANs) are supported but verify with your CA
- Let's Encrypt issues wildcard certs but only via DNS-01 challenge (requires DNS API access for automation)
# Let's Encrypt wildcard via Certbot (DNS-01 challenge)
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.example.com" \
-d "example.com"
Multi-Domain / SAN Certificates
A single certificate with an explicit list of domains in the Subject Alternative Names extension. No wildcards โ every domain is named.
Example SAN list:
DNS: example.com
DNS: www.example.com
DNS: api.example.com
DNS: shop.example.com
DNS: blog.example.com
When to use:
- Fixed, known set of domains that share a trust boundary
- Multiple domains on one server โ
example.comandexample.co.ukboth pointing to the same service - Consolidating certificates on shared infrastructure without wildcard scope
- Maximum flexibility with explicit control over exactly which domains are covered
Choosing the Right Certificate Type
Is the domain count unpredictable or very large?
โโ YES โ Wildcard (*.subdomain.example.com)
โโ NO โโ
Is this a high-security or isolated service (payments, admin, auth)?
โโ YES โ Dedicated single-domain certificate
โโ NO โโ
Are there 2โ100 known domains sharing the same trust tier?
โโ YES โ Multi-domain SAN certificate
โโ NO โ Single-domain certificate
Certificate Lifecycle Management
Certificate expiry is among the most common causes of unplanned service outages. Automate everything.
Automated Renewal (ACME / Let's Encrypt)
Let's Encrypt issues 90-day DV certificates free of charge. The short validity period encourages automation.
# Certbot auto-renewal (runs as a cron/systemd timer)
certbot renew --quiet --deploy-hook "systemctl reload nginx"
# Cert-manager in Kubernetes
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-tls
spec:
secretName: api-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- api.example.com
EOF
Validity Periods
| Certificate Type | Recommended Validity |
|---|---|
| Public HTTPS (Let's Encrypt) | 90 days (automated) |
| Internal PKI โ servers | 1 year |
| Internal PKI โ clients | 1โ2 years |
| Root CA | 10โ20 years |
| Intermediate CA | 5โ10 years |
| Code signing | 1โ3 years |
As of September 2020, publicly trusted certificates have a maximum validity of 398 days. Proposals to further reduce this to 90 days and eventually 47 days are in progress at the CA/Browser Forum.
Monitoring and Alerting
Never rely on developers or operations noticing expiry. Implement automated monitoring:
- Alert at 60 days, 30 days, 14 days, 7 days before expiry
- Alert immediately on certificate mismatch (hostname validation failure)
- Use a certificate inventory tool (cert-manager, Vault, Venafi, or custom scan)
- Monitor with
openssl s_clientor Prometheus blackbox exporter:
# Check expiry of a live certificate
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
| openssl x509 -noout -dates
# Get days remaining
echo | openssl s_client -connect api.example.com:443 2>/dev/null \
| openssl x509 -noout -checkend $((30*86400)) \
&& echo "Valid for >30 days" || echo "EXPIRING WITHIN 30 DAYS"
Private Key Security
The certificate is public โ the private key is the secret. Its compromise requires immediate certificate revocation and reissuance.
Key Generation
# Generate a 3072-bit RSA private key
openssl genrsa -out private.key 3072
# Or an ECDSA key (P-256) โ smaller, faster, equivalently secure
openssl ecparam -name prime256v1 -genkey -noout -out private.key
Key Storage
| Environment | Recommended Storage |
|---|---|
| Web servers (Nginx, Apache) | Filesystem with 600 permissions, owned by service user |
| Kubernetes | Kubernetes Secret (encrypt at rest with KMS) |
| Cloud load balancers | Managed certificate service (AWS ACM, GCP Certificate Manager) |
| High-security / HSM requirement | Hardware Security Module (HSM) or cloud KMS |
| Secrets rotation pipeline | HashiCorp Vault PKI secrets engine |
Rules
- Never commit private keys to source control โ scan repos with tools like
git-secretsor TruffleHog - Never log private keys or include them in support bundles
- Restrict read access โ only the process serving the certificate should read the private key file
- Rotate on personnel change โ if someone with key access leaves, reissue the certificate
- Revoke immediately on suspected compromise โ do not wait for expiry
Revocation
If a certificate's private key is compromised or the certificate was mis-issued, it must be revoked:
CRL (Certificate Revocation List): CA publishes a periodically updated list of revoked serial numbers. Clients download the CRL and check against it.
OCSP (Online Certificate Status Protocol): Client queries the CA's OCSP responder in real time for the status of a specific certificate.
OCSP Stapling: The server fetches and caches the OCSP response and includes it in the TLS handshake โ improves performance and privacy (client does not contact CA directly).
# Enable OCSP stapling in Nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
resolver 8.8.8.8 1.1.1.1 valid=300s;
Common Mistakes
| Mistake | Risk | Correct Approach |
|---|---|---|
| Wildcard on high-trust services | One compromised service exposes all subdomains | Use dedicated certs for auth, payment, admin |
| Single wildcard for all environments | Dev/staging key compromise reaches prod domains | Separate wildcards: *.dev.example.com, *.example.com |
| Manual renewal without monitoring | Service outage on expiry | Automate with ACME; monitor with alerts at 30d/14d/7d |
| Self-signed certs in production | Browser warnings; TLS bypass temptation; no revocation | Use Let's Encrypt (free) or internal PKI |
| Key stored world-readable | Any local process can steal it | chmod 600 private.key; chown service_user private.key |
| SHA-1 signed certificates | Collision attacks; browser rejection | Use SHA-256 signature algorithm |
| Long validity periods | Extended exposure window if key is compromised | Max 1 year; 90 days with automation |
| No certificate inventory | Unknown expiry dates; surprise outages | Maintain inventory; use monitoring tooling |
Internal PKI
For internal services (microservices, internal APIs, mTLS), run your own Certificate Authority rather than using public CAs for non-public names.
Options:
| Tool | Use Case |
|---|---|
| HashiCorp Vault PKI | Dynamic short-lived cert issuance, ACME support, audit logging |
| Microsoft AD CS | On-premises Windows environments, GPO auto-enrolment |
| step-ca (Smallstep) | Modern ACME-compatible CA, easy Kubernetes integration |
| AWS Private CA | Cloud-native, integrates with ACM and EKS |
Short certificate lifetimes (1โ30 days) from an internal CA are achievable with automation and provide strong security guarantees โ a compromised cert expires quickly and revocation complexity is reduced.