Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Master feature] Enable user choice using <amp-consent> component #13716

Closed
zhouyx opened this Issue Feb 28, 2018 · 59 comments

Comments

@zhouyx
Copy link
Collaborator

zhouyx commented Feb 28, 2018

Overview

A new <amp-consent> component that enables publisher to get consents from readers and manage their consents.

Format

<amp-consent>
   <script type='application/json'>{
     “consents”: {
        “consentInstanceABC”: {
           “checkConsentHref”: “endpointABC.com”,
           “promptUI”: “template1”
         },
        “consentInstanceDEF”: {
           “checkConsentHref”: “endpointDEF.com”,
           “promptUI”: “template2”
         }
      },
     “policy”: {
         “policyABC”: {
             “waitFor”: {
                “consentInstanceABC”: [],
              }
           }
     }
   }</script>
   <div id=”template1”>
     Collect consent for instance ABC
     <button on="tap:consentInstanceABC.dismiss">Dismiss</button>
     <button on="tap:consentInstanceABC.accept">Accept</button>
     <button on="tap:consentInstanceABC.decline">Decline</button>
   </div>
   <div id=”template2”>
     Can we use your cookie?
     <button on="tap:consentInstanceDEF.accept">Accept</button>
   </div>
 </amp-consent>

Consent instance

config

Each unique consent instance keeps a list of endpoints to get and update consent states. Initially, the configuration is simple:

  • checkConsentHref: An endpoint to use to check the consent status
  • promptUI: An ID corresponding to the UI container to display that's meant to collect this consent.

In the future, configuration options may be expanded for more functionality:

{
  checkConsentHref: (required)
  promptUI: (required)
  disableLocalStorage: (optional) true/false. Default to false - controls whether state does not get kept in local storage (see below)
  acceptHref: (optional) - an endpoint that is requested when the consent is accepted
  rejectHref: (optional) - an endpoint that is requested when the consent is rejected
  dismissHref: (optional) -  - an endpoint that is requested when the consent is dimissed
}
checkConsentHref

Request

Make a POST request:

{
  consentInstanceId // string for the consent ID being asked about
}

In the future, this may be expanded to include:

{
  consentInstanceId // string for the consent ID being asked about
  ampUserId // For server to identify the user
  timestamp // value stored on client side, can be empty
}

Response

Expect a response with an boolean value:

{
  'promptIfUnknown': boolean (true/false)
}

Consent Policy

A default consent policy will be auto generated to wait for every consent instance. One can overwrite the default consent policy by declaring a new consent policy instance with id "default". Or add other consent policy instances to the <amp-consent> config.

Consent Policy Instance Config

Each unique consent policy instance creates a consent blocking behavior unit that instruct other components on the page. It keeps a list of consent instances to wait for. Initially, the configuration is simple:

  • waitFor: A JSON object that declare the list of consents to wait.
'waitFor': {
  'ABC': [] // Only empty array accept now.  
}

In the future, configuration options may be expanded for more functionality:

{
  'waitFor': {
    'consentId': [] // Array of items that's associated with that consent instance
  }
  'timeout': timeout in case user never respond
}

Storage

All consent instance state will be stored and handled client side.
For each consent instance. LocalStorage looks like

  • Key: amp-consent:${consentInstanceId}
  • Value: true/false (won’t store anything for unknown state)

Blocking Components

Use data-block-on-consent=consent-policy-id to block AMP components with consents. If no consent-policy-id is specified, "default" consent policy instance will be used.

Individual AMP component can override default blocking behaviors and implement blocking logic itself.

UI

UI Restrictions

Prompt UI

  • Only a single UI can be shown at a time.
  • Position fixed and stick to the bottom of the page

Revocation button

  • Will only be displayed after consent state is determined
  • Can overlap when there are multiple consent instances.

Text

  • All text will be static inlined. No template replacing will be supported
Revocation Button Design

Coming soon, we will support the ability to specify a UI container that will be displayed once the prompt has been handled. This can be used optionally to enable a persistent UI affordance to be displayed that allows the end user to revoke their previous choice and pick a new choice.

@zhouyx zhouyx changed the title I2I: `<amp-consent>` component I2I: <amp-consent> component Feb 28, 2018

@rudygalfi

This comment has been minimized.

Copy link
Contributor

rudygalfi commented Feb 28, 2018

Some feedback:

We should avoid the term revocation to talk about the full list management flow. Maybe some terminology like "consent prompt" vs. "consent management" would sufficiently differentiate them.

