The post-mortem reads the same every time: a TLS certificate expired on a service nobody owned, traffic stopped, three teams swarmed before someone found the renewal SOP from two re-orgs ago. ITOM Visibility ships certificate discovery, but the default ingestion produces so much noise that the expiry dashboard is muted by the second sprint. The fix is to be aggressive about scope and ownership before the first scan.
Decide what counts as in-scope
Internal CA chains, expired self-signed development certs, and ephemeral container certs will swamp the table if you ingest everything reachable. Define scope explicitly: certificates exposed on listening sockets in production network ranges, certificates bound to load balancers under CMDB management, and certificates returned by API endpoints in your service catalog. Everything else goes to a staging table for triage, not the main cert_certificate view.
Use the right discovery surface
Three discovery paths produce different fidelity. Network scans via MID Server pick up listener certs but miss bound-but-not-listening ones. Integrations with cert managers (Venafi, AWS ACM, GCP Certificate Manager, Azure Key Vault) give the system-of-record view. Agent-based discovery on hosts catches local trust stores. You probably want all three with a clear precedence rule — system-of-record wins on conflict.
Precedence: cert manager API > host agent > network scan
Reconciliation key: SHA-256 fingerprint, not subject CN
Ownership at ingestion, not later
The single biggest failure mode is ingesting certificates without resolving them to a CI and an owner group. A row with no assigned_to will be ignored. Build the resolution into the ingestion flow: match certificate to listener, listener to host, host to support group via CMDB relationships. If any step fails, route to an exception queue with a 7-day SLA. Do not let unowned certs sit in the table.
Expiry windows that actually drive behavior
A single 30-day expiry alert produces alert fatigue. Tier the alerts: 60 days creates a change ticket assigned to the owner group, 30 days escalates to the group manager, 14 days pages on-call, 7 days fires a Sev-2 incident. The expiry table should have computed columns for each window so notifications are deterministic.
// Business rule on cert_certificate, before update
var days = gs.dateDiff(gs.nowDateTime(), current.valid_to, true) / 86400;
current.expiry_tier = days <= 7 ? 'critical' :
days <= 14 ? 'high' :
days <= 30 ? 'medium' :
days <= 60 ? 'low' : 'none';
Decommission detection is half the value
Expired certificates from systems that were retired six months ago are pure noise. Flag certificates whose hosting CI is in retired state and auto-close any open notifications. A nightly scheduled job that reconciles certificate state against host state turns the dashboard from a wall of red into a meaningful signal.
Common Failure Modes
SAN certificates with twenty hostnames generate twenty rows if the ingestion flattens by SAN entry — keep the cert as one row and the SAN list as a related table. Certificates pinned in mobile apps will not appear in any scan; track those manually with a quarterly review. Wildcard certificates in production are a finding, not a feature; report them on the security dashboard.
What Changed in 2026
The Zurich release added native parsers for the post-quantum hybrid certificate formats showing up in browser previews. If your scope includes the experimental edge tier, the parser handles dual-algorithm certs without coercing them to RSA-only. Older releases will misreport the public key algorithm.
What to do this week: query cert_certificate for rows with no assigned_to and no cmdb_ci — that count is your true exposure.