ASVS 5.0 V12.2.2 requires that external facing services present certificates issued by a publicly trusted CA. This is a Level 1 requirement. Self signed or private CA certificates belong on internal services, not on anything a customer or browser reaches.
Why it matters
When a public site uses a self signed certificate, users learn to click through warnings. That habit is exactly what a man in the middle attacker needs. API clients are worse: they often disable verification to make the error go away, and nobody turns it back on.
How to implement it
Use an automated public CA so renewal is boring. With certbot and nginx:
certbot --nginx -d example.com -d www.example.com
certbot renew --dry-run
Serve the full chain (leaf plus intermediates), not just the leaf. Put renewal under monitoring and alert when expiry is under 14 days. Keep short lifetimes and automation rather than long lived certificates handled by hand.
How to test it
openssl s_client -connect example.com:443 -servername example.com -verify_return_error < /dev/null
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates -issuer
The verify step must end with "Verify return code: 0 (ok)" using a stock system trust store. Check the issuer is a public CA and that the hostname appears in the SAN list.
Common mistakes
- Missing intermediate certificate, which works in desktop browsers (that cache intermediates) and fails in mobile apps and curl.
- A certificate that covers example.com but not the www or api name.
- Telling clients to use the insecure flag because staging has a private CA.
Quick check
Can a private CA certificate be used on an external facing service?
Not to meet V12.2.2. Public clients do not trust it, so use a publicly trusted CA there.