Skip to content

I2I: Client Side Granular Consent #31607

@micajuine-ho

Description

@micajuine-ho

Summary

Create client side granular consent into amp-consent by allowing publishers to add a new data-block-on-consent-purposes attribute onto AMP elements, whose value is a list of publisher defined purposes. This attribute will block AMP elements from being built until all purpose consents have been accepted. Purpose consents will be collected (and stored) by amp-consent, and can also be synced via checkConsentHrefs request and response.

Design document

Original issues and discussion: #26735

Design Doc: https://docs.google.com/document/d/1RThWzCG7-LLzb13lmUNawLkBJCeGyUIi62GefTunIQg/edit

Motivation

A clear and concise description of any alternative solutions or features you've considered.

  • Creating a new component or splitting up amp-consent somehow (future work)
  • Creating multiple consent instances for each "purpose"

Additional context

Launch tracker

Usage

  • Add data-block-on-consent-purposes attributes to elements you want to block based upon consent purposes, and add a list of purposes that you want to be accepted before allowing the component to unblock.
// blocked by AMP runtime
<amp-foo  data-block-on-consent-purposes=”purpose-analytics,purpose-foo,purpose-bar”>  

// blocked by AMP runtime
<amp-bar data-block-on-consent=”purpose-bar”> 
  • To signal to amp-consent what consent purposes need to be collected (by comparing against what's stored in local storage) either add purposeConsentRequired: [‘analytics’, ‘advertising’, ‘vendorA’] to your inline config or checkConsentHref response if consentRequired: remote. If the consent purposes are not found in localStorage then the consent prompt UI will be shown.
  • amp-consent stores the consent information (including this consent purposes) in local storage, to save the decision for next user visit. To opt out of storing, use the expireCache feature
// From checkConsentHref endpoint or via inline <amp-consent> config 
purposeConsentRequired: [‘purpose-analytics’, ‘purpose-foo’, ‘purpose-bar’]
  • Collect purpose consents via promptUI: Add elements that have a new setPurpose action, that takes a list of key value pairs represneting the consent purpose name and if it's been accepted setPurpose(consentPurposeName=boolean). You can use event.checked for the boolean value if using a toggle input. Additionally, it is suggested that you add a parameter purposeConsentDefault=boolean to existing accept and reject actions, in the case that the user clicks the accept or reject button without setting all the individual consent purposes
<amp-consent>
<script>
{
  consentInstanceId: 'myConsent',
  promptUI: 'ui',
  ...
}
</script>

<div id=’ui’>
  <label for="consent-purpose-analytics">
    <input
      type="checkbox"
      on="change: ABC.toggleConsent(purpose-analytics=event.checked)"
      id="consent-purpose-analytics"
    >
    Accept Analytics Consent
  </label>
  
  <label for="consent-purpose-foo">
    <input
      type="checkbox"
      on="change: ABC.toggleConsent(purpose-foo=event.checked)"
      id="consent-purpose-foo"
    >
    Accept Foo Consent
  </label>
    
  <label for="consent-purpose-bar">
    <input
      type="checkbox"
      on="change: ABC.toggleConsent(purpose-bar=event.checked)"
      id="consent-purpose-bar"
    >
    Accept Bar Consent
  </label>

<!-- 
Even if no elements are blocked with data-block-on-consent, still need to accept or reject.
 -->
  <button on="tap:ABC.accept(purposeConsentDefault=accepted)">
    Save
  </button>
  <button on="tap:ABC.dismiss">
    Close
  </button>
</div>
</amp-consent>
  • Send the the consent purpose's consent state via promptUISrc accept or reject post message to amp-consent . In the data object, add in a purposeConsents object that has a string to boolean mapping.
// checkConsentHref response
{
  consentRequired: true
  purposeConsentRequired: [‘purpose-analytics’, ‘purpose-foo’, ‘purpose-bar’],
  consentState: unknown,
  purposeConsentMap: undefined,
}

// promptUiSrc’s iframes postmessage response:
{
    type: 'consent-response',
    action: 'accept',
    purposeConsentMap: {
        “purpose-analytics”: accept,
        “purpose-foo”: reject,
        “purpose-bar”: accept
    } 
}
  • Elements that are blocked with data-block-on-consent-purposes, will be unblocked based off the promptUI
  • The UI will prompt if not all of the purposeConsentRequired purposes are locally stored (and we have a global consent)
  • Amp consent will send the stored consent purpose consents via checkConsentHref. The response can also contain purposeConsents mapping (just like in promptUISrc), so amp-consent can update its stored values to be reflected on next visit.

Metadata

Metadata

Assignees

Labels

INTENT TO IMPLEMENTProposes implementation of a significant new feature. https://bit.ly/amp-contribute-codeStaleInactive for one year or more

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions