Compliance & Risk Assessment

Audit DNS posture, SPF/DMARC adoption, geographic hosting jurisdiction, and surface compliance gaps for vendors.

Updated May 2026recipes Integration

Compliance & Risk Assessment Documentation

You're verifying security posture, checking jurisdictional exposure, and building audit evidence.

Quick Triage

Domain Country Exposure Check

Determine what countries a domain's infrastructure is registered in.

-- Country of the IP allocation for a domain's IPs
MATCH (h:HOSTNAME {name: "cloudflare.com"})
      -[:RESOLVES_TO]->(ip:IPV4)
      -[:ANNOUNCED_BY]->(ap:ANNOUNCED_PREFIX)
      -[:HAS_COUNTRY]->(co:COUNTRY)
RETURN DISTINCT co.name AS country, count(ip) AS ip_count

Sample output:

[{"country": "US", "ip_count": 2}]

Tip: For compliance reviews requiring data residency, use this to check whether a vendor's infrastructure is in permitted jurisdictions. Remember this reflects network registration, not physical server location.

Registrar Verification

Confirm that a domain is registered with an approved registrar.

-- Current registrar for a domain
MATCH (h:HOSTNAME {name: "stripe.com"})-[:HAS_REGISTRAR]->(r:REGISTRAR)
RETURN h.name, r.name

Sample output:

[{"h.name": "stripe.com", "r.name": "iana:447"}]

Tip: Registrar identifiers follow the iana:NNNN format where the number is the IANA registrar ID. You can look up any ID at the IANA registrar database (https://www.iana.org/assignments/registrar-ids/).

Registrant Organization Verification

Verify the organization that registered a domain — useful for third-party due diligence and confirming vendor identity.

-- Registrant organization(s) for a domain
MATCH (h:HOSTNAME {name: "stripe.com"})-[:REGISTERED_BY]->(org:ORGANIZATION)
RETURN h.name, org.name LIMIT 5

Sample output:

[
  {"h.name": "stripe.com", "org.name": "domain admin"},
  {"h.name": "stripe.com", "org.name": "stripe"}
]

Tip: WHOIS records often contain multiple organization entries — the registrant, administrative contact, and technical contact may each have a distinct organization field. Use collect(DISTINCT org.name) to deduplicate.

Deep Dive Investigation

Full Security Profile

Build a comprehensive registration and DNS profile for compliance documentation.

-- Complete security profile: registrar, org, nameservers, mail servers, SPF
MATCH (h:HOSTNAME {name: "microsoft.com"})
OPTIONAL MATCH (h)-[:HAS_REGISTRAR]->(r:REGISTRAR)
OPTIONAL MATCH (h)-[:REGISTERED_BY]->(org:ORGANIZATION)
OPTIONAL MATCH (ns:HOSTNAME)-[:NAMESERVER_FOR]->(h)
OPTIONAL MATCH (mx:HOSTNAME)-[:MAIL_FOR]->(h)
RETURN h.name,
       collect(DISTINCT r.name) AS registrar,
       collect(DISTINCT org.name) AS org,
       collect(DISTINCT ns.name) AS nameservers,
       collect(DISTINCT mx.name) AS mailservers

Sample output:

[{
  "h.name": "microsoft.com",
  "registrar": ["iana:292"],
  "org": ["domain administrator", "microsoft corporation"],
  "nameservers": ["ns1-39.azure-dns.com", "ns2-39.azure-dns.net", "ns3-39.azure-dns.org", "ns4-39.azure-dns.info"],
  "mailservers": ["microsoft-com.mail.protection.outlook.com"]
}]

Tip: Use OPTIONAL MATCH throughout — mandatory MATCH for any WHOIS field will return no results for domains where that field is absent. Each OPTIONAL MATCH independently returns null if no match exists.

Batch Domain Audit

Run a security check across a portfolio of domains.

-- Batch audit: registrar and nameservers for multiple domains
UNWIND ["google.com", "cloudflare.com", "stripe.com"] AS domain
MATCH (h:HOSTNAME {name: domain})
OPTIONAL MATCH (h)-[:HAS_REGISTRAR]->(r:REGISTRAR)
OPTIONAL MATCH (ns:HOSTNAME)-[:NAMESERVER_FOR]->(h)
RETURN domain,
       collect(DISTINCT r.name) AS registrar,
       collect(DISTINCT ns.name) AS nameservers

Tip: For large domain portfolios, break the UNWIND list into batches of 50-100 domains per query to stay within response size limits.

WHOIS History for Compliance Evidence

Pull a timestamped audit trail of registration changes.

-- Historical WHOIS record for evidence collection
CALL whisper.history("google.com")

Sample output (first 2 of 36 snapshots):

[
  {"indicator": "google.com", "type": "domain", "queryTime": "2024-11-05 21:15:21", "createDate": "1997-09-05", "updateDate": "2024-08-02", "expiryDate": "2028-09-13", "registrar": "MarkMonitor, Inc.", "country": "US"},
  {"indicator": "google.com", "type": "domain", "queryTime": "2016-06-14 05:41:13", "createDate": "1997-09-15", "updateDate": "2015-06-12", "expiryDate": "2020-09-14", "registrar": "MarkMonitor, Inc."}
]

Tip: Historical WHOIS is available for many popular domains. The queryTime field shows when each snapshot was captured. Gaps in history are normal — WHOIS scraping doesn't capture every change.