ampproject / ampproject/amphtml

I2I: Client Side Granular Consent

Open
#31,607 5 comments 3 reactions 1 assignee Claimed by @micajuine-ho View on GitHub
INTENT TO IMPLEMENT Stale
Dominant language
JavaScript
Stars
14.9k
Forks
4.1k
PR merge metrics
No merged PRs in 30d

Description

## 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 `checkConsentHref`s request and response.

## Design document

Original issues and discussion: https://github.com/ampproject/amphtml/issues/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

- [x] Create experiment flag (#32433)
- [x] Expose purposeConsentRequired API through `checkConsentHref` & inline (#32433)
- [x] PromptUI changes - create `toggleConsent()`, expand `accept` and `reject` actions, create `purposeConsentMap` from decisions #32470

- [x] PromptUiSrc changes - send and receive `purposeConsentMap` (#32638)
- [x] Store the the `purposeConsentMap` and `purposeConsentRequired` in local storage through the ConsentManager (#32721)
- [x] Create Internal API to get purposeConsentMap from ConsentPolicyManager (for syncing) (#32990)
- [x] Runtime and ConsentPolicyManager changes to block building until all purposes are accepted (#32990)
- [ ] E2E tests
- [x] Lauch 100%
- [x] Cleanup
/cc @ampproject/wg-approvers

## 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

// blocked by AMP runtime

```
- 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`](https://github.com/ampproject/amphtml/blob/master/extensions/amp-consent/amp-consent.md#client-caching) feature
```
// From checkConsentHref endpoint or via inline 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
```

{
consentInstanceId: 'myConsent',
promptUI: 'ui',
...
}




Accept Analytics Consent




Accept Foo Consent




Accept Bar Consent


Save


Close

```
- 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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.