AMP Ads For AMP Pages ("a4a") #3133

Open
michaelkleber opened this Issue May 6, 2016 · 6 comments

Projects

None yet

6 participants

@michaelkleber
Collaborator
michaelkleber commented May 6, 2016 edited

Motivation

Currently <amp-ad> elements can request ad creatives written in classical HTML+JS, which therefore must be sequestered inside cross-domain iframes and loaded only after a delay, to mitigate the potential UX degradation they could cause.  Even so, long-running JS inside the ads can degrade scrolling, swiping in the carousel, etc.

We propose a new ad rendering path which continues to allow HTML+JS ads in cross-domain iframes, but also allows an ad request to instead return an ad written in AMP HTML.  If the ad response is AMP, then the ad can be rendered early by splicing it into the surrounding AMP page, with no need for iframing or delays, without risk to the page's UX.  As a side benefit, we speed up HTML+JS ads as well, because the ad request will still run earlier than it does today; only the rendering will be delayed.

Requirements

The design proposed here is constrained by the desires of publishers, advertisers, and the AMP page's security and user experience requirements.

  1. The ecosystem needs it to be possible for the same ad slot to be filled with either an HTML+JS ad or an AMP ad, as decided by the ad server. This allows the gradual introduction of AMP ad creatives, without publishers worrying about no AMP-format ads being available or advertisers worrying that there will be nowhere for AMP-format ads to display.
  2. Good user experience requires that the ad request be sent early in the page lifecycle, before the time when non-AMP-runtime JS is ever allowed to execute. This means that any JS involved in constructing the ad request must be checked into the GitHub repo, not served by the ad network.
  3. Ad networks, who need their cookies in order to pick the right ad to show, want the ad request to go directly from the browser to their own server (and not proxied through a trusted AMP verification server like cdn.ampproject.org).
  4. The AMP page needs to protect itself from non-AMP content, so must delay the rendering of any ad that has not been blessed by trusted AMP verification. (Trusting any ad server to return AMP without further validation is too risky; full in-browser validation of the response is too slow.)
  5. Good user experience requires that if a validated AMP ad is returned, it should be rendered early and ideally without iframing. If a classical HTML+JS response is returned, it should still be rendered inside a cross-domain iframe and with a delay, preserving the AMP runtime's current heuristic for when it's safe to do so.
  6. Publishers should be offered a way to add custom targeting information to the ad request based on their knowledge of the user. (This is a use case currently supported by remote.html).
  7. Publishers who configure everything within their AMP pages should not need to re-tag; an ad network's migration from the current amp-ad implementation to one supporting AMP-format ads should be transparent. (However, publishers who rely on remote.html and targeting logic in their own server will need to do new work to transition.)

Proposed Design

The a4a proposal is built on the ability to prove that an ad response is valid AMP by sending a cryptographic signature for the ad along with the response.  The ad gets validated and signed before serving.  Validation+signing is done by a new signing service that will be run by the AMP Project, reusing the validator binary that powers cdn.ampproject.org.  An HTTP API to the validation service will be open to all users.  (There is an open question of which pieces of AMP functionality should be allowed within ads; the validator may enforce some ads-specific policies at signing time.)  The signature gets cryptographically verified by the AMP runtime in the browser, using public keys which it fetches from cdn.ampproject.org.

We will implement this plan by adding a new custom extension, "amp-a4a", and experimentally filling the<amp-ad> slot with an <amp-a4a> element with the new behavior described below.  (The script to enable the extension will be automatically loaded by amp-ad if needed — no retagging.)

Early in page rendering (starting at AmpA4A.buildCallback time):

  • The amp-a4a extension will invoke ad-network-contributed code to construct an ad request URL.
    • Optionally, if the publisher wishes to modify the ad request, per requirement 6 above: The <amp-ad> tag may include a new configuration parameter data-3p-ad-request-transform-src="https://…".  If so, the ad-network-contributed code should perform an XHR to that URL (async CORS XHR withCredentials), telling the publisher's server the constructed ad request URL and giving the publisher a chance to modify it before the request goes to the ad network. The details of this request/response/modification is TBD; as described here, its design is entirely up to the ad network.
  • The extension will perform an XHR (async CORS XHR withCredentials) to the ad request URL.
  • In parallel, the extension will also issue an XHR to request public keys from the AMP Project's signing service.  The response may come from browser cache.

The ad response will be processed by ad-network-contributed code, which will render the response through one of two pathways.