In the "config" section, could you clarify the two options that are presented? It looks like the 2nd one just uses more fields.

Could you add a section talking about data persistence (viewer case and origin case)?

CONSENT_RESTRICT_STATES.CONSENT_NEEDED: It seems like it's valid for this value to be returned even if a list of items is returned, none of which requires consent. Basically, my reading of the items is:

  • NO_CONSENT_RESTRICT: Consent is being asked for by this page, but it should be ignored (could be used to convey decisions relating to geo)
  • CONSENT_NOT_NEEDED: How is this case differentiated from the previous one? Are we asking the caller to summarize the outcome of the response or is this acting like an override (in which case it seems to be like NO_CONSENT_RESTRICT.
  • CONSENT_NEEDED: Related to the above, is this saying to definitely prompt, or is it just saying that we should let the rest of the consent logic decide what to do on the page. Maybe we need some sort of prompt/no-prompt decision in this enum.

fullConsentStateList: Is id meant to be something the publisher comes up with, or is it specifically meant to say "id"?

CONSENT_STATE.DISMISS: How do you imagine this is needed? I could see AMP sending it to the pub, but I can't imagine when it's useful for the pub to tell this to AMP.

CONSENT_INSTANCE_STATUS: Can we provide more granular information about consent status to a component? Specific items/vendors?

Component management: We should include affordances for timeouts and define the defaults for consent blocking. For example, if the page has an amp-consent component but it's silent on which elements it applies to, we should conservatively block the element from loading.

@jpettitt

This comment has been minimized.

Copy link
Collaborator

jpettitt commented Mar 2, 2018

Where variable replacement is overridden in the case of no consent, for example client id, it would be useful for the publisher to be able to specify a default value rather than just returning blank.

@ayumihamsaki

This comment has been minimized.

Copy link

ayumihamsaki commented Apr 3, 2018

Hi,

Can I ask what would be the difference with this and using the <amp-user-notification> and displaying a banner at the bottom of the screen asking people to accept cookies or not see a screenshot of one I have running on a production website:

untitled

~I blanked out the website, due to the owner not wanting to show the website. But you can see the Cookie Consent banner at the bottom.

@rudygalfi

This comment has been minimized.

Copy link
Contributor

rudygalfi commented Apr 3, 2018

@ayumihamsaki One key difference is that you can collect a user response of yes or no. amp-user-notification only supports being dismissed (and storing that so that the notification doesn't re-appear).

@itspauli

This comment has been minimized.

Copy link

itspauli commented Apr 3, 2018

@ayumihamsaki there are a number of subtle differences which are designed to comply with the detail in the GDPR. Amongst other things;

consent: the user should be given ability to optin or out, a solo accept button is equivalent to a pre-ticked box (which is non-compliant),

storage: You are required to keep an up-to-date record of users preference status and be able to demonstrate that record upon request (local storage in this instance), and

optout: The user should be able to change their mind with as much ease as they opted in, preferably using the same mechanism (DP by design).

There is a bunch more reasons. It's worth noting that cookies are one of the most ambiguous topics of the GDPR, mentioned one (I recall) but included in the scope without much direction on how to comply. It is the EU's view that much of the data collected using cookies can be used alone or in combination to pinpoint a specific users (IP, GA snippet, Zip or postcode) so it is well within scope.

P.S. Good solution @zhouyx this will help a bunch of people

@src-code

This comment has been minimized.

Copy link
Contributor

src-code commented Apr 4, 2018

@rudygalfi Assuming this is intended primarily for GDPR, will Google Search and other consumers of cached AMP pages actually execute this consent flow when displaying a publisher's AMP page, or will Google obtain its own consent from EU users which will cover the display of cached AMP pages, much like what's needed for 3rd party display ads, etc? In other words, is this component intended only for publishers who serve AMP as their primary experience from the own domain, or is it also intended for cached pages served by 3rd parties like Google Search? (Eg, will Google Search require the user to click through the publisher's AMP consent flow for every publisher displayed in the Google Search carousel?)

@rudygalfi

This comment has been minimized.

Copy link
Contributor

rudygalfi commented Apr 9, 2018

@src-code: Whilst individual companies' interpretations of applicable law may vary, it's clear that each entity that processes personal data of European users must have a valid legal basis - such as end user consent - to do so. For Google AMP cache pages, the entities processing personal data would include Google, the publisher and any vendors the publisher works with. That's why the AMP Project is building tools to enable those entities to seek consent, if they require it for their own compliance. Put simply: because the publisher chooses the behaviors and vendor integrations in the page, the publisher is primarily responsible for managing the compliance obligations that stem from those choices.

@src-code

This comment has been minimized.

Copy link
Contributor

src-code commented Apr 9, 2018

@zhouyx Will it be default to pass credentials in the CORS requests (eg for acceptHref?) Or at least be configurable? I assume it'll be possible but not documented yet...

@rudygalfi rudygalfi changed the title I2I: <amp-consent> component [Master feature] <amp-consent> component Apr 10, 2018

@zhouyx

This comment has been minimized.

Copy link
Collaborator Author

zhouyx commented May 14, 2018

That only works for acceptHref, not rejectHref.

@zhouyx zhouyx closed this May 14, 2018

AMP HTML Project Roadmap automation moved this from Feature Backlog to Done May 14, 2018

@zhouyx zhouyx reopened this May 14, 2018

AMP HTML Project Roadmap automation moved this from Done to In Progress May 14, 2018

@jpettitt

This comment has been minimized.

Copy link
Collaborator

jpettitt commented May 14, 2018

@clumsyjedi @zhouyx for amp-iframe the default could be to block if data-block-on-consent is present. Only allowing it to run, passing in the consent state, if consent has resolved and data-consent-aware-iframe (of something similar) is set.

@clumsyjedi

This comment has been minimized.

Copy link

clumsyjedi commented May 15, 2018

@clumsyjedi That's a good point for amp-iframe. For amp-ad, we will ask each ad vendor to specify whether they will handle consent state themselves. But for amp-iframe, it will require the publisher to instruct AMP whether the iframe will handle consent blocking or not. We can expose an attribute for that.

@clumsyjedi @zhouyx for amp-iframe the default could be to block if data-block-on-consent is present. Only allowing it to run, passing in the consent state, if consent has resolved and data-consent-aware-iframe (of something similar) is set.

@jpettitt @zhouyx My use case is that we have call backs to our own site for rich content in iframes. We want to render the iframe content regardless of consent state.

For the consent states UNKNOWN, REJECTED and DISMISSED we would render the content without any tracking.

For the states NOT_REQUIRED and GRANTED we would render the content with tracking scripts in it.

So to me it's important that the iframe have access to the consent state to make that determination. Our iframes are embedded using the src attribute of AMP iframe. I would like to see something like a consent-status-parameter attribute on the amp-iframe element, which would contain REJECTED|GRANTED|etc. So consent-status-parameter=gamp-consent-status would append gamp-consent-status=GRANTED to the query string in the src parameter.

I assume other publishers who embed using srcdoc would also need the consent state communicated to the iframe document. I don't know what mechanism could be used... can a CONSENT_STATUS var be injected into the iframed document?

@zhouyx

This comment has been minimized.

Copy link
Collaborator Author

zhouyx commented May 15, 2018

@clumsyjedi Thanks for explaining this. It sounds like a very solid use case to me. We've filed #15290 to track the issue.

@christian-felix

This comment has been minimized.

Copy link

christian-felix commented May 18, 2018

@jasti , are there some propositions in progress as how to get/read the current user consent state?

For example, we would like to disable the opt-in button or show some additionaly info when user already has given his consent, furthermore, when mutliple user consent will be available, we want to display an list with all the vendors and the corresponding consent state.

@jgsojo

This comment has been minimized.

Copy link

jgsojo commented May 22, 2018

@rudygalfi, regarding support for multiple consent instances we have the next use case:
Every page of our web has ads as well as tracking for different user actions, with the incoming law, each user should be able to manage whether they want to consent each of the functionalities.

For example, one user could accept get his navigation data stored to improve the site's knowledge about his users (analytics tracking) but not accept it for get personalized ads. In that case, we need different consents in order to enable some things and disable others.

And regarding your question about how to gather the consent states, I think that making them toggleable with checkboxes would be great.

@ArnoldLovasHeute

This comment has been minimized.

Copy link

ArnoldLovasHeute commented May 24, 2018

hi, i have same problem. the deadline would be on 25th of may, but actually i cant see the way, to use more instances. i would ask the user about the tracking codes and the personalized ads.

is not possible actually?

it would be also important a "global" accept button, i mean, if the user press it, it would accept all instances. the basic strategy, we want to show the detailed setup about the cookies if the user press a cookie setup button, but basically the user will see just the global cookie button.

@christian-felix

This comment has been minimized.

Copy link

christian-felix commented May 24, 2018

@ArnoldLovasHeute, multiuser consent is not possible yet. Actually you have only the option to opt-out or opt-in globaly, whenever you use the "block-data-on-user-consent" attribute.
Individual consent settings would be available soon as stated previously by the developers.

@jasti

This comment has been minimized.

Copy link
Collaborator

jasti commented May 24, 2018

@ArnoldLovasHeute @jgsojo As @christian-felix says, "purpose-based consent" isn't available at the moment and AMP only allows accepting consent at a global state. Purpose based consent won't be available before May 25th and if you strictly need it by your interpretation of the law, a workaround might be to send the user to an external consent acceptance flow using a simple outlinks. A better version for supporting external consent flows will be available shortly but not before May 25th. (this is obviously not legal advise.)

are there some propositions in progress as how to get/read the current user consent state?

@christian-felix, I'll let @zhouyx answer.

@zhouyx

This comment has been minimized.

Copy link
Collaborator Author

zhouyx commented May 24, 2018

are there some propositions in progress as how to get/read the current user consent state?
For example, we would like to disable the opt-in button or show some additionaly info when user already has given his consent, furthermore, when mutliple user consent will be available, we want to display an list with all the vendors and the corresponding consent state.

@christian-felix Individual extension is able to get current user consent state right now.
For analytics tool to collect consent state, we've filed #14916
For making consent state available to consent UI, we've file #15394

If I understand your requirement correctly (let's ignore multiple user consent for now). You want to make the consent state available and be able to customize the content (not any AMP component). One way way would to use css to hide/show content based on consent state, however that involves content position change without user interaction and I'm not convinced about that. Another way would be combine amp-consent and amp-access together and fetch content based on the consent state, would that be possible? Or if it is only a very small portion of the page, maybe <amp-iframe> can also be a workaround.

I've filed #15561 to track this individually. Thank you!

@jasti

This comment has been minimized.

Copy link
Collaborator

jasti commented May 29, 2018

Hi everyone, just some housekeeping. This issue has become long with a lot of FRs, bugs and implementation advice. Now that amp-consent has been in production for a few weeks, we are moving on to phase 2. You can see the new issue at #15651 and follow along the 'In Progress' label in the dedicated 'consent tools' project to know which items are being actively worked on.
Closing this issue but please keep your feedback coming in #15651.

@jasti jasti closed this May 29, 2018

AMP HTML Project Roadmap automation moved this from In Progress to Done May 29, 2018

Consent Tools automation moved this from To do to Done May 29, 2018

@jeffjose jeffjose moved this from Needs triage to Done in Analytics Jun 25, 2018

@wustzdd

This comment has been minimized.

Copy link

wustzdd commented Jul 3, 2018

@zhouyx Thank you for your sharing. But I have a question. In order not to collect any data, the Facebook pixel needs to be revoked before receiving the consent. Once accepted by customer, the Facebook pixel needs to be granted, How can I deal with it in the amp project? You can see the Facebook document:https://developers.facebook.com/docs/facebook-pixel/events-advanced-use-cases/v3.0

@rudygalfi

This comment has been minimized.

Copy link
Contributor

rudygalfi commented Jul 3, 2018

@jeffjose @zhouyx: In order to address @wustzdd's question, could we introduce some delay logic on amp-pixel so it will wait until consent is resolved? cc @jasti

@jasti

This comment has been minimized.

Copy link
Collaborator

jasti commented Jul 3, 2018

@wustzdd amp-pixel already supports the data-block-on-consent attribute which allows amp-pixel pings to be held back until consent is received from the user as described here: #13716 (comment)
Please let us know if that doesn't work for your use case.

@wustzdd

This comment has been minimized.

Copy link

wustzdd commented Jul 4, 2018

@jasti Thank you for your reply, AMP supports or component to use this attribute, but in my case above, I haven't found a component to support facebook pixel. Can you give me some suggestion about my case? Thank you very much.

@wustzdd

This comment has been minimized.

Copy link

wustzdd commented Jul 4, 2018

@jasti Thank you for your reply, AMP supports amp-ad or amp-analytics component to use this attribute, but in my case above, I haven't found a component to support facebook pixel. Can you give me some suggestion about my case? Thank you very much.

@jasti

This comment has been minimized.

Copy link
Collaborator

jasti commented Jul 9, 2018

@wustzdd You could probably use the <noscript> version of FB's pixel tag in <amp-pixel> but the best thing to do is approach Facebook to add an integration directly in AMP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.