Supply-Chain Dependency Mapping
Maps every external provider a domain depends on — nameservers, mail exchangers, third-party email senders (SPF), CDN and hosting networks, registrar and DKIM vendors — by reading each layer of the graph and keeping only providers whose registrable apex differs from the target’s own. Each dependency is grouped by function and the flow flags single-vendor concentration: one DNS operator, one mail provider or one hosting network is a single point of failure whose outage takes the whole function down. The mirror of Digital Infrastructure Mapping: that flow maps what an entity owns, this maps what it depends on.
The alert
A third-party-risk questionnaire asks which providers shopify.com depends on, and where one outage takes an entire function down with it. The vendor list in a contract system records what was bought; the zone records what actually answers, and those are not the same document.
The question
Do I sign this domain off as concentrated only in mail, and what would tell me I am wrong?
Not "how many providers does it use". The provider count is an input to that question, and on this domain it is the input that points the wrong way.
What this cannot answer
- Whether a listed dependency carries anything.
NAMESERVER_FOR,MAIL_FORandSPF_INCLUDEare published records: delegation and authorization, never delivery. This domain authorizes three external senders; nothing says a message ever went through one. - What runs behind the CDN.
whisper.originsreturned ten candidate addresses on 2026-08-09, every one at confidence 0.0948 by thelinks_tomethod alone, and the step's confidence bar drops all ten. The real origin is not established here —whisper.origins(). - Who the registrar is, by name. The ownership dependency comes back as
iana:292, and the node's only other property is the type labelREGISTRAR. That is an identifier, not a company. - How much of the estate was read.
shopify.comholds zeroRESOLVES_TOedges of its own, so every hosting row comes from its subdomains: 171 of 22,358 known subdomains hold an address, and the step reads a 40-address sample of those. That is Coverage, not a census.
What do we know
Measured 2026-08-09. DNS is delegated to three registrable apexes: foundationdns.com, .org and .net, one nameserver each. Mail is one provider, google.com, across five exchangers. Three external senders are authorized — google.com, sendgrid.net, zendesk.com — and DKIM signing names one vendor, google. The 40 sampled addresses route to three networks: AS13335 CLOUDFLARENET with 33, AS40934 FORTINET with 5, AS15169 GOOGLE with 2. Across a wider sample of 190 subdomain delegations, 135 land on AS13335 and 27 on AS40934.
The concentration reading those counts produce flags exactly one thing: all inbound mail on one provider. DNS at three and hosting at three do not trip it. No step returns a threat verdict, so nothing in this run says whether any provider is listed anywhere.
The physical section came back empty, and empty is where to stop and re-read the query rather than the world. Its step binds a variable inside a bounded subquery and re-binds the same name outside it; the re-bound nodes serialize with an empty name and every pattern comprehension on them returns nothing. Rename the outer variable and the identical walk returns five rows: Cloudflare at 1,503 facilities and 356 exchanges, Google at 1,042 and 177, Fortinet at 226 and 29, Google Cloud at 7 and 2, Amazon at 0 and 0. Zero rows is never a verdict. Here it was a variable name.
Why
- 01Operator (atlas). whisper.identify names who operates the domain itself — the vendor, its category and derived roles. It is the anchor the external dependencies hang off: everything run by a DIFFERENT apex is a supply-chain dependency.
- 02Registrable apex. whisper.psl.tldPlusOne collapses a host to its registrable domain via the Public Suffix List — the reference apex every provider is classified against. A provider whose apex matches this is self-hosted; a provider whose apex differs is an external dependency.
- 03DNS providers. The nameservers that answer for the domain (NAMESERVER_FOR, reverse), folded to their operator apex and kept only where that apex differs from the domain's own — the third-party managed-DNS vendors. DNS root servers are filtered. One operator answering for the whole zone is a single point of failure.
- 04Mail providers. The mail exchangers accepting inbound mail for the domain (MAIL_FOR, reverse), folded to their operator apex and kept only where external — the mail provider (Google Workspace, Microsoft 365, …). A single mail operator handling all inbound is a concentration risk.
- 05Registrar. The registrar the domain is registered through (HAS_REGISTRAR) — the ownership-layer dependency that controls the domain's very existence. Registrar lock and transfer-control policy live here.
- 06Hosting networks. The networks (ASNs) that route the domain's addresses — its own IPs and a sample of its subdomains (RESOLVES_TO → ANNOUNCED_BY → ROUTES), with the ASN name and registrant org. This is the compute/CDN hosting dependency. A single dominant network is a hosting single point of failure.
- 07Authorized email senders. The third-party senders the domain authorizes to send mail on its behalf (SPF_INCLUDE), folded to their operator apex and kept only where external — SendGrid, Zendesk, Salesforce, Mailchimp and the like. Each is a delegated-trust email-delivery dependency.
- 08De-CDN origin. whisper.origins de-fronts a CDN to the real origin IP and ASN behind it (high-confidence origins only; the bar adapts to the score scale). The origin network is the actual hosting dependency the CDN hides — the provider the service truly runs on.
- 09DKIM signing vendors. The vendors that DKIM-sign mail for the domain (DKIM_SIGNED_BY → VENDOR) — the cryptographic email-authentication dependency. A pattern-comprehension keeps it to one row whether or not the edge is populated.
- 10SaaS subdomain delegations. Which external networks the subdomain estate actually delegates into: sample the resolving subdomains (CHILD_OF → RESOLVES_TO → ROUTES) and tally by ASN. Subdomains pointing into AWS, Google Cloud, Fastly, Zendesk and the like are SaaS/cloud dependencies woven through the namespace.
- 11Physical dependency. The datacenter facilities (AS_PRESENT_AT) and internet exchanges (IX_MEMBER) the hosting networks are physically present at — the deepest supply-chain layer. Sparse: only networks with PeeringDB coverage report it.
The pivot the score did not suggest
Three apexes read as three DNS providers. The hostnames behind them do not: gold.foundationdns.com, gold.foundationdns.org, gold.foundationdns.net, one label wearing three TLDs.
whisper.identify on all three returns Cloudflare, category cdn, roles DNS_OPERATOR, ORIGIN_AS, CDN. Their nine addresses route to one network, AS13335 CLOUDFLARENET, nine of nine. That is the same network carrying 33 of the 40 sampled addresses in the hosting row.
DNS and hosting are one company. The map counts them as separate functions with three providers each because the fold that makes providers comparable is the registrable apex, and an apex is not an operator. The run already calls the procedure that closes this, on the target, where it returns no vendor name at all; pointed at the providers it answers in one call — whisper.identify().
Falsify it
Four results would overturn the paragraph above, and each is a query rather than an opinion.
whisper.identifyreturning a different operator for any of the three nameservers. All three returnedCloudflare; a run that splits them ends the single-operator reading.- A nameserver address routing to something other than
AS13335. Nine of nine routed there, and one exception makes DNS genuinely multi-network. - A fourth nameserver on the zone, from a second operator. The graph holds three
NAMESERVER_FORedges and all three aregold.foundationdns.*. whisper.originsclearing its confidence bar on a non-Cloudflare origin network, which would make Cloudflare a front rather than the host.
The nameserver and routing legs are runnable on Posture Audits and BGP & RPKI.
The conclusion
The external supply chain of shopify.com concentrates on two vendors, not six. Cloudflare operates DNS and carries 33 of the 40 sampled addresses. Google receives all inbound mail, signs DKIM, and appears again as an authorized sender. Fortinet, SendGrid and Zendesk are real dependencies and small ones here. The single point of failure is not "mail" alone — it is Cloudflare across two functions the map reports separately.
Attack that at three joints, each named so you can test it:
- the operator fold rests on
whisper.identify, which is a vendor attribution and not a contract; - the hosting share rests on a 40-address sample of 171 resolving subdomains, so a different sample can move it;
- the physical row exists only because a step's zero rows were re-read as a defect in the query, which anyone can dispute by running both forms.
A dependency map with a falsification list can be argued with. One without it can only be believed.
What this cost
11 named steps across the DNS, email, BGP, WHOIS, physical layers. The runner reports what each step returned, row by row, so the evidence and what it took to get it arrive together rather than as one number at the end.
How it uses the graph
Traverses the DNS, email, BGP, WHOIS, physical layers of the graph, in 11 steps:
Attributing the domain to its operator…
Resolving the registrable apex (eTLD+1)…
Finding the external nameserver operators…
Finding the external mail exchangers…
Reading the domain registrar…
Mapping the networks the addresses sit on…
Reading the third-party SPF senders…
Peeling back any CDN front to the real origin…
Reading the DKIM signing vendors…
Grouping the subdomain estate by the network it delegates into…
Mapping the physical facilities the hosting networks sit in…