<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>braedon.dev</title><link href="https://braedon.dev/" rel="alternate"></link><link href="https://braedon.dev/feeds/atom.xml" rel="self"></link><id>https://braedon.dev/</id><updated>2022-11-11T06:00:00+08:00</updated><entry><title>Mastodon Isn't Twitter</title><link href="https://braedon.dev/2022/mastodon-twitter.html" rel="alternate"></link><published>2022-11-11T06:00:00+08:00</published><updated>2022-11-11T06:00:00+08:00</updated><author><name></name></author><id>tag:braedon.dev,2022-11-11:/2022/mastodon-twitter.html</id><summary type="html">&lt;p&gt;I&amp;rsquo;ve spent the last couple of years being very &lt;em&gt;on Twitter&lt;/em&gt;. Along with spending too much time scrolling/reading, I write there frequently and at length. It&amp;rsquo;s where I publish most of my adtech/disinformation research, and where I talk about my software projects.&lt;br&gt;
&lt;br&gt;
Like a lot of Twitter users recently, I&amp;rsquo;ve been trying to work out if Mastodon is an alternative if/when it&amp;rsquo;s no longer viable to stay on Twitter. I have my doubts.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I&amp;rsquo;ve spent the last couple of years being very &lt;em&gt;on Twitter&lt;/em&gt;. Along with spending too much time scrolling/reading, I write there frequently and at length. It&amp;rsquo;s where I publish most of my adtech/disinformation research, and where I talk about my software projects.&lt;/p&gt;
&lt;p&gt;Like a lot of Twitter users recently, I&amp;rsquo;ve been trying to work out if Mastodon is an alternative if/when it&amp;rsquo;s no longer viable to stay on Twitter. I have my doubts.&lt;/p&gt;
&lt;p&gt;To understand why, we first need to look at why the bird site had such a draw with a certain group of people &amp;mdash; what set it apart from the various other types of mass communication.&lt;/p&gt;
&lt;h2 id="twitter"&gt;&lt;a class="greyLink" href="#twitter"&gt;Twitter&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While there are undoubtedly many factors in play, a key part of Twitter&amp;rsquo;s appeal is that tweets have unlimited potential reach, and are persistent.&lt;/p&gt;
&lt;p&gt;Tweets are entirely public. On Twitter, you don&amp;rsquo;t really post to your friends, family, or any other community. You&amp;rsquo;re tweeting to everyone, at least aspirationally. Retweets, replies, and quote tweets all help spread a tweet to a wider audience, and are themselves tweets that can be spread.&lt;/p&gt;
&lt;p&gt;Perhaps more importantly, tweets spread far beyond Twitter itself. They can be viewed by anyone without an account, linked to from anywhere, and they&amp;rsquo;re easy to embed or screenshot. The ability of a tweet to reach the wider world, and the frequency at which that happens, is core to Twitter&amp;rsquo;s appeal.&lt;/p&gt;
&lt;p&gt;Tweets have a short half-life in the Twitter feed, but remain accessible via links and embeds, and can be readily found via searches. Retweets, replies, and quote tweets push them back into the feed and start the spread again. This persistence preserves the value of the work that goes into creating tweets &amp;mdash; particularly long threads.&lt;/p&gt;
&lt;p&gt;Reach and persistence are why Twitter is &lt;em&gt;the&lt;/em&gt; social network for brands, politicians, and journalists; why its influence has always been outsized for its user base. And they&amp;rsquo;re why I&amp;rsquo;m there, building a user-base for a niche research tool, and sharing screenshots of brands advertising on disinformation.&lt;/p&gt;
&lt;p&gt;Twitter is where you go if you want your ideas to spread as widely as possible, and to be able to refer back to them in the future.&lt;/p&gt;
&lt;p&gt;Clearly, this is not what &lt;em&gt;everyone&lt;/em&gt; on Twitter is looking for. And these dynamics cause a lot of issues &amp;mdash; it&amp;rsquo;s often called &amp;ldquo;the hellsite&amp;rdquo; for a reason. But I do think these factors are key to understanding Twitter&amp;rsquo;s niche, and whether any potential replacement can fill it.&lt;/p&gt;
&lt;h2 id="mastodon"&gt;&lt;a class="greyLink" href="#mastodon"&gt;Mastodon&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Superficially, Mastodon looks a lot like Twitter, just open source and federated. But it has a significant number of differences, many of which are directly at odds with Twitter&amp;rsquo;s recipe of reach and persistence.&lt;/p&gt;
&lt;p&gt;One of the first things a Twitter user will notice is the lack of quote tweets. This is an &lt;a href="https://mastodon.social/@Gargron/99662106175542726" rel="noopener noreferrer"&gt;explicit decision to prevent quote-dunking&lt;/a&gt;, an oft-lamented part of Twitter culture.&lt;/p&gt;
&lt;p&gt;But while quote tweets can be used to dunk, they can also be used to reference old tweets (your own, or others&amp;rsquo;) as context for a new tweet, or just to take a conversation in a slightly different direction without hijacking the original one. They&amp;rsquo;re key to how ideas spread, expand, and evolve across Twitter (and beyond).&lt;/p&gt;
&lt;p&gt;Another major departure is searching for posts. Most Mastodon servers only allow searching by hashtag &amp;mdash; full-text search just isn&amp;rsquo;t provided. An &lt;a href="https://fedsearch.io/" rel="noopener noreferrer"&gt;external search service&lt;/a&gt; was recently created and then shut down almost immediately due to community backlash.&lt;/p&gt;
&lt;p&gt;Once again, this is a deliberate choice &amp;mdash; harassers often find targets by searching for specific key words or phrases. But it also makes it hard to find old posts you want to reference (even your own) &amp;mdash; once they&amp;rsquo;re out of your feed, they&amp;rsquo;re largely gone.&lt;/p&gt;
&lt;p&gt;Automatic post deletion is a built-in feature, and used by a lot of people. When you migrate your profile to a new server you can bring your followers, but not your posts. Long-term post persistence is clearly not the goal here.&lt;/p&gt;
&lt;p&gt;Mastodon servers are designed to be distinct communities, with their own rules and norms. While you can follow people from other servers, it&amp;rsquo;s highly recommended you &lt;a href="https://fightwithtools.dev/posts/writing/why-you-should-find-a-mastodon-instance/" rel="noopener noreferrer"&gt;find a server that matches your interests&lt;/a&gt;. Mastodon doesn&amp;rsquo;t have a recommendation algorithm, so discovery is largely facilitated by your server&amp;rsquo;s local timeline &amp;mdash; a feed of all the posts from users on your server.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re not posting to everyone, aiming for maximum reach &amp;mdash; you&amp;rsquo;re talking to your local community. Trying to talk to followers on other servers spams your community with posts they don&amp;rsquo;t care about.&lt;/p&gt;
&lt;p&gt;Reach is further curtailed when server admins block entire other servers, preventing users from following each other. While there are often obvious reasons for this &amp;mdash; there are some toxic servers out there &amp;mdash; other cases are due to more complex cultural issues.&lt;/p&gt;
&lt;p&gt;For example, a &lt;a href="https://journa.host" rel="noopener noreferrer"&gt;new server for journalists&lt;/a&gt; is apparently being blocked by a number of servers. I expect these kinds of culture clashes to be a problem for a lot of Twitter users trying to migrate, not to mention the existing Mastodon communities being impacted.&lt;/p&gt;
&lt;p&gt;Overall, a Mastodon server seems a lot closer to a forum, or even something like a Discord server, than Twitter. Posts are essentially transient, and work best when you&amp;rsquo;re talking to your local community.&lt;/p&gt;
&lt;p&gt;I have no doubt many Twexiters will find and create great communities on Mastodon, but I&amp;rsquo;m not convinced it can slot into the niche Twitter has filled for so long.&lt;/p&gt;</content><category term="general"></category><category term="twitter"></category><category term="mastodon"></category></entry><entry><title>Ads.txt OwnerDomain and ManagerDomain</title><link href="https://braedon.dev/2022/adstxt-update.html" rel="alternate"></link><published>2022-04-27T20:00:00+08:00</published><updated>2022-04-27T20:00:00+08:00</updated><author><name></name></author><id>tag:braedon.dev,2022-04-27:/2022/adstxt-update.html</id><summary type="html">&lt;p&gt;IAB Tech Lab recently released a new version of the &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt&lt;/a&gt; standard for comment. This 1.1 update defines two new variables &amp;mdash; OWNERDOMAIN and MANAGERDOMAIN &amp;mdash; that attempt to solve some outstanding issues with how seller relationships are expressed.&lt;br&gt;
&lt;br&gt;
While these new variables provide useful extra data points, I&amp;rsquo;m concerned they won&amp;rsquo;t achieve the wide adoption necessary to make a meaningful difference, and that some of the changes are moving the standard in the wrong direction.&lt;/p&gt;</summary><content type="html">&lt;p&gt;IAB Tech Lab recently released a new version of the &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt&lt;/a&gt; standard for comment. This 1.1 update defines two new variables &amp;mdash; OWNERDOMAIN and MANAGERDOMAIN &amp;mdash; that attempt to solve some outstanding issues with how seller relationships are expressed.&lt;/p&gt;
&lt;p&gt;While these new variables provide useful extra data points, I&amp;rsquo;m concerned they won&amp;rsquo;t achieve the wide adoption necessary to make a meaningful difference, and that some of the additions are moving the standard in the wrong direction.&lt;/p&gt;
&lt;h2 id="ownerdomain"&gt;&lt;a class="greyLink" href="#ownerdomain"&gt;OwnerDomain&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adstxt-update_ownerdomain-def.png"&gt;&lt;img alt="Variable: &amp;quot;OWNERDOMAIN&amp;quot;, Value: &amp;quot;Specifies the business domain of the business entity that owns the domain/site/app (e.g., example.com owns example1.com, example2, com, etc.)&amp;quot;, Description: &amp;quot;(Recommended) This should be the same value as the seller_domain in all Publisher entries in a sellers.json file. Like seller_domain, this should be Public Suffix List+1, not a full hostname or a URL. For OpenRTB SupplyChain objects that are complete, the node representing the originating publisher (the node listed first in the schain object) should have seller_domain that matches the OWNERDOMAIN. If more than one instance of this variable is included only the first should be used. If this variable is absent, it should be assumed that the OWNERDOMAIN is the same as the domain being monetized and where the ads.txt file was found. It is recommended that this field is included even if the OWNERDOMAIN is the same as the domain on which the ads.txt file is found. It is also recommended that buyers mandate for sellers that are listed as BOTH in sellers.json to correctly list OWNERDOMAIN in all ads.txt files that they own OR represent.&amp;quot;" src="https://braedon.dev/images/a_tech/adstxt-update_ownerdomain-def.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of the OWNERDOMAIN variable from the updated ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;OWNERDOMAIN allows a site to declare who owns it by specifying the owner&amp;rsquo;s &amp;ldquo;business domain&amp;rdquo;. While this can just be the site domain, it&amp;rsquo;s often different, particularly when a company owns multiple different sites. For example, Gizmodo could add &lt;code&gt;OWNERDOMAIN=g-omedia.com&lt;/code&gt; to their ads.txt, indicating they&amp;rsquo;re owned by G/O Media.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adstxt-update_gizmodo-pub-direct-sellers.png"&gt;&lt;img alt="The top 6 rows of a table titled &amp;quot;Publisher Direct Sellers&amp;quot;. The listed ad accounts are from a variety of ad systems. 4 accounts have the domain &amp;quot;g-omedia.com&amp;quot;, one has &amp;quot;gizmodo.com&amp;quot;, and one has &amp;quot;thefmg.com&amp;quot;." src="https://braedon.dev/images/a_tech/adstxt-update_gizmodo-pub-direct-sellers.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Some of the PUBLISHER ad accounts authorized as DIRECT sellers by Gizmodo.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;A site&amp;rsquo;s OWNERDOMAIN can be compared with an ad account&amp;rsquo;s domain from its sellers.json entry to determine if they have the same owner. This will be helpful in checking if a PUBLISHER account is actually a valid seller for a particular site, for example.&lt;/p&gt;
&lt;p&gt;A related use case is determining whether an account labelled BOTH in sellers.json is acting as a PUBLISHER or INTERMEDIARY on a given site. If the site&amp;rsquo;s OWNERDOMAIN matches the account&amp;rsquo;s domain, it&amp;rsquo;s acting as a PUBLISHER; otherwise it&amp;rsquo;s an INTERMEDIARY.&lt;/p&gt;
&lt;p&gt;Intuitively, OWNERDOMAIN should also help in checking if an account is actually DIRECT. However, this isn&amp;rsquo;t mentioned by the spec (though there is a brief mention in the &amp;ldquo;Implementation Guide&amp;rdquo;), and the &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;definition of DIRECT is a fraught topic&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="managerdomain"&gt;&lt;a class="greyLink" href="#managerdomain"&gt;ManagerDomain&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adstxt-update_managerdomain-def.png"&gt;&lt;img alt="Variable: &amp;quot;MANAGERDOMAIN&amp;quot;, Value: &amp;quot;A pointer to the primary or exclusive monetization partner of the publishers inventory&amp;quot;, Description: &amp;quot;(Optional, use only when relevant) When the owner of the site does not manage monetization either globally or in a specific country, the domain of the exclusive management company is included in this variable. Syntax of the domain is [PSL+1 domain, required], [ISO 3166-1 alpha-3 country code, optional, blank=global] This variable should only be used for a seller who is not the publisher but is the primary or exclusive programmatic seller for this site. This will typically only apply if the publisher is not selling their own inventory in the given market. There can be more than one MANAGERDOMAIN value but only one per country. A global/default MANAGERDOMAIN doesn’t have a country “extension” on the variable line. The default can be overridden by other entries with country extensions included. See example for country declaration format. Consult the implementation guide for details on use cases and potential SPO implications.&amp;quot;" src="https://braedon.dev/images/a_tech/adstxt-update_managerdomain-def.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of the MANAGERDOMAIN variable from the updated ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;MANAGERDOMAIN is similar, but rather than declaring the site&amp;rsquo;s owner, it declares the company exclusively responsible for managing the site&amp;rsquo;s ad inventory (if there is one). Different companies can be declared per country if needed.&lt;/p&gt;
&lt;p&gt;For example, meetup.com&amp;rsquo;s ad inventory is managed by Freestar. They could add &lt;code&gt;MANAGERDOMAIN=freestar.com&lt;/code&gt; to their ads.txt to indicate this relationship.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adstxt-update_meetup-supplychain-graph.png"&gt;&lt;img alt="A directed graph showing meetup.com connecting to freestar.com, which then branches out to connect to large numbers of other ad systems." src="https://braedon.dev/images/a_tech/adstxt-update_meetup-supplychain-graph.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Part of a graph of meetup.com&amp;rsquo;s authorized supply chains.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;A management company&amp;rsquo;s ad accounts can be identified by comparing account domains to the manager&amp;rsquo;s domain. As an exclusive manager&amp;rsquo;s accounts should be the most direct sources of the site&amp;rsquo;s inventory, this can help with Supply Path Optimisation (SPO).&lt;/p&gt;
&lt;p&gt;Note that the spec falls short of saying the manager&amp;rsquo;s accounts can be labelled DIRECT, however, and they are labelled RESELLER in the implementation guide&amp;rsquo;s examples.&lt;/p&gt;
&lt;h2 id="adoption-and-enforcement"&gt;&lt;a class="greyLink" href="#adoption-and-enforcement"&gt;Adoption and Enforcement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These new variables are only useful in preventing ad fraud if DSPs actually enforce them, e.g. by not buying inventory via PUBLISHER accounts that don&amp;rsquo;t match a site&amp;rsquo;s OWNERDOMAIN. But DSPs aren&amp;rsquo;t going to turn off a large proportion of their supply, so wide adoption is required first.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s the incentive for sites to adopt the new variables if DSPs aren&amp;rsquo;t using them? DSPs could add validations that only run on sites that provide them, giving some reason for their existence without overly affecting supply. However, this effectively just adds new restrictions to sites that adopt the variables. Sites that are benefiting from the current paucity of validation effectively have an incentive to &lt;em&gt;not&lt;/em&gt; add them.&lt;/p&gt;
&lt;p&gt;Usually, the ability to say you comply with a spec provides some incentive in itself. However, the spec doesn&amp;rsquo;t actually require either variable. OWNERDOMAIN is &amp;ldquo;recommended&amp;rdquo; and &amp;ldquo;should&amp;rdquo; be checked against the domains of PUBLISHER accounts. MANAGERDOMAIN is &amp;ldquo;optional&amp;rdquo; and &amp;ldquo;should&amp;rdquo; be provided when a manager is used. A site that should provide them can simply not, and still claim they are following the spec. Similarly, a DSP can claim to support the ads.txt spec, but ignore these variables entirely.&lt;/p&gt;
&lt;p&gt;Even if a DSP wants to break from the pack and start enforcing them, they aren&amp;rsquo;t standalone. For example, they need to be compared to account domains, but the account domain field is optional in the sellers.json spec. Currently, more accounts are &lt;a href="https://well-known.dev/resources/ads_txt/sellers/?q=status%3Aok+-domain%3A*#results" rel="noopener noreferrer"&gt;missing a domain&lt;/a&gt; than &lt;a href="https://well-known.dev/resources/ads_txt/sellers/?q=status%3Aok+domain%3A*#results" rel="noopener noreferrer"&gt;provide one&lt;/a&gt;. Enforcing OWNERDOMAIN and MANAGERDOMAIN requires first enforcing account domains, and that hasn&amp;rsquo;t happened in the almost 3 years since sellers.json was released.&lt;/p&gt;
&lt;p&gt;MANAGERDOMAIN isn&amp;rsquo;t really enforceable per se &amp;mdash; it&amp;rsquo;s essentially just a SPO hint. The question is more if DSPs will actually meaningful change their buying decisions based on it. SupplyChain objects were released years ago alongside sellers.json, and there&amp;rsquo;s been little evidence they are being widely used for SPO, or even validated.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also important to note that OWNERDOMAIN and MANAGERDOMAIN are set by sites, and there&amp;rsquo;s no programmatic way for DSPs to check they&amp;rsquo;re actually correct. I can think of a few ways this could be exploited by less than virtuous sites (though determining what would work in practice is always difficult).&lt;/p&gt;
&lt;h2 id="owner-vs-site"&gt;&lt;a class="greyLink" href="#owner-vs-site"&gt;Owner vs. Site&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The definition of OWNERDOMAIN states that it should match the domain of any PUBLISHER accounts &amp;mdash; i.e. account domains in sellers.json should be the owner domain, not the site domain. This isn&amp;rsquo;t a change &amp;mdash; it&amp;rsquo;s essentially what the sellers.json spec already says, though it often isn&amp;rsquo;t followed currently (see the Gizmodo example above).&lt;/p&gt;
&lt;p&gt;However, I&amp;rsquo;m concerned that this doubles down on the idea that SupplyChain objects should start at the site&amp;rsquo;s owner, not the site itself. This means that different sites with the same owner can have identical supply chains.&lt;/p&gt;
&lt;p&gt;This is a complex issue &amp;mdash; see my posts on &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;ads.txt&lt;/a&gt; and &lt;a href="https://braedon.dev/2021/adspecs-2.html"&gt;sellers.json&lt;/a&gt; for more details &amp;mdash; but the core problem is sites that share supply chains can spoof each other&amp;rsquo;s ad inventory at will.&lt;/p&gt;
&lt;p&gt;When I first wrote about this issue it was just a theoretical possibility, but then I found &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;Gannett doing it (accidentally)&lt;/a&gt; in the wild. If they were using SupplyChains that started at the site level, the bug could have been caught by basic SupplyChain validations. Instead, all their sites shared the same supply chains, and no one noticed the issue for 9 months.&lt;/p&gt;
&lt;p&gt;Requiring SupplyChains to start at the site level wouldn&amp;rsquo;t make this kind of authorized domain spoofing impossible &amp;mdash; the SupplyChain itself could be spoofed by a malicious actor (or a particularly unfortunate bug) &amp;mdash; but that&amp;rsquo;s a problem with these specs in general, not something specific to this issue.&lt;/p&gt;
&lt;p&gt;What makes ads.txt, sellers.json, and SupplyChain objects (potentially) useful is the ability to cross-check data from different sources. A SupplyChain can be checked against other fields provided in the bid request (which are often pulled from different places), the sellers.json entries provided by the ad systems, and the ads.txt file provided by the site.&lt;/p&gt;
&lt;p&gt;Not requiring SupplyChains to start at the site level eliminates opportunities to validate the link between the site and the first seller account, and will result in less issues being detected.&lt;/p&gt;
&lt;h2 id="final-thoughts"&gt;&lt;a class="greyLink" href="#final-thoughts"&gt;Final Thoughts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This ads.txt update only introduces two relatively simple variables, but they slot into a complex web of existing standards, and their often less than stellar implementations. I&amp;rsquo;ve only touched on what I think are the most important points, but there&amp;rsquo;s plenty more there to dig into.&lt;/p&gt;
&lt;p&gt;One aspect I&amp;rsquo;ve avoided for brevity (and because I&amp;rsquo;m not sure how to say it nicely &amp;mdash; sorry) is a number of issues that basically boil down to a need for significant copy editing. Key sentences that don&amp;rsquo;t really make sense, incorrect field names, new terms that seemingly duplicate existing ones, paragraphs that are replicated from elsewhere but with differences, etc. I&amp;rsquo;ve tried to avoid being pedantic in this post, but if pedantry is ever required it&amp;rsquo;s when you&amp;rsquo;re writing specifications.&lt;/p&gt;
&lt;p&gt;OWNERDOMAIN patches one of the holes in validating DIRECT PUBLISHER accounts, but others remain. MANAGERDOMAIN helps break the DIRECT/RESELLER binary, if DSPs will use it. Adoption and enforcement will be key, but that&amp;rsquo;s exactly where the existing specs have faltered. Unfortunately, I don&amp;rsquo;t see anything in this update that would fundamentally change that.&lt;/p&gt;
&lt;p&gt;Finally, ads are displayed on sites. Ad inventory supply chains should start at the site.&lt;/p&gt;</content><category term="adtech"></category><category term="adspecs"></category><category term="ads.txt"></category><category term="sellers.json"></category><category term="supply-chain"></category></entry><entry><title>Domain Spoofing on Gannett Sites</title><link href="https://braedon.dev/2022/gannett-spoofing.html" rel="alternate"></link><published>2022-03-09T08:17:00+08:00</published><updated>2022-03-09T08:17:00+08:00</updated><author><name></name></author><id>tag:braedon.dev,2022-03-09:/2022/gannett-spoofing.html</id><summary type="html">&lt;p&gt;Domain spoofing &amp;mdash; where ad inventory is misrepresented as being from a different site &amp;mdash; is often talked about as a solved problem by adtech insiders. Despite this, &lt;a href="https://www.usatoday.com/" rel="noopener noreferrer"&gt;USA Today&lt;/a&gt; and &lt;a href="https://www.gannett.com/brands/" rel="noopener noreferrer"&gt;hundreds of local newspapers&lt;/a&gt; owned by &lt;a href="https://www.gannett.com/" rel="noopener noreferrer"&gt;Gannett&lt;/a&gt; were sending spoofed bid requests to multiple ad exchanges for over 9 months.&lt;/p&gt;</summary><content type="html">&lt;div class="admonition collab"&gt;
&lt;p&gt;This research was done in collaboration with &lt;a href="https://twitter.com/kfranasz"&gt;Krzysztof Franaszek&lt;/a&gt;.
Read &lt;a href="https://adalytics.io/blog/checking-page-data-in-ad-requests" rel="noopener noreferrer"&gt;his post here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Domain spoofing &amp;mdash; where ad inventory is misrepresented as being from a different site &amp;mdash; is often talked about as a solved problem by adtech insiders. Despite this, &lt;a href="https://www.usatoday.com/" rel="noopener noreferrer"&gt;USA Today&lt;/a&gt; and &lt;a href="https://www.gannett.com/brands/" rel="noopener noreferrer"&gt;hundreds of local newspapers&lt;/a&gt; owned by &lt;a href="https://www.gannett.com/" rel="noopener noreferrer"&gt;Gannett&lt;/a&gt; were sending spoofed bid requests to multiple ad exchanges for over 9 months.&lt;/p&gt;
&lt;p&gt;The various companies involved didn&amp;rsquo;t appear to notice this behaviour &amp;mdash; or didn&amp;rsquo;t act to resolve it if they did &amp;mdash; until late last week when it suddenly stopped.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_spoofing-solved.png"&gt;&lt;img alt="Tweet reads: &amp;quot;You ask what prevents an intermediary account holder from spoofing a site? This is table stakes on the web for anti-fraud vendors. Web spoofing effectively ended with the introduction of ads.txt. In 2018, almost all spoofing moved to in-app due to a lack of ads.txt (at the time).&amp;quot;" src="https://braedon.dev/images/a_tech/gannett-spoofing_spoofing-solved.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
A tweet from a senior engineer at a major DSP.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The primary weapon against domain spoofing is the &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt standard&lt;/a&gt; from &lt;a href="https://iabtechlab.com/" rel="noopener noreferrer"&gt;IAB Tech Lab&lt;/a&gt;. This allows a site to authorise specific ad accounts to sell its inventory, preventing other accounts from spoofing it. But &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;ads.txt has its limitations&lt;/a&gt;, and one is that it only protects against domain spoofing by unauthorized accounts. What if the spoofing is coming from inside the house?&lt;/p&gt;
&lt;p&gt;Gannett owns a large network of newspaper sites that share a set of DIRECT ad accounts &amp;mdash; everything from &lt;a href="https://well-known.dev/resources/ads_txt/compare?domain=usatoday.com&amp;amp;domain=wisconsinrapidstribune.com#result" rel="noopener noreferrer"&gt;USA Today to the Wisconsin Rapids Tribune&lt;/a&gt;. As they&amp;rsquo;re the &amp;ldquo;publisher&amp;rdquo; for all these sites, technically they&amp;rsquo;re allowed to do this &amp;mdash; the accounts aren&amp;rsquo;t considered mislabelled.&lt;/p&gt;
&lt;p&gt;However, the shared accounts are authorized to sell inventory for all the sites, so they can theoretically also spoof inventory for any of the sites without failing ads.txt validations. This kind of &amp;ldquo;&lt;a href="https://braedon.dev/2021/adspecs-1.html#authorized-spoofing"&gt;authorized spoofing&lt;/a&gt;&amp;rdquo; is exactly what appeared to be happening until Friday the 4th of March 2022.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to speculate as to whether this spoofing was deliberate on Gannett&amp;rsquo;s part, or if they derived any benefit from it. Instead, I want to focus on how the spoofing worked, and the implications of it.&lt;/p&gt;
&lt;h2 id="finding-the-spoofing"&gt;&lt;a class="greyLink" href="#finding-the-spoofing"&gt;Finding the Spoofing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Gannett sites use &lt;a href="https://adprofs.co/beginners-guide-to-header-bidding/" rel="noopener noreferrer"&gt;header bidding&lt;/a&gt; to run ad auctions on different exchanges when you load a page. Scripts running in your browser make the requests that trigger those auctions, so it&amp;rsquo;s possible to inspect the requests your browser sends to see how Gannett is representing their ad inventory. In September 2021 I noticed that the domains and page URLs included in some of those requests didn&amp;rsquo;t seem to match the actual page being loaded.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at the &lt;a href="https://freep.com" rel="noopener noreferrer"&gt;Detroit Free Press&lt;/a&gt;, a local newspaper owned by Gannett. I loaded this &lt;a href="https://www.freep.com/story/news/local/michigan/2022/02/01/160-dogs-found-blighted-rural-michigan-property/9298848002/" rel="noopener noreferrer"&gt;local news article about mistreated dogs&lt;/a&gt; on the 17th of February 2022.&lt;/p&gt;
&lt;div class="inlineGallery"&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_actual-article.png"&gt;&lt;img alt="Screenshot of a Detroit Free Press article. Title reads: &amp;quot;More than 160 dogs found on blighted property in northern Michigan&amp;quot;." src="https://braedon.dev/images/a_tech/gannett-spoofing_actual-article.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The actual article on the Detroit Free Press.
&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_spoofed-article.png"&gt;&lt;img alt="Screenshot of a USA Today article. Title reads: &amp;quot;Purdy throws for 3 TDs, No. 14 Iowa State routs UNLV 48-3&amp;quot;." src="https://braedon.dev/images/a_tech/gannett-spoofing_spoofed-article.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The spoofed article on USA Today.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Header bidding requests to multiple ad exchanges, such as Pubmatic and IndexExchange, reported the page as a &lt;a href="https://www.usatoday.com/story/sports/ncaaf/2021/09/19/purdy-throws-for-3-tds-no-14-iowa-state-routs-unlv-48-3/49093243/" rel="noopener noreferrer"&gt;USA Today college football article&lt;/a&gt;. That looks a whole lot like domain spoofing.&lt;/p&gt;
&lt;div class="inlineGallery"&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_pubmatic-request.png"&gt;&lt;img alt="Screenshot of Chrome developer tools on a freep.com page, showing a request to hbopenbid.pubmatic.com. The &amp;quot;page&amp;quot; field in the request payload is highlighted --- its value is the URL of an article on usatoday.com." src="https://braedon.dev/images/a_tech/gannett-spoofing_pubmatic-request.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
A header bidding request to Pubmatic.
&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_indexexchange-request.png"&gt;&lt;img alt="Screenshot of Chrome developer tools on a freep.com page, showing a request to htlb.casalemedia.com. A JSON object in the request payload is highlighted --- it contains a &amp;quot;page&amp;quot; field where value is the URL of an article on usatoday.com." src="https://braedon.dev/images/a_tech/gannett-spoofing_indexexchange-request.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
A header bidding request to IndexExchange.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A search of the page&amp;rsquo;s source code shows where the spoofed URL is coming from &amp;mdash; a minified inline script. With the help of a javascript formatter we can more easily see the offending code.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_article-source.png"&gt;&lt;img alt="Screenshot of the source code for the Detroit Free Press article. A usatoday.com URL is highlighted." src="https://braedon.dev/images/a_tech/gannett-spoofing_article-source.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Source code of the actual article.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_article-source-formatted.png"&gt;&lt;img alt="Screenshot of a formatted version of a section of the article source code. An object called &amp;quot;pbjs&amp;quot; is being constructed. A &amp;quot;setConfig&amp;quot; function is called, passing in a large data object that includes the usatoday.com article URL." src="https://braedon.dev/images/a_tech/gannett-spoofing_article-source-formatted.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Part of the inline script, formatted.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;code&gt;pbjs&lt;/code&gt; stands for &lt;a href="https://prebid.org/product-suite/prebid-js/" rel="noopener noreferrer"&gt;Prebid.js&lt;/a&gt;, a JavaScript library that&amp;rsquo;s commonly used to implement header bidding. The &lt;code&gt;a.setConfig({...})&lt;/code&gt; method call is used to configure Prebid, and the &lt;code&gt;ortb2&lt;/code&gt; &lt;a href="https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#first-party-data" rel="noopener noreferrer"&gt;configuration field&lt;/a&gt; provides &lt;a href="https://docs.prebid.org/features/firstPartyData.html" rel="noopener noreferrer"&gt;data about the inventory being sold&lt;/a&gt; in &lt;a href="https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf" rel="noopener noreferrer"&gt;OpenRTB 2.5 format&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In OpenRTB, the &lt;code&gt;site&lt;/code&gt; field should contain data about the page the ad will be shown on. So why was Gannett providing data about a totally different page?&lt;/p&gt;
&lt;p&gt;Further, it wasn&amp;rsquo;t only the domain and page being spoofed. Data about the article section and subsection, keywords, and brand safety was also being provided based on the spoofed page, not the actual page. This spoofed data was all showing up in requests to affected exchanges.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/gannett-spoofing_ortb2-site-docs.png"&gt;&lt;img alt="Screenshot of documentation for the site field in OpenRTB 2.5. Description of the domain field: &amp;quot;Domain of the site&amp;quot;. Description of the page field: &amp;quot;URL of the page where the impression will be shown&amp;quot;." src="https://braedon.dev/images/a_tech/gannett-spoofing_ortb2-site-docs.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Definition of fields in the &lt;code&gt;site&lt;/code&gt; object from the &lt;a href="https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf" rel="noopener noreferrer"&gt;OpenRTB 2.5 spec&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The mapping between actual pages and spoofed pages in the Prebid config seemed to be cached. Loading a given page multiple times within a short period, or from different browsers or computers, usually yielded the same spoofed page. The mappings did eventually change after some period of time &amp;mdash; presumably after the page expired from the cache.&lt;/p&gt;
&lt;p&gt;It is important to note that the spoofed data didn&amp;rsquo;t show up in requests to all exchanges. While some exchanges were only getting spoofed page data, others got actual page data, or a mixture of the two.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s because each exchange has its own Prebid adapter that constructs requests from available data. It&amp;rsquo;s up to these adapters to decide how to use the &lt;code&gt;ortb2&lt;/code&gt; field from the Prebid config, and some didn&amp;rsquo;t end up incorporating the spoofed data.&lt;/p&gt;
&lt;p&gt;Similarly, exchanges that were sent spoofed data may not have passed it on to advertisers. To test this, Krzysztof Franaszek of &lt;a href="https://adalytics.io/" rel="noopener noreferrer"&gt;Adalytics&lt;/a&gt; examined ads served in response to header bidding requests that included spoofed data. He found evidence suggesting &lt;a href="https://adalytics.io/blog/checking-page-data-in-ad-requests" rel="noopener noreferrer"&gt;advertisers were bidding on spoofed ad inventory via multiple exchanges&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="scoping-the-problem"&gt;&lt;a class="greyLink" href="#scoping-the-problem"&gt;Scoping the Problem&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Based on archived versions of the USA Today homepage on &lt;a href="https://archive.org/web/" rel="noopener noreferrer"&gt;The Internet Archive&amp;rsquo;s Wayback Machine&lt;/a&gt;, the &lt;code&gt;ortb2&lt;/code&gt; field was first added to the Prebid config sometime between &lt;a href="https://web.archive.org/web/20210525151505/https://www.usatoday.com/" rel="noopener noreferrer"&gt;11:15am&lt;/a&gt; and &lt;a href="https://web.archive.org/web/20210525212248/https://www.usatoday.com/" rel="noopener noreferrer"&gt;5:22pm&lt;/a&gt; EDT on the 25th of May 2021.&lt;/p&gt;
&lt;p&gt;That first observed &lt;code&gt;ortb2&lt;/code&gt; field contained data for the article &amp;ldquo;&lt;a href="https://www.cantonrep.com/story/news/local/arizona-weather/2019/11/29/arizona-has-seen-worst-its-winter-weather-now/4333587002/" rel="noopener noreferrer"&gt;Arizona has seen the worst of its winter weather &amp;mdash; for now&lt;/a&gt;&amp;rdquo; from &lt;a href="https://www.cantonrep.com/" rel="noopener noreferrer"&gt;Canton Repository&lt;/a&gt; &amp;mdash; i.e. the data was spoofed right from the start.&lt;/p&gt;
&lt;p&gt;The USA Today homepage started consistently including correct data in the &lt;code&gt;ortb2&lt;/code&gt; field sometime between &lt;a href="https://web.archive.org/web/20220304141609/https://www.usatoday.com/" rel="noopener noreferrer"&gt;9:16am&lt;/a&gt; and &lt;a href="https://web.archive.org/web/20220304193721/https://www.usatoday.com/" rel="noopener noreferrer"&gt;2:37pm&lt;/a&gt; EST on the 4th of March 2022.&lt;/p&gt;
&lt;p&gt;In the months since I noticed the spoofing I&amp;rsquo;ve run dozens of scans checking thousands of articles on Gannett sites to see how widespread the issue was. These scans excluded paywalled articles and a small number of special features that have different ad setups, but all public &amp;ldquo;regular&amp;rdquo; articles &amp;mdash; ones where the path starts with &lt;code&gt;/story/&lt;/code&gt; &amp;mdash; were candidates.&lt;/p&gt;
&lt;p&gt;The last scan completed before the spoofing stopped was run on the 3rd of March 2022, and checked articles listed on the homepages of Gannett sites. Of 6,983 articles checked across 275 sites, the domain in the Prebid config was different to the actual domain 99.46% of the time. The page URL in the Prebid config was different to the actual page URL 99.99% of the time. Only a single page wasn&amp;rsquo;t spoofed.&lt;/p&gt;
&lt;p&gt;These results are consistent with the many other scans I ran. The rare cases where a page wasn&amp;rsquo;t spoofed were so infrequent as to likely be flukes &amp;mdash; i.e. the spoofed page happened to match the actual page.&lt;/p&gt;
&lt;p&gt;There didn&amp;rsquo;t appear to be any relationship between the actual and spoofed pages. However, there was a clear pattern to which domains were spoofed. In this scan, spoofed pages were from USA Today 19.05% of the time. The next most common domain was the AZ Central at 2.36%, with other domains decreasing from there.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the scan&amp;rsquo;s top 10 spoofed domains, how many of their articles were checked, how often they were spoofed, and their spoof frequency:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Actual&lt;/th&gt;
&lt;th&gt;Spoofed&lt;/th&gt;
&lt;th&gt;Spoof Freq.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;usatoday.com&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;1330&lt;/td&gt;
&lt;td&gt;19.05%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;azcentral.com&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;165&lt;/td&gt;
&lt;td&gt;2.36%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;desmoinesregister.com&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;1.79%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;heraldtribune.com&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;1.45%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;delawareonline.com&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;1.32%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app.com&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;88&lt;/td&gt;
&lt;td&gt;1.26%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;theledger.com&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;1.16%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;freep.com&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;1.12%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seacoastonline.com&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;76&lt;/td&gt;
&lt;td&gt;1.09%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dispatch.com&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;td&gt;1.05%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Once again, these results are consistent with other scans done on other days, including ones using different methods of sampling articles, e.g. selecting up to 25 articles from each day of a month for each site, or all articles from a single site for a whole year.&lt;/p&gt;
&lt;p&gt;USA Today was always the most frequently spoofed domain by a wide margin. It was typically spoofed on 20% of checked articles, plus or minus a few percentage points.&lt;/p&gt;
&lt;h2 id="the-impact"&gt;&lt;a class="greyLink" href="#the-impact"&gt;The Impact&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Gannett&amp;rsquo;s ad inventory was being misrepresented to advertisers using affected exchanges for over 9 months.&lt;/p&gt;
&lt;p&gt;This might not be a concern for programmatic campaigns that purely target users, but most advertisers do care about the sites and content their ads end up on to some degree or another.&lt;/p&gt;
&lt;p&gt;If you thought you had bought ad space on USA Today, would you be ok with your ad actually displaying on Detroit Free Press? As of writing, USA Today is ranked #189 on the &lt;a href="https://tranco-list.eu/" rel="noopener noreferrer"&gt;Tranco list&lt;/a&gt; of top sites. Detroit Free Press is #1,983. How about another Gannett site that was spoofed a handful of times in each scan, &lt;a href="https://www.galesburg.com" rel="noopener noreferrer"&gt;The Galesburg Register Mail&lt;/a&gt;? It&amp;rsquo;s #98,198. A significant proportion of Gannett&amp;rsquo;s sites don&amp;rsquo;t even make the top 100,000.&lt;/p&gt;
&lt;p&gt;Is ad space on an article about animal neglect in northern Michigan the same as ad space on a college football article? Not if you&amp;rsquo;re trying to reach sports fans, for example. Then there&amp;rsquo;s brand safety and suitability concerns &amp;mdash; I suspect certain brands would not be happy to be placed next to the animal neglect article.&lt;/p&gt;
&lt;h2 id="the-big-picture"&gt;&lt;a class="greyLink" href="#the-big-picture"&gt;The Big Picture&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is unlikely to be the only case of this kind of authorized spoofing in the wild. Exchanges, DSPs, and anti-fraud vendors need to take a good look at why it seemingly went undetected for so long, and where else it might be happening.&lt;/p&gt;
&lt;p&gt;Part of what allowed Gannett&amp;rsquo;s ad inventory to be spoofed is their use of shared DIRECT accounts &amp;mdash; if the sites didn&amp;rsquo;t share accounts the spoofing could have been detected by buyers when validating the inventory against ads.txt files.&lt;/p&gt;
&lt;p&gt;Many other multi-site publishers have similar setups, and even more sales houses and other adtech intermediaries regularly mislabel their accounts as DIRECT across large networks of sites. Any of them could be engaging in spoofing &amp;mdash; accidentally or otherwise &amp;mdash; that won&amp;rsquo;t be caught by ads.txt validations.&lt;/p&gt;
&lt;p&gt;Updating the &lt;a href="https://braedon.dev/2021/adspecs-1.html#a-better-definition-of-direct"&gt;definition of DIRECT&lt;/a&gt; in the ads.txt spec to close the multi-site publisher loophole, along with &lt;a href="https://braedon.dev/2021/adspecs-1.html#the-benefits"&gt;enforcing it to stamp out mislabelling&lt;/a&gt;, would make it easier to detect this kind of authorized domain spoofing (or at least make it harder to implement).&lt;/p&gt;
&lt;p&gt;Finally, it would be helpful if certain segments of the adtech industry were a little more cautious about unfurling the &amp;ldquo;Mission Accomplished&amp;rdquo; banner.&lt;/p&gt;</content><category term="adtech"></category><category term="domain-spoofing"></category><category term="ads.txt"></category></entry><entry><title>Ad Specs Part 2: Sellers and Supply Chains</title><link href="https://braedon.dev/2021/adspecs-2.html" rel="alternate"></link><published>2021-10-18T22:00:00+08:00</published><updated>2021-10-18T22:00:00+08:00</updated><author><name></name></author><id>tag:braedon.dev,2021-10-18:/2021/adspecs-2.html</id><summary type="html">&lt;p&gt;In the previous post I covered the ads.txt standard, and proposed a change to the definition of DIRECT to enable the industry to clean up mislabelled accounts and help tackle domain spoofing.&lt;br&gt;
&lt;br&gt;
But it&amp;rsquo;s been over 4 years since ads.txt was released, and in the meantime it&amp;rsquo;s been joined by a pair of newer standards &amp;mdash; sellers.json and SupplyChain object. Let&amp;rsquo;s take a look at these standards, and how they fit in with the proposed ads.txt update.&lt;/p&gt;</summary><content type="html">&lt;div class="admonition series"&gt;
&lt;p&gt;This is part 2 in a series on IAB Tech Lab adtech standards.
Read &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;part 1 here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In the &lt;a href="https://braedon.dev/2021/adspecs-1.html"&gt;previous post&lt;/a&gt; I covered the &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt&lt;/a&gt; standard, proposing that the account relationship field be re-defined so that DIRECT accounts could only be used on a single site. This change would enable the industry to clean up mislabelled accounts and help tackle domain spoofing.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s been over 4 years since ads.txt was released, and in the meantime it&amp;rsquo;s been joined by a pair of newer standards &amp;mdash; &lt;a href="https://iabtechlab.com/sellers-json/" rel="noopener noreferrer"&gt;sellers.json&lt;/a&gt; and &lt;a href="https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md" rel="noopener noreferrer"&gt;SupplyChain object&lt;/a&gt;. Let&amp;rsquo;s take a look at these standards, and how they fit in with the proposed ads.txt update.&lt;/p&gt;
&lt;h2 id="the-sellersjson-specification"&gt;&lt;a class="greyLink" href="#the-sellersjson-specification"&gt;The Sellers.json Specification&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ads.txt exposes what accounts are authorized to sell a site&amp;rsquo;s inventory, but very little about the accounts themselves.&lt;/p&gt;
&lt;p&gt;In July 2019 the IAB Tech Lab released the &lt;a href="https://iabtechlab.com/sellers-json/" rel="noopener noreferrer"&gt;sellers.json&lt;/a&gt; standard. Where ads.txt is quite limited in its focus &amp;mdash; tackling domain spoofing &amp;mdash; sellers.json has more nebulous goals. It exposes extra information about the accounts used to sell ad inventory, in service of a &amp;ldquo;transparent marketplace&amp;rdquo;.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-abstract.png"&gt;&lt;img alt="Screenshot of a paragraph under the title &amp;quot;Abstract&amp;quot;. Paragraph reads: &amp;quot;As part of a broader effort to eliminate the ability to profit from counterfeit inventory in the open digital advertising ecosystem, Sellers.json provides a mechanism to enable buyers to discover who the entities are that are either direct sellers of or intermediaries in the selling of digital advertising.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-abstract.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The abstract section of the sellers.json spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-audience.png"&gt;&lt;img alt="Screenshot of a paragraph under the title &amp;quot;Audience&amp;quot;. Paragraph reads: &amp;quot;Advertising systems, whether they are sellers or buyers of programmatic advertising both benefit from a transparent marketplace where all parties to the transaction are well understood. This document serves to define the information that sellers will provide to both downstream sellers and buyers of programmatic inventory.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-audience.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The audience section of the sellers.json spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Sellers.json files are hosted by &amp;ldquo;ad systems&amp;rdquo; (sales houses, SSPs, ad exchanges, etc.), and list details of all the accounts used to sell ad inventory via each system.&lt;/p&gt;
&lt;p&gt;These accounts are the same as the accounts listed in ads.txt files. In theory, the details for any account in an ads.txt should be able to be looked up in the relevant ad system&amp;rsquo;s sellers.json file.&lt;/p&gt;
&lt;p&gt;The core information provided is the name of the company that is paid when inventory is sold via the account, along with its domain if it has one. Accounts can be marked as &amp;ldquo;confidential&amp;rdquo;, in which case these fields are omitted.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-company-details.png"&gt;&lt;img alt="Screenshot of the definitions of the &amp;quot;name&amp;quot; and &amp;quot;domain&amp;quot; fields. Name: &amp;quot;The name of the company (the legal entity) that is paid for inventory that is transacted under the given seller_id. Can be omitted only when is_confidential is set to 1.&amp;quot; Domain: &amp;quot;The business domain name of the company (the legal entity) that is paid for inventory that is transacted under the given seller_id. When the seller_type property is set to INTERMEDIARY or BOTH, this should be the root domain name of the seller’s Sellers.json file. Can be omitted when is_confidential is set to 1 or when the seller doesn’t have a web presence.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-company-details.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definitions of the name and domain fields in the sellers.json spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Each account also has a &amp;ldquo;type&amp;rdquo;. If the company getting paid by the ad system (i.e. listed in the name and domain fields) owns the inventory being sold, it&amp;rsquo;s a PUBLISHER account. If the inventory is owned by a different company, it&amp;rsquo;s an INTERMEDIARY account. BOTH accounts sell both types of inventory.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-seller-type.png"&gt;&lt;img alt="Screenshot of the definition of the &amp;quot;seller_type&amp;quot; field. &amp;quot;An enumeration of the type of account, either PUBLISHER, INTERMEDIARY, or BOTH. A value of &amp;quot;PUBLISHER&amp;quot; indicates that the inventory sold through this account is on a site, app, or other medium owned by the named entity and the advertising system pays them directly. A value of “INTERMEDIARY&amp;quot; indicates that the inventory sold through this account is not owned by the named entity or the advertising system does not pay them directly. 'BOTH' indicates that both types of inventory are transacted by this seller. Note that this field should be treated as case insensitive when interpreting the data.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_sellersjson-seller-type.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of the seller_type field in the sellers.json spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;PUBLISHER and INTERMEDIARY seem quite similar to DIRECT and RESELLER from ads.txt, but the definitions are based on different concepts &amp;mdash; payment vs. control &amp;mdash; so they don&amp;rsquo;t always align.&lt;/p&gt;
&lt;p&gt;A small example sellers.json file for a fictional ad exchange:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contact_email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;admin@exchange1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contact_address&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Exchange One Inc., 1 Queen St, London, United Kingdom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sellers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Publisher One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;publisher1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PUBLISHER&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Sales House One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;saleshouse1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;INTERMEDIARY&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SSP One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ssp1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;INTERMEDIARY&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ekki&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Exchange Two&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exchange2.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;INTERMEDIARY&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="the-supplychain-object-specification"&gt;&lt;a class="greyLink" href="#the-supplychain-object-specification"&gt;The SupplyChain Object Specification&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ad buyers have traditionally only been able to see the account they are buying off &amp;mdash; the &amp;ldquo;last seller&amp;rdquo;. When buying direct, it&amp;rsquo;s this last seller account that needs to be DIRECT.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md" rel="noopener noreferrer"&gt;SupplyChain object&lt;/a&gt; OpenRTB extension was released alongside sellers.json. It adds a list of upstream accounts to bid requests, enabling buyers to see the other accounts the inventory has passed through. For &amp;ldquo;complete&amp;rdquo; SupplyChains, this list starts all the way back at the &amp;ldquo;first seller&amp;rdquo; &amp;mdash; the account of the site owner.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_supplychain-introduction.png"&gt;&lt;img alt="Screenshot of a paragraph under the title &amp;quot;Introduction&amp;quot;. Paragraph reads: &amp;quot;Ads.txt has been extremely successful in allowing publishers and app makers to define who is authorized to sell a given set of impressions via the programmatic marketplace. Ads.txt does not however make any attempt at revealing or authorizing all parties that are part of the transacting of those impressions. This information can be important to buyers for a number of reasons including transparency of the supply chain, ensuring that all intermediaries are entities with which the buyer wants to transact and that inventory is purchased as directly as possible. The implementation should be as transparent as possible to buyers. It should enable them to easily understand who it is that is participating in the sale of any piece of inventory.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_supplychain-introduction.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The introduction section of the SupplyChain object spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Once again, these are the same accounts as those in ads.txt and sellers.json files. Any account in a SupplyChain object should be authorized in the site&amp;rsquo;s ads.txt, and be listed in a sellers.json file.&lt;/p&gt;
&lt;p&gt;An example SupplyChain object for an RTB request on our fictional ad exchange:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ver&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;complete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ssp1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;123&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exchange1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="scenarios"&gt;&lt;a class="greyLink" href="#scenarios"&gt;Scenarios&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now we&amp;rsquo;ve covered what sellers.json and SupplyChain objects are, let&amp;rsquo;s take a look at how they interact with the proposed ads.txt update. I&amp;rsquo;ll focus on two scenarios that are affected by the new definition of DIRECT.&lt;/p&gt;
&lt;h3 id="sales-houses"&gt;&lt;a class="greyLink" href="#sales-houses"&gt;Sales Houses&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Sites that use a sales house to sell their inventory often list all the sales house&amp;rsquo;s accounts with downstream ad systems as DIRECT. This wouldn&amp;rsquo;t be allowed under the updated definition.&lt;/p&gt;
&lt;p&gt;The site must list the sales house&amp;rsquo;s accounts with downstream ad systems as RESELLER. The sales house should create a dedicated PUBLISHER account for the site in its sellers.json, with the domain set to the site domain. The site can then list their account with the sales house as DIRECT.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;saleshouse1.com/sellers.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contact_email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;admin@saleshouse1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sellers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1111&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Site One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;site1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PUBLISHER&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;site1.com/ads.txt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;saleshouse1.com, 1111, DIRECT
exchange1.com, bar, RESELLER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Site One SupplyChain object:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ver&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;complete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;saleshouse1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1111&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exchange1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that while this is a change from how many sales houses are set up currently, it&amp;rsquo;s actually what they should be doing already. This was confirmed by a representative of the IAB Tech Lab in response to the previous post. The new definition of DIRECT simply clarifies this scenario.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-2_shails-direct-definition.png"&gt;&lt;img alt="Screenshot of two tweets from @shails that read: &amp;quot;Isn’t the spec pretty clear the publisher must control the account that is as a business it must be the account owner&amp;quot;, and &amp;quot;Your SSP’s account or someone exclusively managing your inventory cannot be direct is pretty clear. What’s needed is that publisher does not lie and seller due diligence about site ownership&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-2_shails-direct-definition.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Tweets from the SVP, Product Management &amp;amp; Global Programs at IAB Tech Lab.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="multi-site-publishers"&gt;&lt;a class="greyLink" href="#multi-site-publishers"&gt;Multi-Site Publishers&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Publishers that own multiple sites often have a single set of accounts with downstream ad systems that are listed as DIRECT by all the sites. This wouldn&amp;rsquo;t be allowed under the updated definition. To keep using these shared accounts, the publisher would need to act as an ad system.&lt;/p&gt;
&lt;p&gt;Each site must list the publisher&amp;rsquo;s accounts with downstream ad systems as RESELLER. The publisher should create a sellers.json containing a PUBLISHER account for each site, with the domains set appropriately. The sellers.json must be hosted on the domain used in the publisher&amp;rsquo;s accounts. Each site can then list their account with the publisher as DIRECT.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;publisher1.com/sellers.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;contact_email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;admin@publisher1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sellers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aaaa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Site A&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;site-a.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PUBLISHER&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bbbb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Site B&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;domain&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;site-b.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;seller_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PUBLISHER&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;site-a.com/ads.txt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;publisher1.com, aaaa, DIRECT
exchange1.com, foo, RESELLER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Site A SupplyChain object:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ver&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;complete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;publisher1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aaaa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exchange1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;site-b.com/ads.txt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;publisher1.com, bbbb, DIRECT
exchange1.com, foo, RESELLER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Site B SupplyChain object:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ver&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;complete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;publisher1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bbbb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;asi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;exchange1.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;sid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;hp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="supply-path-optimisation"&gt;&lt;a class="greyLink" href="#supply-path-optimisation"&gt;Supply Path Optimisation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These account labelling changes will reduce the number of sites with DIRECT last seller accounts. This could result in a significant shift in ad supply and demand if buyers continue to prioritise buying direct.&lt;/p&gt;
&lt;p&gt;If these buyers legitimately don&amp;rsquo;t want to buy from any intermediary, then this would simply be buyers actually getting what they thought they were buying all along. But it&amp;rsquo;s possible many buyers would be OK with certain indirect paths, if they could target them.&lt;/p&gt;
&lt;p&gt;Buying direct is effectively using the ads.txt relationship field for a type of Supply Path Optimisation (SPO). But it&amp;rsquo;s a binary field &amp;mdash; paths are direct or indirect. It just isn&amp;rsquo;t a good tool for the job, regardless of how it&amp;rsquo;s defined.&lt;/p&gt;
&lt;p&gt;The SupplyChain object is clearly a better tool for SPO. With it, a buyer can check that all the accounts are authorized in the site&amp;rsquo;s ads.txt, not just the last seller. They can check the first seller is DIRECT. They can look them up in sellers.json files to see who the intermediaries are, who the first seller was, and determine whether they trust them.&lt;/p&gt;
&lt;p&gt;You get the picture. SupplyChain objects, combined with data from sellers.json and ads.txt files, enable far more sophisticated SPO than the ads.txt relationship field ever could. With this kind of SPO, the importance of the last seller account being DIRECT is significantly reduced. A valid SupplyChain with trustworthy intermediaries could be just as valuable as a DIRECT account, depending on the buyer.&lt;/p&gt;
&lt;p&gt;We should be aiming to get buyers using SupplyChain, rather than worrying about whether sites can be bought direct.&lt;/p&gt;
&lt;h2 id="is-direct-needed"&gt;&lt;a class="greyLink" href="#is-direct-needed"&gt;Is DIRECT Needed?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point, you may be wondering if it&amp;rsquo;s worth updating the definition of DIRECT at all. If buyers should be checking SupplyChains rather than buying direct, does DIRECT mislabelling matter? Do we need the ads.txt relationship field?&lt;/p&gt;
&lt;p&gt;If ads.txt was still being drafted, I think there&amp;rsquo;d be a good argument for simply not including the relationship field. But ads.txt has been in the wild for 4 years, and the relationship field is being actively used by buyers. That&amp;rsquo;s not going to change overnight.&lt;/p&gt;
&lt;p&gt;Using SupplyChain for SPO is not something new I&amp;rsquo;m proposing &amp;mdash; that&amp;rsquo;s what it was designed for, and it was released over two years ago. Buyers are going to keep buying direct for some time yet, and I think it&amp;rsquo;s important to make sure they start getting what they&amp;rsquo;ve been paying for.&lt;/p&gt;
&lt;p&gt;Even once using SupplyChains is standard and the direct/indirect binary is a thing of the past, buyers will need to validate those SupplyChains against information from sellers.json and ads.txt files. With its updated definition, the ads.txt relationship field provides information that isn&amp;rsquo;t available elsewhere: whether the account is specific to a site. This information is important for assessing the risk of domain spoofing by authorized accounts.&lt;/p&gt;
&lt;p&gt;Sellers.json focuses on who gets paid for inventory, not what site it&amp;rsquo;s from. It could be updated to incorporate this information &amp;mdash; something I think we should consider &amp;mdash; but that is a much bigger change.&lt;/p&gt;
&lt;h2 id="a-way-forward"&gt;&lt;a class="greyLink" href="#a-way-forward"&gt;A Way Forward&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DIRECT mislabelling has been a long standing issue with ads.txt. Cleaning it up is essential to weeding out fraud, and building a level playing field for legitimate publishers.&lt;/p&gt;
&lt;p&gt;Narrowing the definition of DIRECT to enable this clean-up will impact some sites, but only while buying direct remains a prominent strategy. SupplyChain objects, paired with sellers.json and ads.txt, give buyers the data required to move away from this reliance.&lt;/p&gt;
&lt;p&gt;Transparent, accurate supply chains are better for both advertisers and publishers. If you&amp;rsquo;re an advertiser, talk to your agency/DSP about utilizing SupplyChain object data in your campaigns. If you&amp;rsquo;re a publisher, check your ads.txt for mislabelled accounts and develop a plan for correcting them.&lt;/p&gt;
&lt;p&gt;Changes like this won&amp;rsquo;t happen overnight, but the sooner we start, the better.&lt;/p&gt;</content><category term="adtech"></category><category term="adspecs"></category><category term="ads.txt"></category><category term="sellers.json"></category><category term="supply-chain"></category></entry><entry><title>Ad Specs Part 1: Ads.txt Ambiguity</title><link href="https://braedon.dev/2021/adspecs-1.html" rel="alternate"></link><published>2021-10-04T22:00:00+08:00</published><updated>2021-10-04T22:00:00+08:00</updated><author><name></name></author><id>tag:braedon.dev,2021-10-04:/2021/adspecs-1.html</id><summary type="html">&lt;p&gt;Programmatic advertising is a massive, complicated, and largely opaque industry. Thousands of companies buy and sell ad space across the web in real-time auctions, determining what ads you see and how much publishers get paid.&lt;br&gt;
&lt;br&gt;
The &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt&lt;/a&gt; and &lt;a href="https://iabtechlab.com/sellers-json/" rel="noopener noreferrer"&gt;sellers.json&lt;/a&gt; standards from the IAB Tech Lab have been touted as tools to provide much needed transparency, but problems with the interpretation, implementation, and enforcement of the standards have blunted their impact.&lt;br&gt;
&lt;br&gt;
This is the first in a series of posts diving into these standards and their problems, and suggesting some potential solutions (or at least improvements).&lt;/p&gt;</summary><content type="html">&lt;p&gt;Programmatic advertising is a massive, complicated, and largely opaque industry. Thousands of companies buy and sell ad space across the web in real-time auctions, determining what ads you see and how much publishers get paid.&lt;/p&gt;
&lt;p&gt;This system funds a large proportion of the web as we know it, but has produced a variety of harms along the way; from the defunding of journalism in favour of clickbait and disinformation, to encouraging and facilitating ever more invasive user tracking, to the prevalence of outright ad fraud.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;ads.txt&lt;/a&gt; and &lt;a href="https://iabtechlab.com/sellers-json/" rel="noopener noreferrer"&gt;sellers.json&lt;/a&gt; standards from the IAB Tech Lab have been touted as tools to provide much needed transparency and help tackle some of these issues, but problems with the interpretation, implementation, and enforcement of the standards have blunted their impact.&lt;/p&gt;
&lt;p&gt;This is the first in a series of posts diving into these standards and their problems, and suggesting some potential solutions (or at least improvements).&lt;/p&gt;
&lt;h2 id="the-adstxt-specification"&gt;&lt;a class="greyLink" href="#the-adstxt-specification"&gt;The Ads.txt Specification&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The obvious place to start is with the &lt;a href="https://iabtechlab.com/ads-txt/" rel="noopener noreferrer"&gt;oldest standard, ads.txt&lt;/a&gt;. The first version of the ads.txt specification was released in June 2017, and it has had 3 minor revisions since then. The latest is v1.0.3, released in March 2021.&lt;/p&gt;
&lt;p&gt;Its stated goal is to tackle domain spoofing &amp;mdash; a type of ad fraud where someone sells ad inventory (ad space) claiming it&amp;rsquo;s for one site, but the buyer&amp;rsquo;s ad is actually displayed on a different site. (Yes, most details about ad inventory are self-declared by the seller, including the domain the inventory is on.)&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_adstxt-purpose.png"&gt;&lt;img alt="Screenshot of a paragraph under the title &amp;quot;2. Introduction&amp;quot;. Paragraph reads: &amp;quot;Fraud can come in various forms, here we are concentrating on the form wherein ad inventory is being offered to buyers with a misrepresented label and account during the real-time bidding process. Typically the domain of the webpage, or the ID of the mobile app has been falsified to look like a site or app they do not have authorization to sell.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_adstxt-purpose.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The introduction section of the ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Ads.txt addresses this problem by getting publishers to add a plaintext file (called ads.txt) to their site listing all the ad accounts that are authorized to sell inventory on that site. Before a buyer bids on ad inventory, they can check that the seller&amp;rsquo;s account is authorized by the relevant site&amp;rsquo;s ads.txt. If it isn&amp;rsquo;t, the domain is probably being spoofed.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of an ads.txt file, from the &lt;a href="https://www.nytimes.com/ads.txt" rel="noopener noreferrer"&gt;New York Times&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;amazon-adsystem.com, 3030, DIRECT
appnexus.com, 3661, DIRECT
google.com, pub-4177862836555934, DIRECT
google.com, pub-9542126426993714, DIRECT
indexexchange.com, 184733, DIRECT
liveintent.com, 130, DIRECT
openx.com, 537145107, DIRECT
openx.com, 539936340, DIRECT
openx.com, 539052954, DIRECT
openx.com, 544071378, DIRECT, 6a698e2ec38604c6
rubiconproject.com, 12330, DIRECT
rubiconproject.com, 17470, DIRECT
triplelift.com, 746, DIRECT
pubmatic.com, 158573, DIRECT, 5d62403b186f2ace
pubmatic.com, 158945, DIRECT, 5d62403b186f2ace
media.net, 8CU2553YN, DIRECT
aol.com, 55861, DIRECT, e1a5b5b6e3255540
yahoo.com, 55861, DIRECT, e1a5b5b6e3255540
aol.com, 55792, DIRECT, e1a5b5b6e3255540
yahoo.com, 55792, DIRECT, e1a5b5b6e3255540
google.com, pub-1793726897772453, DIRECT, f08c47fec0942fa0
aps.amazon.com, 3030, DIRECT
indexexchange.com, 196165, DIRECT, 50b1c356f2c5c8fc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Beyond listing the authorized ad accounts, ads.txt provides another piece of information: the &amp;ldquo;relationship&amp;rdquo; between the publisher and account. This can be &amp;ldquo;DIRECT&amp;rdquo; or &amp;ldquo;RESELLER&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;DIRECT means the &amp;ldquo;&amp;hellip;publisher (content owner) directly controls the account&amp;hellip;&amp;rdquo;. RESELLER means the &amp;ldquo;&amp;hellip;publisher has authorized another entity to&amp;hellip;resell their ad space&amp;hellip;&amp;rdquo;.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_relationship-definition.png"&gt;&lt;img alt="Screenshot of the definition of &amp;quot;Field #3&amp;quot;, named &amp;quot;Type of Account/Relationship&amp;quot;. Description: &amp;quot;(Required) An enumeration of the type of account. A value of 'DIRECT' indicates that the Publisher (content owner) directly controls the account indicated in field #2 on the system in field #1. This tends to mean a direct business contract between the Publisher and the advertising system. A value of 'RESELLER' indicates that the Publisher has authorized another entity to control the account indicated in field #2 and resell their ad space via the system in field #1. Other types may be added in the future. Note that this field should be treated as case insensitive when interpreting the data.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_relationship-definition.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of the relationship field in the ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;That all sounds fairly straightforward, right? If you&amp;rsquo;re a publisher, just add an ads.txt file that lists your own ad accounts as DIRECT, and the accounts of any resellers you work with as RESELLER. However, despite the apparent simplicity, there are at least two major contentious issues with ads.txt.&lt;/p&gt;
&lt;h2 id="authorized-spoofing"&gt;&lt;a class="greyLink" href="#authorized-spoofing"&gt;Authorized Spoofing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When checked by buyers (not a given), ads.txt does prevent spoofing by unauthorized accounts. I can&amp;rsquo;t open an ad account and sell spoofed nytimes.com ad inventory, as my account isn&amp;rsquo;t in their ads.txt. But what if the spoofer &lt;em&gt;is&lt;/em&gt; in the spoofed site&amp;rsquo;s ads.txt?&lt;/p&gt;
&lt;p&gt;Adtech vendors (sales houses, SSPs, resellers, etc.) act as intermediaries for multiple sites, so their ad accounts are authorized by all of them. For example, if a vendor works with a highly prestigious news site that commands high CPMs, what&amp;rsquo;s to stop them spoofing that prestigious site when selling ad inventory from their other sites?&lt;/p&gt;
&lt;p&gt;Checking a site&amp;rsquo;s ads.txt won&amp;rsquo;t help buyers identify this kind of spoofing; the vendor&amp;rsquo;s ad accounts are in the spoofed site&amp;rsquo;s ads.txt, so it is authorized to sell the inventory. The same possibility arises when a publisher owns multiple sites, or colludes with other publishers (i.e. a &lt;a href="https://branded.checkmyads.org/p/so-thats-how-breitbart-is-still-making" rel="noopener noreferrer"&gt;dark pool sales house&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;But let&amp;rsquo;s put a pin in this for a minute, and move on to&amp;hellip;&lt;/p&gt;
&lt;h2 id="account-mislabelling"&gt;&lt;a class="greyLink" href="#account-mislabelling"&gt;Account Mislabelling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ad inventory sold by DIRECT accounts is frequently preferred by buyers. Programmatic ad campaigns can be configured to prioritise buying from DIRECT accounts, or exclude RESELLER accounts entirely.&lt;/p&gt;
&lt;p&gt;Each intermediary between the buyer and the publisher site increases the risk of fraud (e.g. domain spoofing), so &amp;ldquo;buying direct&amp;rdquo; is seen as a way to reduce that risk. It also has the potential to reduce costs by bypassing intermediaries that clip the ticket.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_reseller-fraud-1.png"&gt;&lt;img alt="Screenshot of a tweet that reads: &amp;quot;I used to work in ad fraud, and resellers are full of fraudulent activity to boost their numbers and money, and the blame is often ascribed to the publisher vs the intermediary so they get to just keep on keeping on.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_reseller-fraud-1.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Response to a question on Twitter about why marketers prefer buying direct.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_reseller-fraud-2.png"&gt;&lt;img alt="Screenshot of a tweet that reads: &amp;quot;Not all intermediaries are bad actors, but as an advertiser or marketer you're certainly taking a bit of gamble any time you introduce more links in your digital advertising chain.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_reseller-fraud-2.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Follow-on to above response.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This makes inventory sold by DIRECT accounts more valuable, providing a clear incentive for publishers (often under instruction from the intermediaries) to label accounts as DIRECT, regardless of what the real relationship is.&lt;/p&gt;
&lt;p&gt;Mislabelling accounts is ad fraud, as the buyers aren&amp;rsquo;t getting what they paid for. It&amp;rsquo;s also rampant. Almost any ad-enabled site you can think of will likely have multiple DIRECT accounts in their ads.txt file that are shared by tens, hundreds, or thousands of other unrelated sites.&lt;/p&gt;
&lt;p&gt;They&amp;rsquo;re easy to spot with &lt;a href="https://well-known.dev" rel="noopener noreferrer"&gt;Well-Known&lt;/a&gt;, an open ads.txt index I run. &lt;a href="https://well-known.dev/resources/ads_txt/sites/breitbart.com#direct" rel="noopener noreferrer"&gt;Here&amp;rsquo;s a particularly bad case&lt;/a&gt; (log in to see counts of sites sharing each account), but the problem isn&amp;rsquo;t limited to disinformation sites.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_breitbart-shared-direct.png"&gt;&lt;img alt="Screenshot of the &amp;quot;Intermediary Direct Sellers&amp;quot; table from breitbart.com's ads.txt details on well-known.dev. An alert is shown with the text &amp;quot;Intermediaries shouldn't usually be listed as Direct&amp;quot;. Each of the 23 listed ad accounts is shared by multiple sites, often by 10s of thousands of sites." src="https://braedon.dev/images/a_tech/adspecs-1_breitbart-shared-direct.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
Sample of mislabelled accounts from breitbart.com&amp;rsquo;s ads.txt. The numbers in parentheses are the number of sites that list each account as DIRECT.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Tackling this fraud requires three things: an agreed definition of when an account can be labelled DIRECT, an entity with the power and will to enforce this definition, and the ability for violations to be detected at scale. Currently, none of those things exist.&lt;/p&gt;
&lt;h2 id="the-definition-of-direct"&gt;&lt;a class="greyLink" href="#the-definition-of-direct"&gt;The Definition of DIRECT&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For simple cases, the definition of DIRECT in the ads.txt spec seems clear. For example, if I create an account with Google AdX to sell ads on a site I own, I have direct control of the account, so it&amp;rsquo;s a DIRECT account.&lt;/p&gt;
&lt;p&gt;But what if a publisher owns multiple sites? They still &amp;ldquo;directly control&amp;rdquo; the account, so can list it as DIRECT on all of them, right? What about a parent company that owns hundreds of companies that each have their own sites?&lt;/p&gt;
&lt;p&gt;If an account isn&amp;rsquo;t DIRECT, does that make it RESELLER? It must, as there isn&amp;rsquo;t any other option, but RESELLER isn&amp;rsquo;t defined in opposition to DIRECT &amp;mdash; it has its own separate definition.&lt;/p&gt;
&lt;p&gt;Publishers often contract a vendor to manage their ad inventory for them. The publisher doesn&amp;rsquo;t &amp;ldquo;directly control&amp;rdquo; the vendor&amp;rsquo;s accounts, but the vendor arguably isn&amp;rsquo;t re-selling the inventory, as they never bought it &amp;mdash; they&amp;rsquo;re selling it on behalf of the publisher. Should the vendor&amp;rsquo;s accounts be DIRECT or RESELLER? You can guess what most of these vendors argue.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_creative-interpretation.png"&gt;&lt;img alt="Screenshot of a tweet that reads: &amp;quot;In the cases where Freestar is gateway to accessing monetizing on a site, a DIRECT ads.txt for Freestar's direct SSPs is perfectly legitimate (even as the appropriate sellers.json seller type for Freestar is INTERMEDIARY)&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_creative-interpretation.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
A creative interpretation of DIRECT from an adtech vendor.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The term &amp;ldquo;publisher&amp;rdquo; is an essential part of the definitions, but it&amp;rsquo;s never explicitly defined. The spec refers to &amp;ldquo;content owners&amp;rdquo; (abstract and introduction sections), &amp;ldquo;publisher content distributors&amp;rdquo; (start of the specification section), and &amp;ldquo;publishers&amp;rdquo; (everywhere else) seemingly interchangeably.&lt;/p&gt;
&lt;p&gt;The problem with this lack of consistency is that there are cases (e.g. syndicated content) where the content owner isn&amp;rsquo;t the site owner (&amp;ldquo;content distributor&amp;rdquo;). Either could be reasonably called the &amp;ldquo;publisher&amp;rdquo;. It&amp;rsquo;s the site owner that controls the ads.txt file, but should the content owner determine if an account is DIRECT? While there would be many problems trying to implement that interpretation, the definition of DIRECT explicitly includes &amp;ldquo;content owner&amp;rdquo; in parentheses after &amp;ldquo;publisher&amp;rdquo;, confusing the issue.&lt;/p&gt;
&lt;p&gt;The RESELLER definition even seems to include an outright mistake. When I quoted it above I removed a section from the middle to help it make sense. It actually says: &amp;ldquo;&amp;hellip;the Publisher has authorized another entity to &lt;em&gt;control the account indicated in field #2 and&lt;/em&gt; resell their ad space&amp;hellip;&amp;rdquo; (removed section in italics). This implies that the publisher controls the RESELLER accounts and has delegated that control to the reseller. This simply isn&amp;rsquo;t true in any case I know of. RESELLER accounts are owned and controlled by the reseller itself.&lt;/p&gt;
&lt;p&gt;At this point, it would be helpful to look at the intention behind the account relationship field as a guide in interpreting the definition. However, the spec contains no information about the purpose of the field, nor how it should be used by buyers.&lt;/p&gt;
&lt;p&gt;These fundamental issues with the ads.txt spec result in legitimate ambiguity about which accounts can be labelled DIRECT. This ambiguity is then leveraged to manufacture reasonable doubt whenever mislabelling is highlighted by researchers and activists. While everyone is stuck arguing about whose interpretation is correct &amp;mdash; a clash of opinion that&amp;rsquo;s never resolved &amp;mdash; the fraud continues.&lt;/p&gt;
&lt;h2 id="enforcement"&gt;&lt;a class="greyLink" href="#enforcement"&gt;Enforcement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is where an enforcement body could step in. Even without a clear definition of DIRECT in the ads.txt spec itself, some interpretation could be selected and enforced, becoming the de facto &amp;ldquo;correct&amp;rdquo; interpretation.&lt;/p&gt;
&lt;p&gt;The IAB Tech Lab itself is the obvious candidate here, as they developed the ads.txt standard in the first place. However, they constantly insist they aren&amp;rsquo;t an enforcement body, and would likely argue they don&amp;rsquo;t have power to actually enforce their standards even if they wanted to.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_iab-enforcement.png"&gt;&lt;img alt="Screenshot of a tweet from @shails that reads: &amp;quot;All our standards are voluntary. Thats how a trade organization works. There is no mandate or enforcement. We don't endorse anyone or defend any one company. Every company is treated equally and all their work, participation and adoption is voluntary.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_iab-enforcement.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
A Tweet from the SVP, Product Management &amp;amp; Global Programs at IAB Tech Lab.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Large scale DSPs and ad exchanges could act as enforcers by not buying from mislabelled accounts. There&amp;rsquo;s precedent for this &amp;mdash; the general adoption of ads.txt was largely driven by &lt;a href="https://www.blog.google/products/marketingplatform/360/working-with-industry-towards-fraud_21/" rel="noopener noreferrer"&gt;Google&amp;rsquo;s announcement in September 2017&lt;/a&gt; that their products would only buy from ads.txt authorized accounts.&lt;/p&gt;
&lt;p&gt;So far, Google and the other big players don&amp;rsquo;t seem to be interested in seriously addressing account mislabelling. But even if they were, how would they detect it reliably enough to take enforcement action?&lt;/p&gt;
&lt;p&gt;Under any reasonable interpretation of the spec, determining whether a publisher has &amp;ldquo;direct control&amp;rdquo; over an ad account requires knowing who the site&amp;rsquo;s publisher is, who owns the account, the relationship between the two, and how much &amp;ldquo;control&amp;rdquo; that relationship affords the publisher. That simply can&amp;rsquo;t be done programmatically.&lt;/p&gt;
&lt;p&gt;Well-Known currently has &lt;a href="https://well-known.dev/?q=resource%3Aads_txt#results" rel="noopener noreferrer"&gt;ads.txt data for around 467k sites&lt;/a&gt;, which collectively list 537k unique accounts as DIRECT. Then there&amp;rsquo;s the long tail of ad-enabled sites that aren&amp;rsquo;t in Well-Known&amp;rsquo;s dataset. Manually investigating every potential case of mislabelling wouldn&amp;rsquo;t make a dent in the problem.&lt;/p&gt;
&lt;h2 id="a-better-definition-of-direct"&gt;&lt;a class="greyLink" href="#a-better-definition-of-direct"&gt;A Better Definition of DIRECT&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have some idea of the shortcomings of the ads.txt standard, what can we do about it? Here&amp;rsquo;s where the pin we put in authorized domain spoofing comes in.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t know what the original purpose of the relationship field was, but given that the purpose of the standard as a whole was to tackle domain spoofing, and ad buyers are trying to use it to limit fraud by avoiding intermediaries, why not use it to tackle authorized domain spoofing?&lt;/p&gt;
&lt;p&gt;With this purpose in mind, here&amp;rsquo;s a new definition of the relationship field:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A value of DIRECT indicates that the ad account is only authorized to sell ad inventory on this site.&lt;/p&gt;
&lt;p&gt;A value of RESELLER must be used in all other cases.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Clearly the term &amp;ldquo;RESELLER&amp;rdquo; is far from ideal, but keeping it for backwards compatibility is worth the definitional dissonance.)&lt;/p&gt;
&lt;p&gt;We also need a definition of &amp;ldquo;site&amp;rdquo; to go with this new relationship definition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A site is determined by its root domain, with the exception of declared subdomains.&lt;/p&gt;
&lt;p&gt;A subdomain that is declared with a SUBDOMAIN variable in its root domain&amp;rsquo;s ads.txt is its own separate site. Its ads.txt file therefore can&amp;rsquo;t share any DIRECT accounts with the root domain.&lt;/p&gt;
&lt;p&gt;Undeclared subdomains are part of the root domain&amp;rsquo;s site.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that the ads.txt spec already defines the &amp;ldquo;root domain&amp;rdquo;, and how to handle SUBDOMAIN variables:&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_adstxt-root-domain.png"&gt;&lt;img alt="Screenshot of a paragraph under the title &amp;quot;3.1 Access Method&amp;quot;. Paragraph reads: &amp;quot;Publishers should post the /ads.txt file on their root domain and any subdomains as needed. For the purposes of this document the “root domain” is defined as the public suffix plus one string in the name. Crawlers should incorporate Public Suffix list to derive the root domain.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_adstxt-root-domain.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of root domain from the ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href="https://braedon.dev/images/a_tech/adspecs-1_adstxt-subdomain-definition.png"&gt;&lt;img alt="Screenshot of the definition of variable &amp;quot;SUBDOMAIN&amp;quot;. Value: &amp;quot;Pointer to a subdomain file.&amp;quot; Description: &amp;quot;(Optional) A machine readable subdomain pointer to a subdomain within the root domain, on which an ads.txt can be found. The crawler should fetch and consume associate the data to the subdomain, not the current domain. This referral should be exempt from the public suffix truncation process. Only root domains should refer crawlers to subdomains. Subdomains should not refer to other subdomains.&amp;quot;" src="https://braedon.dev/images/a_tech/adspecs-1_adstxt-subdomain-definition.png"&gt;&lt;/a&gt;&lt;figcaption&gt;
The definition of the SUBDOMAIN variable in the ads.txt spec.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="the-benefits"&gt;&lt;a class="greyLink" href="#the-benefits"&gt;The Benefits&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This new definition is enforceable, less prone to misinterpretation, meaningfully reduces opportunities for domain spoofing, and is more in line with what ad buyers expect.&lt;/p&gt;
&lt;p&gt;It doesn&amp;rsquo;t matter who the &amp;ldquo;publisher&amp;rdquo; is, what sites they own, or how much &amp;ldquo;control&amp;rdquo; they have over the account. All that matters is whether the account is exclusive to the site or not.&lt;/p&gt;
&lt;p&gt;Mislabelling is easily detectable &amp;mdash; every DIRECT account must only appear in the ads.txt for a single site. This can be automatically checked by anyone with a database of ads.txt files. Any ads.txt file can be checked for mislabelled accounts on &lt;a href="https://well-known.dev" rel="noopener noreferrer"&gt;Well-Known&lt;/a&gt; right now, and DSPs and exchanges could enforce this at any point with minimal effort.&lt;/p&gt;
&lt;p&gt;With an unambiguous definition and wide enforcement, buyers could be sure that when they buy from a DIRECT account their money is going to the site the seller claims the inventory is from, and isn&amp;rsquo;t going through any intermediaries. This doesn&amp;rsquo;t entirely remove the possibility of domain spoofing &amp;mdash; that would require enabling the buyer to validate the inventory details independently of the seller &amp;mdash; but it&amp;rsquo;s far better than what we have currently.&lt;/p&gt;
&lt;p&gt;The main limitation with this approach is that it&amp;rsquo;s a blunt tool. It&amp;rsquo;s based on what&amp;rsquo;s essentially a boolean field, so accounts are either DIRECT or they&amp;rsquo;re not. Buyers can&amp;rsquo;t choose &lt;em&gt;how&lt;/em&gt; direct they want to buy. Many sites won&amp;rsquo;t be able to be bought DIRECT at all, as they&amp;rsquo;re too small to have their own accounts.&lt;/p&gt;
&lt;p&gt;Thankfully, newer standards provide tools to address these limitations, which I&amp;rsquo;ll cover in a future post.&lt;/p&gt;
&lt;div class="admonition series"&gt;
&lt;p&gt;The second post in this series is now available &lt;a href="https://braedon.dev/2021/adspecs-2.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</content><category term="adtech"></category><category term="adspecs"></category><category term="ads.txt"></category></entry></feed>