One possible response to the XHR is a Signed AMP Ad Creative, whose handling can continue to run without delay.

  • The ad-network-specific code can pass the AMP HTML ad, along with its cryptographic signature, to an extension-provided rendering method.
  • The extension will verify the signature with the public keys, using browser-native cryptography (window.crypto.subtle.verify / window.crypto.webkitSubtle.verify).  This verification happens asynchronously and off of the main JS thread.  (A crypto.subtle polyfill which runs on the main JS thread is not appropriate here.)
  • Once verified, the extension will render the AMP ad without further delay:
    • If the browser supports Shadow DOM, the ad will be by spliced into the surrounding AMP HTML document, primarily rendering as a Shadow DOM tree hosted at the <amp-a4a> element.
    • Otherwise the ad will be rendered without delay inside an iframe.  Details still to be determined; see the following bullets.

If the response is not a signed AMP creative, or if the fast rendering path fails for any reason (bad signature, browser lacks crypto, etc), then the extension instead gets to render the ad at AmpA4A.layoutCallback time, after the usual runtime-determined delay.  The ad must render inside of an iframe.  We plan to explore a few options for this rendering mode:

  1. Create an iframe whose src is the same URL used for the XHR.  If the response was cacheable, then the XHR response can be pulled from browser cache and reused as the contents of the iframe.  This would leave the ad rendering in a cross-domain iframe on the domain of the ad server, a well-understood environment for ads.  (However, if there is a cache miss, a second ad request might be issued.)
  2. An iframe with sandbox and srcdoc.
  3. The AMP 3p iframe mechanism.

Wouldn't That be Better Explained by a Picture?

Perhaps it would.

a4a flow

Initial Steps

We intend to implement the a4a infrastructure, along with model uses of it by amp-ad elements of types "adsense" and "doubleclick".  We will also generate experimental AMP ads for several types of ads in which the HTML is constructed by Google's servers.  New ad rendering paths can be subtle, and we will run A/B experimentation to be sure of their effectiveness.

Ads in AMP format will require runtime support for use cases currently handled in JavaScript.  Probably the most pressing example is viewability measurement, a need which will be met by work like #3110 .  Others will surely arise.

Alternatives and Future Directions

We considered a template-based system in which ads were broken up into cacheable templates, which could be proxied through cdn.ampproject.org for validation, and simple strings, which could be expanded into the templates without breaking the validity of the document.  This could have better scaling properties than needing to re-validate every ad at serving time.  But it seems more difficult than the full-ad-signing approach proposed here: decomposing arbitrary AMP ads and safely re-combining a cached template with validated strings in the browser seems hard.  If a template-based alternative is viable and is appealing to other ad networks, it could coexist as another form of XHR response leading to the early-rendering code path.

If web browsers implemented AMP validation as a native operation, then the cryptographic signing, or the template expansion alternative, would be unnecessary.

@ericlindley-g ericlindley-g added this to the Pending Sprint Slotting milestone May 9, 2016
@cramforce
Member

LGTM

I'm very excited by this. It is a real chance to solve the "coordination problem" for display advertising.

One thing that should be spelled out and planned for is additional validation for ads. We should probably go with an extension whitelist (e.g. no amp-iframe) and also do additional checks on the CSS.

@dkolba
dkolba commented Jun 9, 2016

Will a4a distinguish between mobile and desktop clients and deliver the appropriate ads?

@tdrl
Collaborator
tdrl commented Jun 9, 2016

@dkolba A4A itself will be agnostic -- it will be up to an individual ad network's implementation to check client state and deliver an appropriate creative. (Either because the network's sub-class of A4A itself checks and crafts an appropriate URL request or because the ad network server, say, detects user agent and chooses a creative to deliver based on that.)

@johnfmorton
johnfmorton commented Jul 20, 2016 edited

Hello all. Regarding the "HTTP API to the validation service will be open to all users" in the Proposed Design section above, that's of interest to me. I'm not sure the best way to help with this project but I'm interested in being involved. I maintain the Yeoman Build A Banner workflow.

What's the best way to be of help in the A4A project?

@cramforce
Member
cramforce commented Jul 20, 2016 edited

@johnfmorton A4A will have stricter rules than AMP itself and might even have a different document marker to signify being an ad instead of a doc. For now passing https://www.npmjs.com/package/amphtml-validator would be a great start. We will definitely add support for A4A validation to that module when it becomes more final.

@johnfmorton

@cramforce Thanks for the quick reply. I'll look into that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment