Prebid Support for Enforcing TCF 2.0

Overview

Definitions

Assumptions

Summary of Prebid TCF 2.0 Enforcement

Basic-vs-Full Enforcement

Basic Enforcement

Full Enforcement (Prebid Server Only)

Prebid.js Functional Requirements

Prebid SDK Functional Requirements

Prebid Server Functional Requirements

Overview

The IAB's Transparency and Consent Framework version 2.0 for enhanced support of GDPR is scheduled to take effect Apr 1 2020. It's a major update from TCF 1.1 which Prebid currently supports, and is not compatible with the previous release.

The key changes are:

References

Definitions

Assumptions

Important Legal Note: Prebid.org cannot provide legal advice about GDPR or any other governmental regulation. Our aim is to provide a toolkit of functionality that will let publishers configure header bidding as defined by their legal counsel. We will consider feature suggestions, and review any code offered by the community.

Enforcement of Purpose 2 (basic ad selection) looks to be one of the bigger areas of concern because the TCF policy could be interpreted to be a form of ad blocking. You will need to work with your legal counsel to determine how you intend to handle this scenario. Prebid.js and Prebid Server offer publishers the ability to enforce or not-enforce purposes individually. As an example of the kind of flexibility we aim to offer (*), here are some options you could discuss with your lawyers:

  1. Treat Purpose 2 as an ad blocker.
  2. Ignore enforcement of selected Purposes at the Prebid level entirely, assuming that downstream vendors will handle the TCF strings appropriately.
  3. Ignore enforcement Purpose 2, assuming that users who object to ‘Basic Ads’ will also object to ‘Personalized Ads’, causing any User IDs to be removed from ad requests.
  4. Ignore the Purpose-Consent portion of Purpose 2, but allow the user to block specific vendors.

(*) - Note on phasing: Please be aware that Prebid.js and Prebid Server will likely not deliver on the full TCF functionality by April 1st. Our initial goal for both products is to support Purpose 1 (Device Access) enforcement by that date. The ability to enforce the other purposes will be developed as soon as we can.

(**) Did we mention that you cannot rely on this document to learn how to configure your header bidding for GDPR? Seriously, talk to your lawyers.

General

  1. Prebid.org is neither a data controller nor data processor, but we supply software to both types of entities. Therefore, our software should provide a flexible set of controls necessary for both types of entities to run their businesses.
  2. Even if Prebid is configured to enforce activities by parsing consent data, publishers and downstream vendors are still responsible for ensuring their legal bases using the consent data they're provided.
  3. Prebid will ignore the TCF "stack" feature, assuming that the CMP will set the underlying Purposes appropriately.
  4. Data from the CMP will never be modified before passing to downstream entities.
  5. If TCF processing is turned on, and the user is determined to be in GDPR scope, and hasn’t provided a consent string, the system should assume a consent string that has no consent offered.

Prebid.js

  1. Prebid.js will only support parsing the TCF 2.0 consent string.
  2. TCF 2.0 features are available in Prebid.js only in a consent module, not as part of core. This allows publishers to build two versions of their wrappers: one for users in the EEA, one for users outside of the EEA.
  3. It's assumed that publishers run in two modes:
  1. A CMP is loaded on every page so TCF functions and data are fully available.
  2. Consent data is stored in first party storage and passed to Prebid directly. TCF functions are not available from the CMP.
  1. Prebid.js will not load the Global Vendors List (GVL) as this would significantly impact the success of header bidding implementations. However, Prebid.js will require a mapping of GVL vendor IDs to Prebid.js bidder codes.
  1. Further, we assume that not all Prebid adapters will be in the GVL, so we'll need to support reference by GVL ID or bidder code.
  2. Further, we assume that bidder aliases within one adapter may have different GVL IDs.
  1. As a result of not having access to GVL entries, Prebid.js will only support ‘Basic Enforcement’.
  2. TCF2 will be supported in Prebid.js 3.x, with 'no enforcement' being the default option. Prebid.js 4.0 will enforce Purpose 1 by default when the module is included.
  3. PurposeOneTreatment is ignored for Prebid.js. Publishers who don’t want to enforce Purpose 1 (or any other purpose) need to set Prebid’s configuration appropriately.

Prebid Server

  1. Prebid Server will need concurrent support of TCF 1.1 and TCF 2.0.
  2. Prebid Server will need to support “Full Enforcement” checks.
  3. AMP TCF 2.0 will be passed on the same parameter as TCF 1.1.

Prebid SDK

  1. Prebid SDK should parse the consent string in order to read the IDFA. Other than that, SDK just passes consent values to Prebid Server..

Summary of Prebid TCF 2.0 Enforcement

TCF Field

In-scope Activities

System

Enforcement

Publisher/

Host Company Controls

Purpose 1 - Store and/or access information on a device

usersync pixels, user ID modules, and device storage

Prebid.js and Prebid Server and Prebid SDK

May result in preventing one or more uesrsync activities for one or more vendors.

Do not enforce purpose 1

Do not enforce purpose 1 for vendor V

Enforce purpose 1 at the vendor level only.

Purpose 2 - Select basic ads

call bid adapters

Prebid.js and Prebid Server

May result in skipping one or more bid adapters.

All configured modules will be called as usual unless all bidders are eliminated.

Do not enforce purpose 2

Do not enforce purpose 2 for vendor V

Enforce purpose 2 at the vendor level only.

Purpose 4 - Select Personalized Ads

call bid adapters with userIds

Prebid.js and Prebid Server

May result in removing the userIds before calling one or more bid adapters.

Do not enforce purpose 4

Do not enforce purpose 4 for vendor V

Enforce purpose 4 at the vendor level only.

Purpose 7 - Measure ad performance

initiate analytics

Prebid.js and Prebid Server

May result in skipping one or more analytics adapters.

Do not enforce purpose 7

Do not enforce purpose 7 for vendor V

Enforce purpose 7 at the vendor level only.

Special Feature 1 - Use precise geolocation data

passing lat/long to server-side bid adapters

Prebid Server

May result in rounding lat/long values and IP address before sending to server-side adapters.

Do not enforce Special Feature 1

Special Purpose 2 - Technically deliver ads or content

n/a

Special Purposes do not require consent. If a publisher’s legal team wants to consider SP2, Prebid software should not be called.

PurposeOneConsent

n/a

Prebid does not provide specific support for enforcing this flag. Instead, publishers may use the provided controls for Purpose 1 and other Prebid configuration to control whether the user’s device is accessed.

Basic-vs-Full Enforcement

Prebid offers publishers several controls for whether consent/legal basis confirmation is even performed. The following flowchart shows how the controls

Basic Enforcement

The goal of 'basic enforcement' is to confirm that there's enough evidence of consent to pass data on to vendors who have access to the GVL and can fully parse and enforce.

Before allowing a Purpose for a given Vendor, one of these scenarios must be true: :

In terms of the TCF 2.0 fields, Purpose P is ok for vendor V if either of these is true:

  1. PurposesConsent[P,V]==1 AND VendorConsentBitfield[V]==1
  2. pbEnforceVendor[P]==true AND VendorConsentBitfield[V]==1
  3. PurposesLITransparency[P]==1 AND VendorLegitimateInterestBitfield[V]==1
  4. pbEnforceVendor[P,V]==true AND VendorLegitimateInterestBitfield[V]==1

Before allowing Special Feature 1, SpecialFeatureOptIns[1] must be true.

Full Enforcement (Prebid Server Only)

The big difference between 'basic' and 'full' enforcement is that Prebid Server has the GVL available to examine vendor legal bases.

