API Tutorials

DNS and SSL Change Evidence Packs for Safer Releases

Production changes rarely fail because one person forgot what DNS is. They fail because the team lacks before-and-after evidence. This guide shows how to capture DNS, WHOIS, IP, and certificate state around every risky infrastructure change.

April 11, 20268 min readPlatform Engineering Team
2
Snapshots per change
4
Validation checks
1
Change record

The Problem: Change Tickets Miss Runtime State

A platform team changes an A record during a migration. A security team rotates a certificate. A domain owner updates nameservers. A CDN vendor changes an edge IP. The ticket says the change was approved, and CI says the deployment passed. That still does not answer the question that matters during an outage: what did the public internet see before and after the change?

An evidence pack closes that gap. It is a timestamped bundle of API results captured before and after a production change. It does not replace CI/CD guardrails or monitoring. It gives SRE, security, compliance, and incident responders a durable record of DNS resolution, registration status, network context, and certificate health.

When to Use an Evidence Pack

Use this workflow for changes that affect how users, mail providers, partners, or scanners reach your public assets. It is most valuable when the blast radius crosses teams.

Change typeEvidence to captureRollback signal
DNS migrationA, AAAA, CNAME, MX, TXT, NS, and SOA recordsWrong target, missing MX, stale nameserver, unexpected TTL
Certificate rotationValidity, issuer, SANs, chain status, days remainingInvalid chain, wrong hostname, self-signed or expired certificate
Registrar or nameserver updateParsed WHOIS data, registrar, expiration, nameserversUnexpected registrar, domain near expiration, nameserver mismatch
Hosting or CDN cutoverResolved IP, geolocation, ASN, organizationUnexpected ASN, country, or network owner

Step-by-Step Workflow

  1. Attach the asset list to the change. Include domains, subdomains, expected record values, expected IP ownership, and certificate hostnames.
  2. Capture the baseline. Run API checks before the change window and store raw JSON with the ticket ID, release ID, and timestamp.
  3. Apply the change through the approved path. This might be Terraform, a registrar console, a certificate automation job, or a CDN dashboard.
  4. Run post-change validation. Compare the new state against the expected target, not just the old state.
  5. Send exceptions by webhook-based automation. If a plan or internal workflow supports webhooks, send only the failed checks to the incident channel or change ticket.
  6. Archive the pack. Store the JSON and human-readable summary so incident responders can answer what changed without rerunning stale checks.

Technical Implementation

Ops.Tools verifies DNS lookup, WHOIS data, SSL checker, and IP detail routes in the repo OpenAPI spec. The API paths below follow those generated client routes. The examples use an automation script, but the same checks can run from GitHub Actions, GitLab CI, Buildkite, Jenkins, or an internal change bot.

cURL: capture a pre-change snapshot

API="https://ops.tools/api"
KEY="$OPS_TOOLS_API_KEY"
DOMAIN="api.example.com"
TICKET="CHG-1842"

mkdir -p "evidence/$TICKET/pre"

curl -s "$API/v1-dns-lookup?address=$DOMAIN&type=A" \
  -H "Authorization: Bearer $KEY" > "evidence/$TICKET/pre/dns-a.json"

curl -s "$API/v1-dns-lookup?address=$DOMAIN&type=TXT" \
  -H "Authorization: Bearer $KEY" > "evidence/$TICKET/pre/dns-txt.json"

curl -s "$API/v1-whois-data?domain=example.com&parseWhoisToJson=true" \
  -H "Authorization: Bearer $KEY" > "evidence/$TICKET/pre/whois.json"

curl -s "$API/v1-ssl-checker?domain=$DOMAIN" \
  -H "Authorization: Bearer $KEY" > "evidence/$TICKET/pre/ssl.json"

TypeScript: compare pre and post states

interface ChangeTarget {
  ticketId: string;
  domain: string;
  expectedARecord: string;
  expectedAsn?: number;
}

interface CheckResult {
  check: string;
  ok: boolean;
  detail: string;
}

const API = 'https://ops.tools/api';
const headers = { Authorization: `Bearer ${process.env.OPS_TOOLS_API_KEY}` };

async function getJson<T>(path: string): Promise<T> {
  const response = await fetch(`${API}${path}`, { headers });
  if (!response.ok) throw new Error(`Check failed with ${response.status}`);
  return response.json() as Promise<T>;
}