Before allowing an activity that falls under a specific Purpose for a given Vendor, one of these 6 basic scenarios needs to be true:

  1. Vendor claims consent as their basis, publisher doesn't restrict the purpose, user consents to the purpose (if the enforcePurpose flag is on), and user consents to the vendor (if the enforceVendor flag is on).
  2. Vendor claims (inflexible) legitimate interest as their basis, publisher doesn't restrict the purpose, user was provided notice of the legitimate interest basis for this purpose (if the enforcePurpose flag is on), and user was provided notice for the LI basis for this vendor (if the enforceVendor flag is on)
  3. Vendor claims flexible legal basis with legitimate interest as the default, publisher restriction doesn't require consent, and ((user was provided notice of the legitimate interest basis for this purpose+vendor) OR (user consents to purpose+vendor)) [Purpose checked only if the enforcePurpose flag is on, and vendor checked only if the enforceVendor flag is on]
  4. Vendor claims flexible legal basis with legitimate interest as the default, publisher does require consent, user consents to the purpose, and user consents to the vendor. [Purpose checked only if the enforcePurpose flag is on, and vendor checked only if the enforceVendor flag is on]
  5. Vendor claims flexible legal basis with consent as the default, publisher restriction doesn't require legitimate interest, ((user consents to the purpose+vendor) OR (user was provided notice for the legitimate interest basis for this purpose+vendor)) [Purpose checked only if the enforcePurpose flag is on, and vendor checked only if the enforceVendor flag is on]
  6. Vendor claims flexible legal basis with consent as the default, publisher restriction does require legitimate interest, and user was provided notice for the legitimate interest basis for this purpose+vendor. [Purpose checked only if the enforcePurpose flag is on, and vendor checked only if the enforceVendor flag is on]

Note that there are many more scenarios where the activity would not be allowed.

The technical definition in terms of the TCF 2.0 fields follows. Purpose P is ok for vendor V if any of these is true:

  1. GVL[V].purposes contains P and GVL[V].flexiblePurposes doesn't contain P and publisherRestrictions[P]!=0 and (!enforcePurpose[P] or PurposesConsent[P]==1) AND (!enforceVendor[P,V] or VendorConsentBitfield[V]==1)
  2. GVL[V].legIntPurposes contains P and GVL[V].flexiblePurposes doesn't contain P and publisherRestrictions[P]!=0 and (!enforcePurpose[P] or PurposesLITransparency[P]==1) AND (!enforceVendor[P,V] or VendorLegitimateInterestBitfield[V]==1)
  3. GVL[V].legIntPurposes contains P and GVL[V].flexiblePurposes contains P and publisherRestrictions[P]==2 and (((!enforcePurpose[P] or PurposesConsent[P]==1) AND (!enforceVendor[P,V] or VendorConsentBitfield[V]==1)) OR ((!enforcePurpose[P] or PurposesLITransparency[P]==1) AND (!enforceVendor[P,V] or VendorLegitimateInterestBitfield[V]==1)))
  4. GVL[V].legIntPurposes contains P and GVL[V].flexiblePurposes contains P and publisherRestrictions[P]==1 and (!enforcePurpose[P] or PurposesConsent[P]==1) AND (!enforceVendor[P,V] or VendorConsentBitfield[V]==1)
  5. GVL[V].purposes contains P and GVL[V].flexiblePurposes contains P and publisherRestrictions[P]==1 and (((!enforcePurpose[P] or PurposesConsent[P]==1) AND (!enforceVendor[P,V] or VendorConsentBitfield[V]==1)) OR ((!enforcePurpose[P] or PurposesLITransparency[P]==1) AND (!enforceVendor[P,V] or VendorLegitimateInterestBitfield[V]==1)))
  6. GVL[V].purposes contains P and GVL[V].flexiblePurposes contains P and publisherRestrictions[P]==2 and (!enforcePurpose[P] or PurposesLITransparency[P]==1) AND (!enforceVendor[P,V] or VendorLegitimateInterestBitfield[V]==1)

Before allowing Special Feature 1, SpecialFeatureOptIns[1] must be true.

Prebid.js Functional Requirements

1) An optional module must be available for reading the IAB TCF 2.0 API data. Publishers will include this module in their Prebid.js package when they need to support EEA users.