async function validateChange(target: ChangeTarget): Promise<CheckResult[]> {
  const checks: CheckResult[] = [];

  const dns = await getJson<{ records?: string[] }>(
    `/v1-dns-lookup?address=${target.domain}&type=A`,
  );
  const records = dns.records ?? [];
  checks.push({
    check: 'DNS A record',
    ok: records.includes(target.expectedARecord),
    detail: `Expected ${target.expectedARecord}; got ${records.join(', ') || 'no records'}`,
  });

  const ssl = await getJson<{ certificate?: { isValid?: boolean; daysRemaining?: number } }>(
    `/v1-ssl-checker?domain=${target.domain}`,
  );
  checks.push({
    check: 'SSL certificate',
    ok: Boolean(ssl.certificate?.isValid) && (ssl.certificate?.daysRemaining ?? 0) >= 30,
    detail: `Valid: ${ssl.certificate?.isValid}; days remaining: ${ssl.certificate?.daysRemaining ?? 'unknown'}`,
  });

  if (target.expectedAsn) {
    const ip = await getJson<{ asn?: number; organization?: string }>(
      `/v1-get-ip-details?ip=${target.expectedARecord}`,
    );
    checks.push({
      check: 'IP ownership',
      ok: ip.asn === target.expectedAsn,
      detail: `Expected ASN ${target.expectedAsn}; got ${ip.asn ?? 'unknown'} ${ip.organization ?? ''}`,
    });
  }

  return checks;
}

async function sendWebhookIfNeeded(url: string, target: ChangeTarget, checks: CheckResult[]) {
  const failures = checks.filter((check) => !check.ok);
  if (failures.length === 0) return;

  await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ticketId: target.ticketId,
      domain: target.domain,
      failures,
      source: 'ops-tools-change-evidence',
    }),
  });
}

Decision Matrix: What Should Block the Change?

Not every difference should stop a release. A DNS TXT record changing during a planned email authentication update may be expected. A certificate with the wrong hostname is not. Use blocking rules only where the signal is strong.

SignalActionReason
Expected A record missingBlock or roll backTraffic may not reach the new service.
Certificate invalidBlock or roll backBrowsers, clients, or partner systems may reject TLS.
Domain expires soonCreate urgent taskThe change may be safe, but ownership risk needs follow-up.
Unexpected ASN or countryEscalate for reviewCould be a CDN change, DNS hijack, or asset inventory gap.

Where CI/CD, Monitoring, and AI Agents Fit

CI/CD is still useful. Run a lightweight version of the checks before deployment to catch obvious failures. The evidence pack extends that idea beyond the deployment step by storing the before-and-after state. For scheduled monitoring, run the same checks daily and alert only on policy exceptions.

If your team uses AI agents or MCP-based orchestration, frame the pattern accurately: the agent can call the same HTTP APIs, compare results, and draft a change summary. That is an API-based workflow, not a native Ops.Tools AI or MCP integration unless you build and operate that integration yourself.

Design the Policy Before the Script

The hard part is not calling an API. The hard part is deciding which signals are allowed to fail. Write the policy in plain language before you automate it. For DNS, decide which record types matter for the service and which values are expected after the change. For WHOIS, decide how much renewal runway your organization requires and who owns registrar follow-up. For IP context, decide whether an unexpected ASN should block the change or trigger review. For SSL, decide the minimum days remaining and whether self-signed certificates are ever acceptable for public endpoints.

This policy should live with your release process, not inside one engineer's script. Put the thresholds in a versioned configuration file, a change-management template, or a platform service that multiple teams can reuse. That makes the evidence pack explainable. When a release is blocked, the team can point to the policy rather than arguing over the script's opinion.

{
  "domain": "api.example.com",
  "dns": {
    "A": ["203.0.113.42"],
    "TXT": ["v=spf1 include:_spf.example.net -all"]
  },
  "ssl": {
    "minimumDaysRemaining": 30,
    "allowSelfSigned": false
  },
  "ip": {
    "expectedAsn": 64500,
    "expectedCountryCode": "US"
  },
  "whois": {
    "minimumDomainDaysRemaining": 90
  }
}

Webhook-Based Alert Routing