2) Prebid.js must support scenarios where the TCF string parsing functions are not available.  If the codebase for parsing the TCF string is significant, it should be made an optional module separate from the enforcement functions. A key goal of Prebid.js is to include only the code that publishers need for their particular use case. The technical design should consider whether it makes sense to bundle all of these components together, or break them into 2 or 3 separate modules:

3) Prebid.js must support the following publisher controls:

Here's a set of proposed configurations within the existing consentManagement config object:

Param

Type

Description

Details

gdpr.allowAuctionWithoutConsent

boolean

Available in 3.x only, defines behavior for backwards compatibility.

For 3.x: If true, consider all Purposes as not enforceable.

If false, consider only Purpose 2 enforceable.

gdpr.consentData

object

Consent data provided statically.

Used when cmpApi is "static".

gdpr.defaultGdprScope

boolean

gdpr.rules

object

Lets the publisher override the defaults set by the enforceMode

gdpr.rules[].purpose

string

Possible values are "storage", "basicAds", "personalizedAds", and "measurement" corresponding to Purposes 1,2,4, and 7 respectively.

For some reason, people tend to prefer using the string names rather than the numbers.

gdpr.rules[].enforcePurpose

boolean

Whether to enforce this purpose or not. Overrides the setting from enforceMode.

The default in PBJS 3.x will be to enforce no purposes, and in 4.0 to enforce Purpose 1 and no others.

gdpr.rules[].enforceVendor

boolean

Whether to enforce vendor consent/legal basis for this purpose or not..

The default in PBJS 3.x will be to enforce no purposes, and in 4.0 to enforce Purpose 1 and no others.

gdpr.rules[].vendorExceptions

array of strings

Which biddercodes or module names should be treated as the opposite of the enforceVendor flag.

If enforceVendor=false, then vendorExceptions are those that will be treated as true.

If enforce=true, then vendorExceptions are those that will be treated as false.

Example configurations:

pbjs.setConfig({

  consentManagement: {

    gdpr: {

      cmpApi: 'iab',

      defaultGdprScope: true/false (0/1?)

      timeout: 3000,

      // allowAuctionWithoutConsent: false,  // deprecated

      rules: [{

        // don’t enforce Purpose 1 except for bidderA.

        // this means that TCF approval is only considered

        // for this one bidder.

        purpose: "storage",

        enforcePurpose: false,

        enforceVendor: false,

        vendorExceptions: ["bidderA"]

      },{

        // Allow the user to object to vendors for Purpose 2

        // but don’t allow them to turn off header bidding

        // altogether.

        // The exception is bidderB, which the user will

        // not be allowed to reject

        purpose: "basicAds",

        enforcePurpose: false,

        enforceVendor: true,

        vendorExceptions: ["bidderB"]

      },{

        // allow the user to have their userId removed from

        // header bidding except for bidders A and B

        purpose: "personalizedAds",

        enforcePurpose: true,

        enforceVendor: true

        vendorExceptions: ["bidderA","bidderB"]

      },{

        // analytics adapters are ok

       

        purpose: "measurement",

        enforcePurpose: false,

        enforcePurpose: false

      }]

    }

  }

});

You may notice that the examples above provide more flexibility than TCF requires. This allows publishers to establish custom legal bases in consultation with their legal counsel.

4) If the 'gdprApplies' flag is defined and is false, then Prebid.js may assume that GDPR is not in scope and therefore doesn't need to be enforced. All Purposes will be set to enforce=false.

4) There should be a way for bidAdapters to supply a GVL ID for each alias they support.

5) The aliasBidder() function should be extended to support specification of a GVL ID. e.g.

pbjs.aliasBidder('appnexus', 'newAlias', 999);

6) If a bidder code isn't associated with a GVL ID, enforcement should assume that the vendor is not allowed unless the publisher has specifically named their bidder code.

7) Analytics adapters must be associated with a GVL ID and/or a "name" to allow the system to determine which analytics adapter(s) are permitted to operate in the current context.

8) User ID modules and Real Time Data modules should be associated with a GVL ID and/or a "name" to allow the system to determine which modules are permitted to operate in the current context.

9) The system must be able to verify vendor consent in two ways:

10) The internal interface to bid adapters should remain the same: bidrequest.gdprConsent

11) The OpenRTB interface to Prebid Server should remain the same:

12) The system must support all the activity enforcement noted in the 'Summary of Prebid TCF 2.0 Enforcement' section.

  1. If Purpose 1 is being enforced:
  1. Before invoking usersync pixels for each enforceable vendor, verify consent as described in 'Basic Enforcement'.
  2. Before reading or storing cookies or HTML 5 localstorage for each enforceable vendor, verify consent as described in 'Basic Enforcement'. This will require enhancing the getCookie and setCookie utility functions to determine or accept the biddercode or module name.
  3. Before invoking each enforceable userID sub-module, verify consent as described in 'Basic Enforcement'.
  1. If Purpose 2 is being enforced, verify consent for each vendor as described in 'Basic Enforcement' before calling a bid adapter. If consent is not granted, log a console warning and skip it.
  2. If Purpose 4 is being enforced, verify consent for each vendor that passed the Purpose 2 test. If consent is not granted, log a console warning, remove the bidrequest.userId attribute and call the adapter.
  3. If Purpose 7 is being enforced, verify consent for each analytics module. If consent is not granted, log a console warning and skip it.

13) If consentManagement.gdpr is configured but no consent string is available, the system must assume that the user does not consent to either purpose or vendor. Activities may still take place if the publisher has configured the relevant Purposes as 'not enforced'.

13) Bid adapters must do one of the following for all device access activities (reading or setting cookies or local storage):

14) Prebid core must make the following information available to analytics adapters:

15) It should be possible for a pub to define a mapping between a module code and a GVL ID

   pbjs.setConfig({

     gvlMapping: {

          “id5”: 9999

          “bidderX”: 8888

     }

Prebid SDK Functional Requirements

1) Prebid SDK must accept the following optional parameters to support TCF 2.0. It’s assumed the app will pass these values directly or indirectly from a mobile CMP.

2) When a request is defined to be GDPR in-scope, the SDK must confirm that the ‘deviceAccessConsent’ flag is true. Here’s the truth table for when the SDK is allowed to access the device ID:

deviceAccessConsent=true

deviceAccessConsent=false

deviceAccessConsent undefined

GDPR scope=false

Yes, read IDFA

No, don’t read IDFA

Yes, read IDFA

GDPR scope=true

Yes, read IDFA

No, don’t read IDFA

No, don’t read IDFA

GDPR scope undefined

Yes, read IDFA

No, don’t read IDFA

Yes, read IDFA

3) The SDK must pass the consent data to Prebid Server on the same OpenRTB attributes as defined in TCF 1.1:

Prebid Server Functional Requirements

1) Optional configuration must be available for host companies to turn on and off enforcing GDPR with IAB TCF 2.0 API data. There should be global and publisher account level configuration. The default should be to enforce.

2) If enforcement is turned on for this request, Prebid Server must be able to determine whether it's in-scope for GDPR processing. If any of the following conditions are true, the request is in-scope:

  1. the incoming request defines regs.ext.gdpr:true.
  2. regs.ext.gdpr is undefined, geo-lookup is turned on, and the user's IP address is in a configurable set of countries.
  3. regs.ext.gdpr is undefined and the host company's default scope is to enforce.

3) Prebid Server must support the following host company controls:

4) Prebid Server must give host company config to say what to do with the purposeOneTreatment - both as a default and for each account:

  1. ignore the flag entirely
  2. if purposeOneTreatment=1 and IsServiceSpecific=1 then Purpose 1 is overridden to no-access-allowed
  3. if purposeOneTreatment=1 and IsServiceSpecific=1 then Purpose 1 is overridden to access-allowed

The implementation of this “PurposeOneTreatmentInterpretation flag modifies the flowchart above: it may short-circuit the logic, jumping straight to Yes or No without a normal enforcement check.

5) It must be possible for a Host Company to define its GVL ID to use for confirming user user consent for setting cookies.