Ops.Tools pricing pages list webhook notifications on the Growth plan, and many teams also use their own webhook layer after API checks. Keep the distinction clear in runbooks: unless a destination integration is verified as native, describe the alerting path as webhook-based or automation-based. That is still a strong workflow. A change bot can post failed checks to Slack, create a Jira task, update a ServiceNow change, or page the on-call team through the organization's existing incident platform.

Send less than you collect. The archive should keep the full JSON output, but the alert should include only the failed check, expected value, actual value, ticket ID, and rollback owner. Long alerts get ignored during a change window. Short alerts move work to the right person.

Domain Portfolio and Compliance Value

Evidence packs are not only for individual releases. Over time, they create a useful history of domain operations. You can see which services change DNS often, which teams rotate certificates late, which domains are drifting away from approved registrars, and which assets repeatedly resolve to unexpected networks. That history helps platform teams prioritize automation and helps security teams focus on assets with repeated exceptions.

For compliance, do not overstate the control. An evidence pack does not make a system compliant by itself. It supports control evidence by showing that public infrastructure changes were checked, exceptions were captured, and ownership was assigned. That is the kind of artifact auditors and risk teams can review without asking an engineer to reconstruct a change from memory.

Ownership, Retention, and Review Cadence

A useful evidence pack has an owner. For application releases, the owner is usually the service team. For DNS and registrar changes, it may be platform, IT, or domain operations. For certificate rotation, it may be the team that owns the public endpoint, even if the certificate automation is centralized. Record that owner in the evidence summary so exceptions do not become anonymous backlog items.

Retention should follow the importance of the asset. A low-risk marketing subdomain may only need a short retention window. A customer-facing API, payment domain, identity endpoint, or regulated product domain may need evidence preserved with the change ticket for longer. Store the raw JSON output, the normalized summary, and the policy version used for validation. That last piece matters because a passing check in April may not pass under a stricter policy in September.

Review the exceptions regularly. If the same service trips DNS validation every release, the expected-state file is probably stale or the deployment process is bypassing infrastructure-as-code. If the same domain keeps approaching expiration thresholds, ownership may be unclear. If IP ownership checks keep flagging a CDN ASN, update the policy to reflect the real target network. Evidence packs are most valuable when they improve the operating model, not when they become another folder no one opens.

A good monthly review is short: list repeated failures, decide whether each one is a real risk or a bad baseline, assign one owner, and update the policy before the next release window.

Incident Response Value

During an incident, responders need to move fast without rewriting history. The archived evidence pack tells them whether DNS shifted to the intended IP, whether the certificate was valid after rotation, whether the registrar or nameservers changed, and whether the resolved IP belonged to the expected network. That context supports both operational triage and security investigation.

FAQ

What is a DNS and SSL evidence pack?

It is a stored before-and-after record for a production change. A good pack includes DNS records, parsed WHOIS data, IP context, SSL certificate details, timestamps, expected values, and a short exception summary.

How is this different from a CI/CD check?

CI/CD checks decide whether a deployment should proceed. Evidence packs create a durable record for change review, incident response, compliance, and cross-team debugging after the change has happened.

Can webhook alerts be part of the workflow?

Yes. Ops.Tools pricing pages list webhook notifications on the Growth plan, and your own automation can also send webhooks after API checks. Describe it as webhook-based unless you have verified a native integration with the destination system.

For deeper implementation detail, pair this workflow with the CI/CD infrastructure checks guide and the certificate monitoring guide.

Recommended Next Step

Validate Public Infrastructure Before and After Changes

Use Ops.Tools API checks to capture DNS, WHOIS, IP, and SSL evidence for safer releases and faster incident review.

Related Articles

API Tutorials8 min read

DNS Migration Checklist for Production Teams in 2026: Validate DNS, SSL, IP, and Headers Before Cutover

Use a repeatable cutover checklist to validate DNS records, registration context, IP ownership, certificates, and HTTP headers before you move production traffic.

Read Article
API Tutorials8 min read

How to Automate Third-Party Domain Due Diligence in 2026

Build a vendor-intake workflow that checks DNS, WHOIS, IP, SSL, and headers in bulk, routes findings by webhook, and keeps evidence for security reviews.

Read Article
API Tutorials12 min read

DNS Lookup API: How to Check DNS Records Programmatically

Complete developer guide to querying DNS records via API. Includes working code examples in Python, Node.js, Go, and PHP with caching best practices.

Read Article