Example configuration/DB entries:

gdpr.host-vendor-id: 52
gdpr.enabled: true/false // default true

gdpr.purpose.P.enforcePurpose: no/basic/full // default full

gdpr.purpose.P.enforceVendors: true/false // default true

gdpr.purpose.P.vendorExceptions: list of biddercodes
gdpr.specialfeature.S.enforce: true/false // default true

gdpr.specialfeature.S.vendorExceptions: list of biddercodes

gdpr.purposeOneTreatmentInterpretation: ignore/no-access-allowed/access-allowed

account.A.gdpr.enabled: true/false  // default true

account.A.gdpr.purpose.P.enforcePurpose

account.A.gdpr.purpose.P.enforceVendors

account.A.gdpr.purpose.P.vendorExceptions
account.A.gdpr.specialfeature.S.enforce

account.A.gdpr.specialfeature.S.vendorExceptions

account.A.gdpr.purposeOneTreatmentInterpretation

geolocation.VENDOR.server: url // location of geo lookup service

6) There should be a way for bidAdapters to supply a GVL ID for each alias they support.

7) The external definition of aliases should be extended to support specification of a GVL ID. e.g.

"ext": {

    "prebid": {

      "aliases": {         // existing feature

        "districtm": "appnexus"

      },

      "aliasgvlids": {     // new feature

        "districtm": 144

      }

    }

  }

8) Prebid Server's enforcement should be "Full" mode unless it doesn't have access to the proper GVL version.

9) Prebid Server should be able to read the TCF2.0 GVL that's specified in the consent string. If it does not have immediate access to that version of the GVL, it may downgrade enforcement to "Basic". The assumption is that subsequent requests for that version of the GVL will succeed. The system should log any usage of Basic Enforcement.

10) If a bidder code isn't associated with a GVL ID, enforcement should assume that the vendor is not allowed unless the publisher has specifically named the bidder code as a configured exception.

11) Analytics adapters must be associated with a GVL ID and/or a "name" to allow the system to determine which analytics adapter(s) are permitted to operate in the current context.

12) User ID modules and Real Time Data modules should be associated with a GVL ID and/or a "name" to allow the system to determine which modules are permitted to operate in the current context.

13) The system must be able to verify vendor consent in two ways:

14) The internal interface to bid adapters should remain the same.

15) The OpenRTB interface to Prebid Server should remain the same:

16) The system must support all the activity enforcement noted in the 'Summary of Prebid TCF 2.0 Enforcement' section.

  1. If Purpose 1 is being enforced:
  1. Before invoking /cookie_sync pixels for each enforceable vendor, verify consent as appropriate for the enforcement method.
  2. Before setting a cookie on /setuid, verify consent for the Host Company's GVL ID as appropriate for the enforcement method
  3. Before passing ID values to each enforceable vendor, verify consent as appropriate for the enforcement method.
  1. If Purpose 2 is being enforced, verify consent for each vendor as appropriate for the enforcement method before calling a bid adapter. If consent is not granted, log a metric and skip it.
  2. If Purpose 4 is being enforced, verify consent for each vendor that passed the Purpose 2 test. If consent is not granted, log a metric, remove the bidrequest.userId attribute and call the adapter.
  3. If Purpose 7 is being enforced, verify consent for each analytics module. If consent is not granted, log a metric and skip it.
  4. If Special Feature 1 is being enforced, verify user opt-in. If the user has opted out, round off the IP address and lat/long details and log a metric.
  1. IP masking: for IPv4, zero out the last byte. For IPv6, zero out the last 2 bytes.
  2. Check the OpenRtb packet for $.device.geo.lat, $.device.geo.lon, $.user.geo.lat, $.user.geo.lon. Round off the values to the last two decimal points if they exist.

17) If GDPR is being enforced but no consent string is available, the system must assume that the user does not consent to either purpose or vendor. Activities may still take place if the Host Company has configured the relevant Purposes as 'not enforced'.

18) Prebid Server core must make the following information available to analytics adapters: