Repository: prebid/prebid-server
Pull request #2264 (2022-06-03 21:54:18)

GDPR: move request-specific data onto permissions object
~~This PR is in draft. I'll rebase it and put it up for formal review once the open PRs it depends on are merged.~~

This PR moves request-specific GDPR data (signal, consent, alias GVL IDs and publisher ID) onto the permissions object. The auction flow is updated accordingly.

Also the cookie sync and setuid endpoints have been updated as follows:
- the GDPR object is instantiated on a per-request basis in each endpoint rather than being instantiated once for these endpoints at startup
- the fetched account is now used to generate an aggregated config (host GDPR TCF2 config + account GDPR config)
- the aggregated config is passed into the per-request GDPR permissions object



Patch:
diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go
index da66e443..c25eecc9 100644
--- a/adapters/adnuntius/adnuntius.go
+++ b/adapters/adnuntius/adnuntius.go
@@ -233,7 +233,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte
 func getGDPR(request *openrtb2.BidRequest) (string, string, error) {
 	gdpr := ""
 	var extRegs openrtb_ext.ExtRegs
-	if request.Regs != nil {
+	if request.Regs != nil && request.Regs.Ext != nil {
 		if err := json.Unmarshal(request.Regs.Ext, &extRegs); err != nil {
 			return "", "", fmt.Errorf("failed to parse ExtRegs in Adnuntius GDPR check: %v", err)
 		}
diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go
index da20457b..c6f651ca 100644
--- a/endpoints/cookie_sync.go
+++ b/endpoints/cookie_sync.go
@@ -41,7 +41,8 @@ var cookieSyncBidderFilterAllowAll = usersync.NewUniformBidderFilter(usersync.Bi
 func NewCookieSyncEndpoint(
 	syncersByBidder map[string]usersync.Syncer,
 	config *config.Configuration,
-	gdprPermissions gdpr.Permissions,
+	gdprPermsBuilder gdpr.PermissionsBuilder,
+	tcf2CfgBuilder gdpr.TCF2ConfigBuilder,
 	metrics metrics.MetricsEngine,
 	pbsAnalytics analytics.PBSAnalyticsModule,
 	accountsFetcher stored_requests.AccountFetcher,
@@ -56,10 +57,11 @@ func NewCookieSyncEndpoint(
 		chooser: usersync.NewChooser(syncersByBidder),
 		config:  config,
 		privacyConfig: usersyncPrivacyConfig{
-			gdprConfig:      config.GDPR,
-			gdprPermissions: gdprPermissions,
-			ccpaEnforce:     config.CCPA.Enforce,
-			bidderHashSet:   bidderHashSet,
+			gdprConfig:             config.GDPR,
+			gdprPermissionsBuilder: gdprPermsBuilder,
+			tcf2ConfigBuilder:      tcf2CfgBuilder,
+			ccpaEnforce:            config.CCPA.Enforce,
+			bidderHashSet:          bidderHashSet,
 		},
 		metrics:         metrics,
 		pbsAnalytics:    pbsAnalytics,
@@ -169,6 +171,14 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr
 		return usersync.Request{}, privacy.Policies{}, err
 	}
 
+	gdprRequestInfo := gdpr.RequestInfo{
+		Consent:    request.GDPRConsent,
+		GDPRSignal: gdprSignal,
+	}
+
+	tcf2Cfg := c.privacyConfig.tcf2ConfigBuilder(c.privacyConfig.gdprConfig.TCF2, account.GDPR)
+	gdprPerms := c.privacyConfig.gdprPermissionsBuilder(tcf2Cfg, gdprRequestInfo)
+
 	rx := usersync.Request{
 		Bidders: request.Bidders,
 		Cooperative: usersync.Cooperative{
@@ -177,9 +187,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr
 		},
 		Limit: request.Limit,
 		Privacy: usersyncPrivacy{
-			gdprPermissions:  c.privacyConfig.gdprPermissions,
-			gdprSignal:       gdprSignal,
-			gdprConsent:      request.GDPRConsent,
+			gdprPermissions:  gdprPerms,
 			ccpaParsedPolicy: ccpaParsedPolicy,
 		},
 		SyncTypeFilter: syncTypeFilter,
@@ -418,26 +426,25 @@ type cookieSyncResponseSync struct {
 }
 
 type usersyncPrivacyConfig struct {
-	gdprConfig      config.GDPR
-	gdprPermissions gdpr.Permissions
-	ccpaEnforce     bool
-	bidderHashSet   map[string]struct{}
+	gdprConfig             config.GDPR
+	gdprPermissionsBuilder gdpr.PermissionsBuilder
+	tcf2ConfigBuilder      gdpr.TCF2ConfigBuilder
+	ccpaEnforce            bool
+	bidderHashSet          map[string]struct{}
 }
 
 type usersyncPrivacy struct {
 	gdprPermissions  gdpr.Permissions
-	gdprSignal       gdpr.Signal
-	gdprConsent      string
 	ccpaParsedPolicy ccpa.ParsedPolicy
 }
 
 func (p usersyncPrivacy) GDPRAllowsHostCookie() bool {
-	allowCookie, err := p.gdprPermissions.HostCookiesAllowed(context.Background(), p.gdprSignal, p.gdprConsent)
+	allowCookie, err := p.gdprPermissions.HostCookiesAllowed(context.Background())
 	return err == nil && allowCookie
 }
 
 func (p usersyncPrivacy) GDPRAllowsBidderSync(bidder string) bool {
-	allowSync, err := p.gdprPermissions.BidderSyncAllowed(context.Background(), openrtb_ext.BidderName(bidder), p.gdprSignal, p.gdprConsent)
+	allowSync, err := p.gdprPermissions.BidderSyncAllowed(context.Background(), openrtb_ext.BidderName(bidder))
 	return err == nil && allowSync
 }
 
diff --git a/endpoints/setuid.go b/endpoints/setuid.go
index 2dc76e57..716044a2 100644
--- a/endpoints/setuid.go
+++ b/endpoints/setuid.go
@@ -28,7 +28,7 @@ const (
 	chromeiOSStrLen = len(chromeiOSStr)
 )
 
-func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, perms gdpr.Permissions, pbsanalytics analytics.PBSAnalyticsModule, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle {
+func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, pbsanalytics analytics.PBSAnalyticsModule, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle {
 	cookieTTL := time.Duration(cfg.HostCookie.TTL) * 24 * time.Hour
 
 	// convert map of syncers by bidder to map of syncers by key
@@ -79,8 +79,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use
 		if accountID == "" {
 			accountID = metrics.PublisherUnknown
 		}
-		// the fetched account is not currently used. It'll be used to get account-specific GDPR config in a future PR.
-		_, fetchErrs := accountService.GetAccount(context.Background(), cfg, accountsFetcher, accountID)
+		account, fetchErrs := accountService.GetAccount(context.Background(), cfg, accountsFetcher, accountID)
 		if len(fetchErrs) > 0 {
 			w.WriteHeader(http.StatusBadRequest)
 			w.Write([]byte(combineErrors(fetchErrs).Error()))
@@ -89,7 +88,9 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use
 			return
 		}
 
-		if shouldReturn, status, body := preventSyncsGDPR(query.Get("gdpr"), query.Get("gdpr_consent"), perms); shouldReturn {
+		tcf2Cfg := tcf2CfgBuilder(cfg.GDPR.TCF2, account.GDPR)
+
+		if shouldReturn, status, body := preventSyncsGDPR(query.Get("gdpr"), query.Get("gdpr_consent"), gdprPermsBuilder, tcf2Cfg); shouldReturn {
 			w.WriteHeader(status)
 			w.Write([]byte(body))
 			switch status {
@@ -201,7 +202,7 @@ func checkChromeBrowserVersion(ua string, index int, chromeStrLength int) bool {
 	return result
 }
 
-func preventSyncsGDPR(gdprEnabled string, gdprConsent string, perms gdpr.Permissions) (shouldReturn bool, status int, body string) {
+func preventSyncsGDPR(gdprEnabled string, gdprConsent string, permsBuilder gdpr.PermissionsBuilder, tcf2Cfg gdpr.TCF2ConfigReader) (shouldReturn bool, status int, body string) {
 	if gdprEnabled != "" && gdprEnabled != "0" && gdprEnabled != "1" {
 		return true, http.StatusBadRequest, "the gdpr query param must be either 0 or 1. You gave " + gdprEnabled
 	}
@@ -216,7 +217,14 @@ func preventSyncsGDPR(gdprEnabled string, gdprConsent string, perms gdpr.Permiss
 		gdprSignal = gdpr.Signal(i)
 	}
 
-	allowed, err := perms.HostCookiesAllowed(context.Background(), gdprSignal, gdprConsent)
+	gdprRequestInfo := gdpr.RequestInfo{
+		Consent:    gdprConsent,
+		GDPRSignal: gdprSignal,
+	}
+
+	perms := permsBuilder(tcf2Cfg, gdprRequestInfo)
+
+	allowed, err := perms.HostCookiesAllowed(context.Background())
 	if err != nil {
 		if _, ok := err.(*gdpr.ErrorMalformedConsent); ok {
 			return true, http.StatusBadRequest, "gdpr_consent was invalid. " + err.Error()
diff --git a/exchange/utils.go b/exchange/utils.go
index 103a7f7e..610a1587 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -120,7 +120,14 @@ func cleanOpenRTBRequests(ctx context.Context,
 			version := int(parsedConsent.Version())
 			privacyLabels.GDPRTCFVersion = metrics.TCFVersionToValue(version)
 		}
-		gdprPerms = gdprPermsBuilder(tcf2Cfg)
+
+		gdprRequestInfo := gdpr.RequestInfo{
+			AliasGVLIDs: aliasesGVLIDs,
+			Consent:     consent,
+			GDPRSignal:  gdprSignal,
+			PublisherID: auctionReq.LegacyLabels.PubID,
+		}
+		gdprPerms = gdprPermsBuilder(tcf2Cfg, gdprRequestInfo)
 	}
 
 	// bidder level privacy policies
@@ -132,8 +139,7 @@ func cleanOpenRTBRequests(ctx context.Context,
 
 		// GDPR
 		if gdprEnforced {
-			var publisherID = auctionReq.LegacyLabels.PubID
-			auctionPermissions, err := gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName, publisherID, gdprSignal, consent, aliasesGVLIDs)
+			auctionPermissions, err := gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName)
 			bidRequestAllowed = auctionPermissions.AllowBidRequest
 
 			if err == nil {
@@ -155,7 +161,6 @@ func cleanOpenRTBRequests(ctx context.Context,
 
 		if bidRequestAllowed {
 			privacyEnforcement.Apply(bidderRequest.BidRequest)
-
 			allowedBidderRequests = append(allowedBidderRequests, bidderRequest)
 		}
 	}
@@ -737,6 +742,11 @@ func applyFPD(fpd *firstpartydata.ResolvedFirstPartyData, bidReq *openrtb2.BidRe
 		bidReq.App = fpd.App
 	}
 	if fpd.User != nil {
+		//BuyerUID is a value obtained between fpd extraction and fpd application.
+		//BuyerUID needs to be set back to fpd before applying this fpd to final bidder request
+		if bidReq.User != nil && len(bidReq.User.BuyerUID) > 0 {
+			fpd.User.BuyerUID = bidReq.User.BuyerUID
+		}
 		bidReq.User = fpd.User
 	}
 }
diff --git a/gdpr/gdpr.go b/gdpr/gdpr.go
index a1ad10b8..efad6a81 100644
--- a/gdpr/gdpr.go
+++ b/gdpr/gdpr.go
@@ -11,31 +11,38 @@ type Permissions interface {
 	// Determines whether or not the host company is allowed to read/write cookies.
 	//
 	// If the consent string was nonsensical, the returned error will be an ErrorMalformedConsent.
-	HostCookiesAllowed(ctx context.Context, gdprSignal Signal, consent string) (bool, error)
+	HostCookiesAllowed(ctx context.Context) (bool, error)
 
 	// Determines whether or not the given bidder is allowed to user personal info for ad targeting.
 	//
 	// If the consent string was nonsensical, the returned error will be an ErrorMalformedConsent.
-	BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdprSignal Signal, consent string) (bool, error)
+	BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error)
 
 	// Determines whether or not to send PI information to a bidder, or mask it out.
 	//
 	// If the consent string was nonsensical, the returned error will be an ErrorMalformedConsent.
-	AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal Signal, consent string, aliasGVLIDs map[string]uint16) (permissions AuctionPermissions, err error)
+	AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error)
 }
 
-type PermissionsBuilder func(TCF2ConfigReader) Permissions
+type PermissionsBuilder func(TCF2ConfigReader, RequestInfo) Permissions
+
+type RequestInfo struct {
+	AliasGVLIDs map[string]uint16
+	Consent     string
+	GDPRSignal  Signal
+	PublisherID string
+}
 
 // NewPermissionsBuilder is of type PermissionsBuilderMaker
 // It takes host config data used to configure the builder function it returns
 func NewPermissionsBuilder(cfg config.GDPR, gvlVendorIDs map[openrtb_ext.BidderName]uint16, vendorListFetcher VendorListFetcher) PermissionsBuilder {
-	return func(tcf2Cfg TCF2ConfigReader) Permissions {
-		return NewPermissions(cfg, tcf2Cfg, gvlVendorIDs, vendorListFetcher)
+	return func(tcf2Cfg TCF2ConfigReader, requestInfo RequestInfo) Permissions {
+		return NewPermissions(cfg, tcf2Cfg, gvlVendorIDs, vendorListFetcher, requestInfo)
 	}
 }
 
 // NewPermissions gets a per-request Permissions object that can then be used to check GDPR permissions for a given bidder.
-func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[openrtb_ext.BidderName]uint16, fetcher VendorListFetcher) Permissions {
+func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[openrtb_ext.BidderName]uint16, fetcher VendorListFetcher, requestInfo RequestInfo) Permissions {
 	if !cfg.Enabled {
 		return &AlwaysAllow{}
 	}
@@ -47,6 +54,10 @@ func NewPermissions(cfg config.GDPR, tcf2Config TCF2ConfigReader, vendorIDs map[
 		nonStandardPublishers: cfg.NonStandardPublisherMap,
 		cfg:                   tcf2Config,
 		vendorIDs:             vendorIDs,
+		publisherID:           requestInfo.PublisherID,
+		gdprSignal:            SignalNormalize(requestInfo.GDPRSignal, cfg.DefaultValue),
+		consent:               requestInfo.Consent,
+		aliasGVLIDs:           requestInfo.AliasGVLIDs,
 	}
 
 	if cfg.HostVendorID == 0 {
diff --git a/gdpr/impl.go b/gdpr/impl.go
index fd08d839..5116374d 100644
--- a/gdpr/impl.go
+++ b/gdpr/impl.go
@@ -20,66 +20,60 @@ type permissionsImpl struct {
 	nonStandardPublishers map[string]struct{}
 	cfg                   TCF2ConfigReader
 	vendorIDs             map[openrtb_ext.BidderName]uint16
+	consent               string
+	gdprSignal            Signal
+	publisherID           string
+	aliasGVLIDs           map[string]uint16
 }
 
-func (p *permissionsImpl) HostCookiesAllowed(ctx context.Context, gdprSignal Signal, consent string) (bool, error) {
-	gdprSignal = SignalNormalize(gdprSignal, p.gdprDefaultValue)
-
-	if gdprSignal == SignalNo {
+func (p *permissionsImpl) HostCookiesAllowed(ctx context.Context) (bool, error) {
+	if p.gdprSignal != SignalYes {
 		return true, nil
 	}
 
-	return p.allowSync(ctx, uint16(p.hostVendorID), consent, false)
+	return p.allowSync(ctx, uint16(p.hostVendorID), false)
 }
 
-func (p *permissionsImpl) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdprSignal Signal, consent string) (bool, error) {
-	gdprSignal = SignalNormalize(gdprSignal, p.gdprDefaultValue)
-
-	if gdprSignal == SignalNo {
+func (p *permissionsImpl) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
+	if p.gdprSignal != SignalYes {
 		return true, nil
 	}
 
 	id, ok := p.vendorIDs[bidder]
 	if ok {
 		vendorException := p.cfg.PurposeVendorException(consentconstants.Purpose(1), bidder)
-		return p.allowSync(ctx, id, consent, vendorException)
+		return p.allowSync(ctx, id, vendorException)
 	}
 
 	return false, nil
 }
 
-func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal Signal, consent string, aliasGVLIDs map[string]uint16) (permissions AuctionPermissions, err error) {
-	if _, ok := p.nonStandardPublishers[PublisherID]; ok {
+func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) {
+	if _, ok := p.nonStandardPublishers[p.publisherID]; ok {
 		return AllowAll, nil
 	}
 
-	gdprSignal = SignalNormalize(gdprSignal, p.gdprDefaultValue)
-
-	if gdprSignal == SignalNo {
+	if p.gdprSignal != SignalYes {
 		return AllowAll, nil
 	}
 
-	if consent == "" && gdprSignal == SignalYes {
+	if p.consent == "" {
 		return DenyAll, nil
 	}
 
 	weakVendorEnforcement := p.cfg.BasicEnforcementVendor(bidder)
 
-	if id, ok := p.resolveVendorId(bidderCoreName, bidder, aliasGVLIDs); ok {
-		return p.allowActivities(ctx, id, bidderCoreName, consent, weakVendorEnforcement)
+	if id, ok := p.resolveVendorId(bidderCoreName, bidder); ok {
+		return p.allowActivities(ctx, id, bidderCoreName, weakVendorEnforcement)
 	} else if weakVendorEnforcement {
-		return p.allowActivities(ctx, 0, bidderCoreName, consent, weakVendorEnforcement)
+		return p.allowActivities(ctx, 0, bidderCoreName, weakVendorEnforcement)
 	}
 
-	return p.defaultVendorPermissions()
-}
-
-func (p *permissionsImpl) defaultVendorPermissions() (permissions AuctionPermissions, err error) {
 	return DenyAll, nil
 }
 
-func (p *permissionsImpl) resolveVendorId(bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, aliasGVLIDs map[string]uint16) (id uint16, ok bool) {
-	if id, ok = aliasGVLIDs[string(bidder)]; ok {
+func (p *permissionsImpl) resolveVendorId(bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (id uint16, ok bool) {
+	if id, ok = p.aliasGVLIDs[string(bidder)]; ok {
 		return id, ok
 	}
 
@@ -88,12 +82,12 @@ func (p *permissionsImpl) resolveVendorId(bidderCoreName openrtb_ext.BidderName,
 	return id, ok
 }
 
-func (p *permissionsImpl) allowSync(ctx context.Context, vendorID uint16, consent string, vendorException bool) (bool, error) {
-	if consent == "" {
+func (p *permissionsImpl) allowSync(ctx context.Context, vendorID uint16, vendorException bool) (bool, error) {
+	if p.consent == "" {
 		return false, nil
 	}
 
-	parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, consent)
+	parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, p.consent)
 	if err != nil {
 		return false, err
 	}
@@ -119,8 +113,8 @@ func (p *permissionsImpl) allowSync(ctx context.Context, vendorID uint16, consen
 	return p.checkPurpose(consentMeta, vendor, vendorID, tcf2ConsentConstants.InfoStorageAccess, enforceVendors, vendorException, false), nil
 }
 
-func (p *permissionsImpl) allowActivities(ctx context.Context, vendorID uint16, bidder openrtb_ext.BidderName, consent string, weakVendorEnforcement bool) (AuctionPermissions, error) {
-	parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, consent)
+func (p *permissionsImpl) allowActivities(ctx context.Context, vendorID uint16, bidder openrtb_ext.BidderName, weakVendorEnforcement bool) (AuctionPermissions, error) {
+	parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, p.consent)
 	if err != nil {
 		return DenyAll, err
 	}
@@ -259,22 +253,22 @@ type AllowHostCookies struct {
 }
 
 // HostCookiesAllowed always returns true
-func (p *AllowHostCookies) HostCookiesAllowed(ctx context.Context, gdprSignal Signal, consent string) (bool, error) {
+func (p *AllowHostCookies) HostCookiesAllowed(ctx context.Context) (bool, error) {
 	return true, nil
 }
 
 // Exporting to allow for easy test setups
 type AlwaysAllow struct{}
 
-func (a AlwaysAllow) HostCookiesAllowed(ctx context.Context, gdprSignal Signal, consent string) (bool, error) {
+func (a AlwaysAllow) HostCookiesAllowed(ctx context.Context) (bool, error) {
 	return true, nil
 }
 
-func (a AlwaysAllow) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdprSignal Signal, consent string) (bool, error) {
+func (a AlwaysAllow) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
 	return true, nil
 }
 
-func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal Signal, consent string, aliasGVLIDs map[string]uint16) (permissions AuctionPermissions, err error) {
+func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) {
 	return AllowAll, nil
 }
 
diff --git a/router/router.go b/router/router.go
index 65fa8ef9..abd407de 100644
--- a/router/router.go
+++ b/router/router.go
@@ -200,7 +200,6 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R
 
 	gvlVendorIDs := bidderInfos.ToGVLVendorIDMap()
 	vendorListFetcher := gdpr.NewVendorListFetcher(context.Background(), cfg.GDPR, generalHttpClient, gdpr.VendorListURLMaker)
-	gdprPerms := gdpr.NewPermissions(cfg.GDPR, &cfg.GDPR.TCF2, gvlVendorIDs, vendorListFetcher)
 	gdprPermsBuilder := gdpr.NewPermissionsBuilder(cfg.GDPR, gvlVendorIDs, vendorListFetcher)
 	tcf2CfgBuilder := gdpr.NewTCF2Config
 
@@ -240,7 +239,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R
 	r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(bidderInfos, defaultAliases))
 	r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(bidderInfos, cfg.Adapters, defaultAliases))
 	r.GET("/bidders/params", NewJsonDirectoryServer(schemaDirectory, paramsValidator, defaultAliases))
-	r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPerms, r.MetricsEngine, pbsAnalytics, accounts, activeBidders).Handle)
+	r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, pbsAnalytics, accounts, activeBidders).Handle)
 	r.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse))
 	r.GET("/", serveIndex)
 	r.Handler("GET", "/version", endpoints.NewVersionEndpoint(version.Ver, version.Rev))
@@ -262,7 +261,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R
 		RecaptchaSecret:  cfg.RecaptchaSecret,
 	}
 
-	r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPerms, pbsAnalytics, accounts, r.MetricsEngine))
+	r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, pbsAnalytics, accounts, r.MetricsEngine))
 	r.GET("/getuids", endpoints.NewGetUIDsEndpoint(cfg.HostCookie))
 	r.POST("/optout", userSyncDeps.OptOut)
 	r.GET("/optout", userSyncDeps.OptOut)


Test patch:
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json b/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json
index e195429c..d1dfa0ad 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json
@@ -1,109 +1,110 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "user": {
-            "id": "1kjh3429kjh295jkl",
-            "ext": {
-                "consent": "CONSENT_STRING"
-            }
-        },
-        "regs": {
-            "ext": {
-                "gdpr": 1
-            }
-        },
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123"
-                    }
-                }
-            }
-        ]
-    },
-
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?consentString=CONSENT_STRING&format=json&gdpr=1&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-imp-id"
-                        }
-                    ],
-                    "metaData": {
-                        "usi": "1kjh3429kjh295jkl"
-                    },
-                    "context": "unknown"
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": "980",
-                                    "creativeHeight": "240",
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [
-        {
-            "bids": [
-                {
-                    "bid": {
-                        "id": "adn-id-1559784094",
-                        "impid": "test-imp-id",
-                        "price": 20000,
-                        "adm": "<ADCODE>",
-                        "adid": "adn-id-1559784094",
-                        "adomain": ["google.com"],
-                        "cid": "q7y9qm5b0xt9htrv",
-                        "crid": "jn9hpzvlsf8cpdmm",
-                        "w": 980,
-                        "h": 240
-                    },
-                    "type": "banner"
-                }
-            ],
-            "currency": "NOK"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"user": {
+			"id": "1kjh3429kjh295jkl",
+			"ext": {
+				"consent": "CONSENT_STRING"
+			}
+		},
+		"regs": {
+			"ext": {
+				"gdpr": 1
+			}
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?consentString=CONSENT_STRING&format=json&gdpr=1&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"metaData": {
+						"usi": "1kjh3429kjh295jkl"
+					},
+					"context": "unknown"
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-imp-id",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json b/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json
index 8305bcdb..b4788ba6 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json
@@ -1,101 +1,102 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "user": {
-            "id": "1kjh3429kjh295jkl"
-        },
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123"
-                    }
-                }
-            }
-        ]
-    },
-
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-imp-id"
-                        }
-                    ],
-                    "metaData": {
-                        "usi": "1kjh3429kjh295jkl"
-                    },
-                    "context": "unknown"
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": "980",
-                                    "creativeHeight": "240",
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [
-        {
-            "bids": [
-                {
-                    "bid": {
-                        "id": "adn-id-1559784094",
-                        "impid": "test-imp-id",
-                        "price": 20000,
-                        "adm": "<ADCODE>",
-                        "adid": "adn-id-1559784094",
-                        "adomain": ["google.com"],
-                        "cid": "q7y9qm5b0xt9htrv",
-                        "crid": "jn9hpzvlsf8cpdmm",
-                        "w": 980,
-                        "h": 240
-                    },
-                    "type": "banner"
-                }
-            ],
-            "currency": "NOK"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"user": {
+			"id": "1kjh3429kjh295jkl"
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"metaData": {
+						"usi": "1kjh3429kjh295jkl"
+					},
+					"context": "unknown"
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-imp-id",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json
new file mode 100644
index 00000000..f352e11d
--- /dev/null
+++ b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json
@@ -0,0 +1,105 @@
+{
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"user": {
+			"id": "1kjh3429kjh295jkl"
+		},
+		"regs": {
+			"ext": {}
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"metaData": {
+						"usi": "1kjh3429kjh295jkl"
+					},
+					"context": "unknown"
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-imp-id",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
+}
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json
new file mode 100644
index 00000000..9c56b4cd
--- /dev/null
+++ b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json
@@ -0,0 +1,104 @@
+{
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"user": {
+			"id": "1kjh3429kjh295jkl"
+		},
+		"regs": {
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"metaData": {
+						"usi": "1kjh3429kjh295jkl"
+					},
+					"context": "unknown"
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-imp-id",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
+}
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json
index ba388f1d..51204648 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json
@@ -1,84 +1,87 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "site": {
-            "page": "prebid.org"
-        },
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123"
-                    }
-                }
-            }
-        ]
-    },
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"site": {
+			"page": "prebid.org"
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"context": "prebid.org",
+					"metaData": {
 
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-imp-id"
-                        }
-                    ],
-                    "context": "prebid.org",
-                    "metaData": {}
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": "abc",
-                                    "creativeHeight": 240,
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [],
-    "expectedMakeBidsErrors": [
-        {
-            "value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeHeight of type string",
-            "comparison": "literal"
-        }
-    ]
+					}
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "abc",
+									"creativeHeight": 240,
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+
+	],
+	"expectedMakeBidsErrors": [
+		{
+			"value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeHeight of type string",
+			"comparison": "literal"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/native-error.json b/adapters/adnuntius/adnuntiustest/supplemental/native-error.json
index a8203e58..cf21ba0e 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/native-error.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/native-error.json
@@ -1,25 +1,24 @@
 {
-    "mockBidRequest": {
-        "id": "unsupported-native-request",
-        "imp": [
-            {
-                "id": "unsupported-native-imp",
-                "native": {
-                    "ver": "1.1"
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "1"
-                    }
-                }
-            }
-        ]
-    },
-
-    "expectedMakeRequestsErrors": [
-        {
-            "value": "ignoring imp id=unsupported-native-imp, Adnuntius supports only Banner",
-            "comparison": "literal"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "unsupported-native-request",
+		"imp": [
+			{
+				"id": "unsupported-native-imp",
+				"native": {
+					"ver": "1.1"
+				},
+				"ext": {
+					"bidder": {
+						"auId": "1"
+					}
+				}
+			}
+		]
+	},
+	"expectedMakeRequestsErrors": [
+		{
+			"value": "ignoring imp id=unsupported-native-imp, Adnuntius supports only Banner",
+			"comparison": "literal"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
index 96ddff85..a0c87682 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
@@ -1,122 +1,123 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "user": {
-            "id": "1kjh3429kjh295jkl",
-            "ext": {
-                "consent": "CONSENT_STRING"
-            }
-        },
-        "device": {
-            "ip": "158.174.81.143",
-            "ua": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
-        },
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123"
-                    }
-                }
-            }
-        ]
-    },
-
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "headers": {
-                    "Content-Type": [
-                        "application/json;charset=utf-8"
-                    ],
-                    "Accept": [
-                        "application/json"
-                    ],
-                    "X-Forwarded-For": [
-                        "158.174.81.143"
-                    ],
-                    "User-Agent": [
-                        "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
-                    ]
-                },
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-imp-id"
-                        }
-                    ],
-                    "metaData": {
-                        "usi": "1kjh3429kjh295jkl"
-                    },
-                    "context": "unknown"
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": "980",
-                                    "creativeHeight": "240",
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [
-        {
-            "bids": [
-                {
-                    "bid": {
-                        "id": "adn-id-1559784094",
-                        "impid": "test-imp-id",
-                        "price": 20000,
-                        "adm": "<ADCODE>",
-                        "adid": "adn-id-1559784094",
-                        "adomain": ["google.com"],
-                        "cid": "q7y9qm5b0xt9htrv",
-                        "crid": "jn9hpzvlsf8cpdmm",
-                        "w": 980,
-                        "h": 240
-                    },
-                    "type": "banner"
-                }
-            ],
-            "currency": "NOK"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"user": {
+			"id": "1kjh3429kjh295jkl",
+			"ext": {
+				"consent": "CONSENT_STRING"
+			}
+		},
+		"device": {
+			"ip": "158.174.81.143",
+			"ua": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"headers": {
+					"Content-Type": [
+						"application/json;charset=utf-8"
+					],
+					"Accept": [
+						"application/json"
+					],
+					"X-Forwarded-For": [
+						"158.174.81.143"
+					],
+					"User-Agent": [
+						"Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
+					]
+				},
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"metaData": {
+						"usi": "1kjh3429kjh295jkl"
+					},
+					"context": "unknown"
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-imp-id",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/status-400.json b/adapters/adnuntius/adnuntiustest/supplemental/status-400.json
index c6da39da..70441b7b 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/status-400.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/status-400.json
@@ -1,54 +1,58 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auI": "1"
-                    }
-                }
-            }
-        ]
-    },
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "",
-                            "targetId": "-test-imp-id"
-                        }
-                    ],
-                    "context": "unknown",
-                    "metaData": {}
-                }
-            },
-            "mockResponse": {
-                "status": 400,
-                "body": {}
-            }
-        }
-    ],
-    "expectedMakeBidsErrors": [
-        {
-            "value": "Status code: 400, Request malformed",
-            "comparison": "literal"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auI": "1"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "",
+							"targetId": "-test-imp-id"
+						}
+					],
+					"context": "unknown",
+					"metaData": {
+
+					}
+				}
+			},
+			"mockResponse": {
+				"status": 400,
+				"body": {
+
+				}
+			}
+		}
+	],
+	"expectedMakeBidsErrors": [
+		{
+			"value": "Status code: 400, Request malformed",
+			"comparison": "literal"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json b/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json
index 727cf194..28b892bd 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json
@@ -1,97 +1,100 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "imp": [
-            {
-                "id": "test-network",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123",
-                        "network": "test"
-                    }
-                }
-            }
-        ]
-    },
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"imp": [
+			{
+				"id": "test-network",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123",
+						"network": "test"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-network"
+						}
+					],
+					"context": "unknown",
+					"metaData": {
 
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-network"
-                        }
-                    ],
-                    "context": "unknown",
-                    "metaData": {}
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": "980",
-                                    "creativeHeight": "240",
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [
-        {
-            "bids": [
-                {
-                    "bid": {
-                        "id": "adn-id-1559784094",
-                        "impid": "test-network",
-                        "price": 20000,
-                        "adm": "<ADCODE>",
-                        "adid": "adn-id-1559784094",
-                        "adomain": ["google.com"],
-                        "cid": "q7y9qm5b0xt9htrv",
-                        "crid": "jn9hpzvlsf8cpdmm",
-                        "w": 980,
-                        "h": 240
-                    },
-                    "type": "banner"
-                }
-            ],
-            "currency": "NOK"
-        }
-    ]
+					}
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": "980",
+									"creativeHeight": "240",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+		{
+			"bids": [
+				{
+					"bid": {
+						"id": "adn-id-1559784094",
+						"impid": "test-network",
+						"price": 20000,
+						"adm": "<ADCODE>",
+						"adid": "adn-id-1559784094",
+						"adomain": [
+							"google.com"
+						],
+						"cid": "q7y9qm5b0xt9htrv",
+						"crid": "jn9hpzvlsf8cpdmm",
+						"w": 980,
+						"h": 240
+					},
+					"type": "banner"
+				}
+			],
+			"currency": "NOK"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/video-error.json b/adapters/adnuntius/adnuntiustest/supplemental/video-error.json
index 357cb165..ed22dc54 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/video-error.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/video-error.json
@@ -1,26 +1,25 @@
 {
-    "mockBidRequest": {
-        "id": "unsupported-native-request",
-        "imp": [
-            {
-                "id": "unsupported-native-imp",
-                "video": {
-                    "w": 728,
-                    "h": 90
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "1"
-                    }
-                }
-            }
-        ]
-    },
-
-    "expectedMakeRequestsErrors": [
-        {
-            "value": "ignoring imp id=unsupported-native-imp, Adnuntius supports only Banner",
-            "comparison": "literal"
-        }
-    ]
+	"mockBidRequest": {
+		"id": "unsupported-native-request",
+		"imp": [
+			{
+				"id": "unsupported-native-imp",
+				"video": {
+					"w": 728,
+					"h": 90
+				},
+				"ext": {
+					"bidder": {
+						"auId": "1"
+					}
+				}
+			}
+		]
+	},
+	"expectedMakeRequestsErrors": [
+		{
+			"value": "ignoring imp id=unsupported-native-imp, Adnuntius supports only Banner",
+			"comparison": "literal"
+		}
+	]
 }
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json
index 26598411..14a1e833 100644
--- a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json
+++ b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json
@@ -1,84 +1,87 @@
 {
-    "mockBidRequest": {
-        "id": "test-request-id",
-        "site": {
-            "page": "prebid.org"
-        },
-        "imp": [
-            {
-                "id": "test-imp-id",
-                "banner": {
-                    "format": [
-                        {
-                            "w": 300,
-                            "h": 250
-                        },
-                        {
-                            "w": 300,
-                            "h": 600
-                        }
-                    ]
-                },
-                "ext": {
-                    "bidder": {
-                        "auId": "123"
-                    }
-                }
-            }
-        ]
-    },
+	"mockBidRequest": {
+		"id": "test-request-id",
+		"site": {
+			"page": "prebid.org"
+		},
+		"imp": [
+			{
+				"id": "test-imp-id",
+				"banner": {
+					"format": [
+						{
+							"w": 300,
+							"h": 250
+						},
+						{
+							"w": 300,
+							"h": 600
+						}
+					]
+				},
+				"ext": {
+					"bidder": {
+						"auId": "123"
+					}
+				}
+			}
+		]
+	},
+	"httpCalls": [
+		{
+			"expectedRequest": {
+				"uri": "http://whatever.url?format=json&tzo=0",
+				"body": {
+					"adUnits": [
+						{
+							"auId": "123",
+							"targetId": "123-test-imp-id"
+						}
+					],
+					"context": "prebid.org",
+					"metaData": {
 
-    "httpCalls": [
-        {
-            "expectedRequest": {
-                "uri": "http://whatever.url?format=json&tzo=0",
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "123",
-                            "targetId": "123-test-imp-id"
-                        }
-                    ],
-                    "context": "prebid.org",
-                    "metaData": {}
-                }
-            },
-            "mockResponse": {
-                "status": 200,
-                "body": {
-                    "adUnits": [
-                        {
-                            "auId": "0000000000000123",
-                            "targetId": "123-test-imp-id",
-                            "html": "<ADCODE>",
-                            "responseId": "adn-rsp-900646517",
-                            "ads": [
-                                {
-                                    "destinationUrls": {
-                                        "url": "http://www.google.com"
-                                    },
-                                    "bid": {
-                                        "amount": 20.0,
-                                        "currency": "NOK"
-                                    },
-                                    "adId": "adn-id-1559784094",
-                                    "creativeWidth": 980,
-                                    "creativeHeight": "abc",
-                                    "creativeId": "jn9hpzvlsf8cpdmm",
-                                    "lineItemId": "q7y9qm5b0xt9htrv"
-                                }
-                            ]
-                        }
-                    ]
-                }
-            }
-        }
-    ],
-    "expectedBidResponses": [],
-    "expectedMakeBidsErrors": [
-        {
-            "value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeWidth of type string",
-            "comparison": "literal"
-        }
-    ]
+					}
+				}
+			},
+			"mockResponse": {
+				"status": 200,
+				"body": {
+					"adUnits": [
+						{
+							"auId": "0000000000000123",
+							"targetId": "123-test-imp-id",
+							"html": "<ADCODE>",
+							"responseId": "adn-rsp-900646517",
+							"ads": [
+								{
+									"destinationUrls": {
+										"url": "http://www.google.com"
+									},
+									"bid": {
+										"amount": 20.0,
+										"currency": "NOK"
+									},
+									"adId": "adn-id-1559784094",
+									"creativeWidth": 980,
+									"creativeHeight": "abc",
+									"creativeId": "jn9hpzvlsf8cpdmm",
+									"lineItemId": "q7y9qm5b0xt9htrv"
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	],
+	"expectedBidResponses": [
+
+	],
+	"expectedMakeBidsErrors": [
+		{
+			"value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeWidth of type string",
+			"comparison": "literal"
+		}
+	]
 }
diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go
index efbb57a4..171b1b24 100644
--- a/endpoints/cookie_sync_test.go
+++ b/endpoints/cookie_sync_test.go
@@ -28,8 +28,13 @@ import (
 
 func TestNewCookieSyncEndpoint(t *testing.T) {
 	var (
-		syncersByBidder   = map[string]usersync.Syncer{"a": &MockSyncer{}}
-		gdprPerms         = MockGDPRPerms{}
+		syncersByBidder  = map[string]usersync.Syncer{"a": &MockSyncer{}}
+		gdprPermsBuilder = fakePermissionsBuilder{
+			permissions: &fakePermissions{},
+		}.Builder
+		tcf2ConfigBuilder = fakeTCF2ConfigBuilder{
+			cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+		}.Builder
 		configUserSync    = config.UserSync{Cooperative: config.UserSyncCooperative{EnabledByDefault: true}}
 		configHostCookie  = config.HostCookie{Family: "foo"}
 		configGDPR        = config.GDPR{HostVendorID: 42}
@@ -48,12 +53,14 @@ func TestNewCookieSyncEndpoint(t *testing.T) {
 			GDPR:       configGDPR,
 			CCPA:       config.CCPA{Enforce: configCCPAEnforce},
 		},
-		&gdprPerms,
+		gdprPermsBuilder,
+		tcf2ConfigBuilder,
 		&metrics,
 		&analytics,
 		&fetcher,
 		bidders,
 	)
+	result := endpoint.(*cookieSyncEndpoint)
 
 	expected := &cookieSyncEndpoint{
 		chooser: usersync.NewChooser(syncersByBidder),
@@ -64,17 +71,28 @@ func TestNewCookieSyncEndpoint(t *testing.T) {
 			CCPA:       config.CCPA{Enforce: configCCPAEnforce},
 		},
 		privacyConfig: usersyncPrivacyConfig{
-			gdprConfig:      configGDPR,
-			gdprPermissions: &gdprPerms,
-			ccpaEnforce:     configCCPAEnforce,
-			bidderHashSet:   map[string]struct{}{"bidderA": {}, "bidderB": {}},
+			gdprConfig:             configGDPR,
+			gdprPermissionsBuilder: gdprPermsBuilder,
+			tcf2ConfigBuilder:      tcf2ConfigBuilder,
+			ccpaEnforce:            configCCPAEnforce,
+			bidderHashSet:          map[string]struct{}{"bidderA": {}, "bidderB": {}},
 		},
 		metrics:         &metrics,
 		pbsAnalytics:    &analytics,
 		accountsFetcher: &fetcher,
 	}
 
-	assert.Equal(t, expected, endpoint)
+	assert.IsType(t, &cookieSyncEndpoint{}, endpoint)
+
+	assert.Equal(t, expected.config, result.config)
+	assert.Equal(t, expected.chooser, result.chooser)
+	assert.Equal(t, expected.metrics, result.metrics)
+	assert.Equal(t, expected.pbsAnalytics, result.pbsAnalytics)
+	assert.Equal(t, expected.accountsFetcher, result.accountsFetcher)
+
+	assert.Equal(t, expected.privacyConfig.gdprConfig, result.privacyConfig.gdprConfig)
+	assert.Equal(t, expected.privacyConfig.ccpaEnforce, result.privacyConfig.ccpaEnforce)
+	assert.Equal(t, expected.privacyConfig.bidderHashSet, result.privacyConfig.bidderHashSet)
 }
 
 // usersyncPrivacy
@@ -241,6 +259,13 @@ func TestCookieSyncHandle(t *testing.T) {
 
 		fakeAccountFetcher := FakeAccountsFetcher{}
 
+		gdprPermsBuilder := fakePermissionsBuilder{
+			permissions: &fakePermissions{},
+		}.Builder
+		tcf2ConfigBuilder := fakeTCF2ConfigBuilder{
+			cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+		}.Builder
+
 		request := httptest.NewRequest("POST", "/cookiesync", test.givenBody)
 		if test.givenCookie != nil {
 			request.AddCookie(test.givenCookie.ToHTTPCookie(24 * time.Hour))
@@ -250,18 +275,24 @@ func TestCookieSyncHandle(t *testing.T) {
 
 		endpoint := cookieSyncEndpoint{
 			chooser: FakeChooser{Result: test.givenChooserResult},
-			config:  &config.Configuration{},
+			config: &config.Configuration{
+				AccountDefaults: config.Account{Disabled: false},
+			},
 			privacyConfig: usersyncPrivacyConfig{
 				gdprConfig: config.GDPR{
 					Enabled:      true,
 					DefaultValue: "0",
 				},
-				ccpaEnforce: true,
+				gdprPermissionsBuilder: gdprPermsBuilder,
+				tcf2ConfigBuilder:      tcf2ConfigBuilder,
+				ccpaEnforce:            true,
 			},
 			metrics:         &mockMetrics,
 			pbsAnalytics:    &mockAnalytics,
 			accountsFetcher: &fakeAccountFetcher,
 		}
+		assert.NoError(t, endpoint.config.MarshalAccountDefaults())
+
 		endpoint.Handle(writer, request, nil)
 
 		assert.Equal(t, test.expectedStatusCode, writer.Code, test.description+":status_code")
@@ -321,8 +352,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 				},
 				Limit: 42,
 				Privacy: usersyncPrivacy{
-					gdprSignal:       gdpr.SignalYes,
-					gdprConsent:      "anyGDPRConsent",
+					gdprPermissions:  &fakePermissions{},
 					ccpaParsedPolicy: expectedCCPAParsedPolicy,
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
@@ -365,8 +395,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 				},
 				Limit: 42,
 				Privacy: usersyncPrivacy{
-					gdprSignal:       gdpr.SignalYes,
-					gdprConsent:      "anyGDPRConsent",
+					gdprPermissions:  &fakePermissions{},
 					ccpaParsedPolicy: expectedCCPAParsedPolicy,
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
@@ -383,7 +412,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 			expectedPrivacy:  privacy.Policies{},
 			expectedRequest: usersync.Request{
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -409,7 +438,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -435,7 +464,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -461,7 +490,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -487,7 +516,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -513,7 +542,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -539,7 +568,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 					PriorityGroups: [][]string{{"a", "b", "c"}},
 				},
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -555,7 +584,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 			expectedPrivacy:  privacy.Policies{},
 			expectedRequest: usersync.Request{
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -574,7 +603,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 			},
 			expectedRequest: usersync.Request{
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -613,7 +642,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 			},
 			expectedRequest: usersync.Request{
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalNo,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -638,7 +667,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 			},
 			expectedRequest: usersync.Request{
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -683,7 +712,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 				},
 				Limit: 30,
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -714,7 +743,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 				},
 				Limit: 20,
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -745,7 +774,7 @@ func TestCookieSyncParseRequest(t *testing.T) {
 				},
 				Limit: 20,
 				Privacy: usersyncPrivacy{
-					gdprSignal: gdpr.SignalAmbiguous,
+					gdprPermissions: &fakePermissions{},
 				},
 				SyncTypeFilter: usersync.SyncTypeFilter{
 					IFrame:   usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude),
@@ -760,14 +789,23 @@ func TestCookieSyncParseRequest(t *testing.T) {
 	for _, test := range testCases {
 		httpRequest := httptest.NewRequest("POST", "/cookiesync", test.givenBody)
 
+		gdprPermsBuilder := fakePermissionsBuilder{
+			permissions: &fakePermissions{},
+		}.Builder
+		tcf2ConfigBuilder := fakeTCF2ConfigBuilder{
+			cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+		}.Builder
+
 		endpoint := cookieSyncEndpoint{
 			config: &config.Configuration{
 				UserSync:        test.givenConfig,
 				AccountRequired: test.givenAccountRequired,
 			},
 			privacyConfig: usersyncPrivacyConfig{
-				gdprConfig:  test.givenGDPRConfig,
-				ccpaEnforce: test.givenCCPAEnabled,
+				gdprConfig:             test.givenGDPRConfig,
+				gdprPermissionsBuilder: gdprPermsBuilder,
+				tcf2ConfigBuilder:      tcf2ConfigBuilder,
+				ccpaEnforce:            test.givenCCPAEnabled,
 			},
 			accountsFetcher: FakeAccountsFetcher{AccountData: map[string]json.RawMessage{
 				"TestAccount":     json.RawMessage(`{"cookie_sync": {"default_limit": 20, "max_limit": 30, "default_coop_sync": true}}`),
@@ -1545,12 +1583,10 @@ func TestUsersyncPrivacyGDPRAllowsHostCookie(t *testing.T) {
 
 	for _, test := range testCases {
 		mockPerms := MockGDPRPerms{}
-		mockPerms.On("HostCookiesAllowed", mock.Anything, gdpr.SignalYes, "anyConsent").Return(test.givenResponse, test.givenError)
+		mockPerms.On("HostCookiesAllowed", mock.Anything).Return(test.givenResponse, test.givenError)
 
 		privacy := usersyncPrivacy{
 			gdprPermissions: &mockPerms,
-			gdprSignal:      gdpr.SignalYes,
-			gdprConsent:     "anyConsent",
 		}
 
 		result := privacy.GDPRAllowsHostCookie()
@@ -1593,12 +1629,10 @@ func TestUsersyncPrivacyGDPRAllowsBidderSync(t *testing.T) {
 
 	for _, test := range testCases {
 		mockPerms := MockGDPRPerms{}
-		mockPerms.On("BidderSyncAllowed", mock.Anything, openrtb_ext.BidderName("foo"), gdpr.SignalYes, "anyConsent").Return(test.givenResponse, test.givenError)
+		mockPerms.On("BidderSyncAllowed", mock.Anything, openrtb_ext.BidderName("foo")).Return(test.givenResponse, test.givenError)
 
 		privacy := usersyncPrivacy{
 			gdprPermissions: &mockPerms,
-			gdprSignal:      gdpr.SignalYes,
-			gdprConsent:     "anyConsent",
 		}
 
 		result := privacy.GDPRAllowsBidderSync("foo")
@@ -1749,18 +1783,18 @@ type MockGDPRPerms struct {
 	mock.Mock
 }
 
-func (m *MockGDPRPerms) HostCookiesAllowed(ctx context.Context, gdprSignal gdpr.Signal, consent string) (bool, error) {
-	args := m.Called(ctx, gdprSignal, consent)
+func (m *MockGDPRPerms) HostCookiesAllowed(ctx context.Context) (bool, error) {
+	args := m.Called(ctx)
 	return args.Bool(0), args.Error(1)
 }
 
-func (m *MockGDPRPerms) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdprSignal gdpr.Signal, consent string) (bool, error) {
-	args := m.Called(ctx, bidder, gdprSignal, consent)
+func (m *MockGDPRPerms) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
+	args := m.Called(ctx, bidder)
 	return args.Bool(0), args.Error(1)
 }
 
-func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal gdpr.Signal, consent string, aliasGVLIDs map[string]uint16) (permissions gdpr.AuctionPermissions, err error) {
-	args := m.Called(ctx, bidderCoreName, bidder, PublisherID, gdprSignal, consent, aliasGVLIDs)
+func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
+	args := m.Called(ctx, bidderCoreName, bidder)
 	return args.Get(0).(gdpr.AuctionPermissions), args.Error(1)
 }
 
@@ -1769,6 +1803,11 @@ type FakeAccountsFetcher struct {
 }
 
 func (f FakeAccountsFetcher) FetchAccount(ctx context.Context, accountID string) (json.RawMessage, []error) {
+	defaultAccountJSON := json.RawMessage(`{"disabled":false}`)
+
+	if accountID == metrics.PublisherUnknown {
+		return defaultAccountJSON, nil
+	}
 	if account, ok := f.AccountData[accountID]; ok {
 		return account, nil
 	}
@@ -1788,3 +1827,20 @@ type errReader struct {
 func (r *errReader) Read(p []byte) (int, error) {
 	return 0, r.err
 }
+
+type fakePermissions struct {
+}
+
+func (p *fakePermissions) HostCookiesAllowed(ctx context.Context) (bool, error) {
+	return true, nil
+}
+
+func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
+	return true, nil
+}
+
+func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
+	return gdpr.AuctionPermissions{
+		AllowBidRequest: true,
+	}, nil
+}
diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go
index 5b76345f..c9327976 100644
--- a/endpoints/openrtb2/test_utils.go
+++ b/endpoints/openrtb2/test_utils.go
@@ -1267,7 +1267,7 @@ type fakePermissionsBuilder struct {
 	permissions gdpr.Permissions
 }
 
-func (fpb fakePermissionsBuilder) Builder(gdpr.TCF2ConfigReader) gdpr.Permissions {
+func (fpb fakePermissionsBuilder) Builder(gdpr.TCF2ConfigReader, gdpr.RequestInfo) gdpr.Permissions {
 	return fpb.permissions
 }
 
@@ -1282,15 +1282,15 @@ func (fcr fakeTCF2ConfigBuilder) Builder(hostConfig config.TCF2, accountConfig c
 type fakePermissions struct {
 }
 
-func (p *fakePermissions) HostCookiesAllowed(ctx context.Context, gdpr gdpr.Signal, consent string) (bool, error) {
+func (p *fakePermissions) HostCookiesAllowed(ctx context.Context) (bool, error) {
 	return true, nil
 }
 
-func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdpr gdpr.Signal, consent string) (bool, error) {
+func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
 	return true, nil
 }
 
-func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal gdpr.Signal, consent string, aliasGVLIDs map[string]uint16) (permissions gdpr.AuctionPermissions, err error) {
+func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
 	return gdpr.AuctionPermissions{
 		AllowBidRequest: true,
 	}, nil
diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go
index dd73d8a8..e9b32322 100644
--- a/endpoints/setuid_test.go
+++ b/endpoints/setuid_test.go
@@ -541,12 +541,22 @@ func doRequest(req *http.Request, metrics metrics.MetricsEngine, syncersBidderNa
 	cfg := config.Configuration{}
 	cfg.MarshalAccountDefaults()
 
-	perms := &mockPermsSetUID{
+	query := req.URL.Query()
+
+	perms := &fakePermsSetUID{
 		allowHost:           gdprAllowsHostCookies,
+		consent:             query.Get("gdpr_consent"),
 		errorHost:           gdprReturnsError,
 		errorMalformed:      gdprReturnsMalformedError,
 		personalInfoAllowed: true,
 	}
+	gdprPermsBuilder := fakePermissionsBuilder{
+		permissions: perms,
+	}.Builder
+	tcf2ConfigBuilder := fakeTCF2ConfigBuilder{
+		cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+	}.Builder
+
 	analytics := analyticsConf.NewPBSAnalytics(&cfg.Analytics)
 	syncersByBidder := make(map[string]usersync.Syncer)
 	for bidderName, syncerKey := range syncersBidderNameToKey {
@@ -558,7 +568,7 @@ func doRequest(req *http.Request, metrics metrics.MetricsEngine, syncersBidderNa
 		"disabled_acct": json.RawMessage(`{"disabled":true}`),
 	}}
 
-	endpoint := NewSetUIDEndpoint(&cfg, syncersByBidder, perms, analytics, fakeAccountsFetcher, metrics)
+	endpoint := NewSetUIDEndpoint(&cfg, syncersByBidder, gdprPermsBuilder, tcf2ConfigBuilder, analytics, fakeAccountsFetcher, metrics)
 	response := httptest.NewRecorder()
 	endpoint(response, req, nil)
 	return response
@@ -580,16 +590,33 @@ func parseCookieString(t *testing.T, response *httptest.ResponseRecorder) *users
 	return usersync.ParseCookie(&httpCookie)
 }
 
-type mockPermsSetUID struct {
+type fakePermissionsBuilder struct {
+	permissions gdpr.Permissions
+}
+
+func (fpb fakePermissionsBuilder) Builder(gdpr.TCF2ConfigReader, gdpr.RequestInfo) gdpr.Permissions {
+	return fpb.permissions
+}
+
+type fakeTCF2ConfigBuilder struct {
+	cfg gdpr.TCF2ConfigReader
+}
+
+func (fcr fakeTCF2ConfigBuilder) Builder(hostConfig config.TCF2, accountConfig config.AccountGDPR) gdpr.TCF2ConfigReader {
+	return fcr.cfg
+}
+
+type fakePermsSetUID struct {
 	allowHost           bool
+	consent             string
 	errorHost           bool
 	errorMalformed      bool
 	personalInfoAllowed bool
 }
 
-func (g *mockPermsSetUID) HostCookiesAllowed(ctx context.Context, gdprSignal gdpr.Signal, consent string) (bool, error) {
+func (g *fakePermsSetUID) HostCookiesAllowed(ctx context.Context) (bool, error) {
 	if g.errorMalformed {
-		return g.allowHost, &gdpr.ErrorMalformedConsent{Consent: consent, Cause: errors.New("some error")}
+		return g.allowHost, &gdpr.ErrorMalformedConsent{Consent: g.consent, Cause: errors.New("some error")}
 	}
 	if g.errorHost {
 		return g.allowHost, errors.New("something went wrong")
@@ -597,11 +624,11 @@ func (g *mockPermsSetUID) HostCookiesAllowed(ctx context.Context, gdprSignal gdp
 	return g.allowHost, nil
 }
 
-func (g *mockPermsSetUID) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdprSignal gdpr.Signal, consent string) (bool, error) {
+func (g *fakePermsSetUID) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
 	return false, nil
 }
 
-func (g *mockPermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal gdpr.Signal, consent string, aliasGVLIDs map[string]uint16) (permissions gdpr.AuctionPermissions, err error) {
+func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
 	return gdpr.AuctionPermissions{
 		AllowBidRequest: g.personalInfoAllowed,
 		PassGeo:         g.personalInfoAllowed,
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 1d12f766..dd51b3b3 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -27,15 +27,15 @@ type permissionsMock struct {
 	activitiesError error
 }
 
-func (p *permissionsMock) HostCookiesAllowed(ctx context.Context, gdpr gdpr.Signal, consent string) (bool, error) {
+func (p *permissionsMock) HostCookiesAllowed(ctx context.Context) (bool, error) {
 	return true, nil
 }
 
-func (p *permissionsMock) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName, gdpr gdpr.Signal, consent string) (bool, error) {
+func (p *permissionsMock) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) {
 	return true, nil
 }
 
-func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName, PublisherID string, gdprSignal gdpr.Signal, consent string, aliasGVLIDs map[string]uint16) (permissions gdpr.AuctionPermissions, err error) {
+func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
 	permissions = gdpr.AuctionPermissions{
 		PassGeo: p.passGeo,
 		PassID:  p.passID,
@@ -59,7 +59,7 @@ type fakePermissionsBuilder struct {
 	permissions gdpr.Permissions
 }
 
-func (fpb fakePermissionsBuilder) Builder(gdpr.TCF2ConfigReader) gdpr.Permissions {
+func (fpb fakePermissionsBuilder) Builder(gdpr.TCF2ConfigReader, gdpr.RequestInfo) gdpr.Permissions {
 	return fpb.permissions
 }
 
@@ -599,6 +599,7 @@ func TestCleanOpenRTBRequestsWithFPD(t *testing.T) {
 				assert.Equal(t, fpd[bidderName].Site.Name, bidderRequest.BidRequest.Site.Name, "Incorrect FPD site name")
 				assert.Equal(t, fpd[bidderName].App.Name, bidderRequest.BidRequest.App.Name, "Incorrect FPD app name")
 				assert.Equal(t, fpd[bidderName].User.Keywords, bidderRequest.BidRequest.User.Keywords, "Incorrect FPD user keywords")
+				assert.Equal(t, test.req.BidRequestWrapper.User.BuyerUID, bidderRequest.BidRequest.User.BuyerUID, "Incorrect FPD user buyerUID")
 			} else {
 				assert.Equal(t, "", bidderRequest.BidRequest.Site.Name, "Incorrect FPD site name")
 				assert.Equal(t, "", bidderRequest.BidRequest.User.Keywords, "Incorrect FPD user keywords")
@@ -2956,58 +2957,60 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) {
 }
 
 func TestApplyFPD(t *testing.T) {
-	fpdBidderTest := map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{}
-	bidderTest := openrtb_ext.BidderName("test")
-	fpdBidderTest[bidderTest] = &firstpartydata.ResolvedFirstPartyData{Site: nil, App: nil, User: nil}
-
-	fpdBidderNotNilFPD := map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{}
-	bidderNotNilFPD := openrtb_ext.BidderName("notNilFPD")
-	fpdBidderNotNilFPD[bidderNotNilFPD] = &firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}
-
-	fpdBidderApp := map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{}
-	bidderApp := openrtb_ext.BidderName("AppFPD")
-	fpdBidderApp[bidderApp] = &firstpartydata.ResolvedFirstPartyData{App: &openrtb2.App{ID: "AppId"}}
 
 	testCases := []struct {
 		description     string
-		inputFpd        map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData
-		bidderName      openrtb_ext.BidderName
+		inputFpd        firstpartydata.ResolvedFirstPartyData
 		inputRequest    openrtb2.BidRequest
 		expectedRequest openrtb2.BidRequest
 	}{
 		{
 			description:     "req.Site defined; bidderFPD.Site not defined; expect request.Site remains the same",
-			inputFpd:        fpdBidderTest,
-			bidderName:      bidderTest,
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{Site: nil, App: nil, User: nil},
 			inputRequest:    openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}},
 			expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}},
 		},
 		{
 			description: "req.Site, req.App, req.User are not defined; bidderFPD.App, bidderFPD.Site and bidderFPD.User defined; " +
 				"expect req.Site, req.App, req.User to be overriden by bidderFPD.App, bidderFPD.Site and bidderFPD.User",
-			inputFpd:        fpdBidderNotNilFPD,
-			bidderName:      bidderNotNilFPD,
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}},
 			inputRequest:    openrtb2.BidRequest{},
 			expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}},
 		},
 		{
 			description:     "req.Site, defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App; expect req.Site remains the same",
-			inputFpd:        fpdBidderApp,
-			bidderName:      bidderApp,
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{App: &openrtb2.App{ID: "AppId"}},
 			inputRequest:    openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}},
 			expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}},
 		},
 		{
 			description:     "req.Site, req.App defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App",
-			inputFpd:        fpdBidderApp,
-			bidderName:      bidderApp,
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{App: &openrtb2.App{ID: "AppId"}},
 			inputRequest:    openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "TestAppId"}},
 			expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}},
 		},
+		{
+			description:     "req.User is defined; bidderFPD.User defined; req.User has BuyerUID. Expect to see user.BuyerUID in result request",
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}},
+			inputRequest:    openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: "12345"}},
+			expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId", BuyerUID: "12345"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}},
+		},
+		{
+			description:     "req.User is defined; bidderFPD.User defined; req.User has BuyerUID with zero length. Expect to see empty user.BuyerUID in result request",
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}},
+			inputRequest:    openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: ""}},
+			expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}},
+		},
+		{
+			description:     "req.User is not defined; bidderFPD.User defined and has BuyerUID. Expect to see user.BuyerUID in result request",
+			inputFpd:        firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}},
+			inputRequest:    openrtb2.BidRequest{},
+			expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}},
+		},
 	}
 
 	for _, testCase := range testCases {
-		applyFPD(testCase.inputFpd[testCase.bidderName], &testCase.inputRequest)
+		applyFPD(&testCase.inputFpd, &testCase.inputRequest)
 		assert.Equal(t, testCase.expectedRequest, testCase.inputRequest, fmt.Sprintf("incorrect request after applying fpd, testcase %s", testCase.description))
 	}
 }
diff --git a/gdpr/gdpr_test.go b/gdpr/gdpr_test.go
index 906a27e2..7425cafe 100644
--- a/gdpr/gdpr_test.go
+++ b/gdpr/gdpr_test.go
@@ -45,7 +45,7 @@ func TestNewPermissions(t *testing.T) {
 			return nil, nil
 		}
 
-		perms := NewPermissions(config, &tcf2Config{}, vendorIDs, vendorListFetcher)
+		perms := NewPermissions(config, &tcf2Config{}, vendorIDs, vendorListFetcher, RequestInfo{})
 
 		assert.IsType(t, tt.wantType, perms, tt.description)
 	}
diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go
index b51c376f..8aa0d1ed 100644
--- a/gdpr/impl_test.go
+++ b/gdpr/impl_test.go
@@ -16,31 +16,37 @@ import (
 )
 
 func TestDisallowOnEmptyConsent(t *testing.T) {
+	emptyConsent := ""
 	perms := permissionsImpl{
 		cfg:              &tcf2Config{},
 		fetchVendorList:  failedListFetcher,
 		gdprDefaultValue: "0",
 		hostVendorID:     3,
 		vendorIDs:        nil,
+		gdprSignal:       SignalYes,
+		consent:          emptyConsent,
 	}
 
-	allowSync, err := perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus, SignalYes, "")
+	allowSync, err := perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus)
 	assertBoolsEqual(t, false, allowSync)
 	assertNilErr(t, err)
-	allowSync, err = perms.HostCookiesAllowed(context.Background(), SignalYes, "")
+	allowSync, err = perms.HostCookiesAllowed(context.Background())
 	assertBoolsEqual(t, false, allowSync)
 	assertNilErr(t, err)
 }
 
 func TestAllowOnSignalNo(t *testing.T) {
-	perms := permissionsImpl{}
 	emptyConsent := ""
+	perms := permissionsImpl{
+		gdprSignal: SignalNo,
+		consent:    emptyConsent,
+	}
 
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalNo, emptyConsent)
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assert.Equal(t, true, allowSync)
 	assert.Nil(t, err)
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus, SignalNo, emptyConsent)
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus)
 	assert.Equal(t, true, allowSync)
 	assert.Nil(t, err)
 }
@@ -78,13 +84,15 @@ func TestAllowedSyncs(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			1: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    vendor2AndPurpose1Consent,
 	}
 
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, vendor2AndPurpose1Consent)
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assertNilErr(t, err)
 	assertBoolsEqual(t, true, allowSync)
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus, SignalYes, vendor2AndPurpose1Consent)
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus)
 	assertNilErr(t, err)
 	assertBoolsEqual(t, true, allowSync)
 }
@@ -121,13 +129,15 @@ func TestProhibitedPurposes(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			1: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    vendor2NoPurpose1Consent,
 	}
 
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, vendor2NoPurpose1Consent)
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assertNilErr(t, err)
 	assertBoolsEqual(t, false, allowSync)
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus, SignalYes, vendor2NoPurpose1Consent)
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderAppnexus)
 	assertNilErr(t, err)
 	assertBoolsEqual(t, false, allowSync)
 }
@@ -165,13 +175,15 @@ func TestProhibitedVendors(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			1: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    purpose1NoVendorConsent,
 	}
 
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, purpose1NoVendorConsent)
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assertNilErr(t, err)
 	assertBoolsEqual(t, false, allowSync)
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderPubmatic, SignalYes, purpose1NoVendorConsent)
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderPubmatic)
 	assertNilErr(t, err)
 	assertBoolsEqual(t, false, allowSync)
 }
@@ -180,9 +192,11 @@ func TestMalformedConsent(t *testing.T) {
 	perms := permissionsImpl{
 		hostVendorID:    2,
 		fetchVendorList: listFetcher(nil),
+		gdprSignal:      SignalYes,
+		consent:         "BON",
 	}
 
-	sync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, "BON")
+	sync, err := perms.HostCookiesAllowed(context.Background())
 	assertErr(t, err, true)
 	assertBoolsEqual(t, false, sync)
 }
@@ -198,7 +212,6 @@ func TestAllowActivities(t *testing.T) {
 		bidderName            openrtb_ext.BidderName
 		bidderCoreName        openrtb_ext.BidderName
 		publisherID           string
-		gdprDefaultValue      string
 		gdpr                  Signal
 		consent               string
 		passID                bool
@@ -206,106 +219,79 @@ func TestAllowActivities(t *testing.T) {
 		aliasGVLIDs           map[string]uint16
 	}{
 		{
-			description:      "Allow PI - Non standard publisher",
-			bidderName:       bidderBlockedByConsent,
-			bidderCoreName:   bidderBlockedByConsent,
-			publisherID:      "appNexusAppID",
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
-		},
-		{
-			description:      "Allow PI - known vendor with No GDPR",
-			bidderName:       bidderBlockedByConsent,
-			bidderCoreName:   bidderBlockedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalNo,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
-		},
-		{
-			description:      "Allow PI - known vendor with Yes GDPR",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
+			description:    "Allow PI - Non standard publisher",
+			bidderName:     bidderBlockedByConsent,
+			bidderCoreName: bidderBlockedByConsent,
+			publisherID:    "appNexusAppID",
+			gdpr:           SignalYes,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         true,
 		},
 		{
-			description:      "Allow PI - known Alias vendor GVLID with Yes GDPR",
-			bidderName:       aliasedBidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
-			aliasGVLIDs:      map[string]uint16{"appnexus1": 2},
+			description:    "Allow PI - known vendor with No GDPR",
+			bidderName:     bidderBlockedByConsent,
+			bidderCoreName: bidderBlockedByConsent,
+			gdpr:           SignalNo,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         true,
 		},
 		{
-			description:      "Don't allow PI - known alias vendor with Yes GDPR, alias vendor does not consent to purpose 2",
-			bidderName:       aliasedBidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           false,
-			aliasGVLIDs:      map[string]uint16{"appnexus1": 1},
+			description:    "Allow PI - known vendor with Yes GDPR",
+			bidderName:     bidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalYes,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         true,
 		},
 		{
-			description:      "PI allowed according to host setting gdprDefaultValue 0 - known vendor with ambiguous GDPR and empty consent",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "0",
-			gdpr:             SignalAmbiguous,
-			consent:          "",
-			passID:           true,
+			description:    "Allow PI - known Alias vendor GVLID with Yes GDPR",
+			bidderName:     aliasedBidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalYes,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         true,
+			aliasGVLIDs:    map[string]uint16{"appnexus1": 2},
 		},
 		{
-			description:      "PI allowed according to host setting gdprDefaultValue 0 - known vendor with ambiguous GDPR and non-empty consent",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "0",
-			gdpr:             SignalAmbiguous,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
+			description:    "Don't allow PI - known alias vendor with Yes GDPR, alias vendor does not consent to purpose 2",
+			bidderName:     aliasedBidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalYes,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         false,
+			aliasGVLIDs:    map[string]uint16{"appnexus1": 1},
 		},
 		{
-			description:      "PI allowed according to host setting gdprDefaultValue 1 - known vendor with ambiguous GDPR and empty consent",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalAmbiguous,
-			consent:          "",
-			passID:           false,
+			description:    "Allow PI - known vendor with Ambiguous GDPR and empty consent",
+			bidderName:     bidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalAmbiguous,
+			consent:        "",
+			passID:         true,
 		},
 		{
-			description:      "PI allowed according to host setting gdprDefaultValue 1 - known vendor with ambiguous GDPR and non-empty consent",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalAmbiguous,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           true,
+			description:    "Allow PI - known vendor with Ambiguous GDPR and non-empty consent",
+			bidderName:     bidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalAmbiguous,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         true,
 		},
 		{
-			description:      "Don't allow PI - known vendor with Yes GDPR and empty consent",
-			bidderName:       bidderAllowedByConsent,
-			bidderCoreName:   bidderAllowedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          "",
-			passID:           false,
+			description:    "Don't allow PI - known vendor with Yes GDPR and empty consent",
+			bidderName:     bidderAllowedByConsent,
+			bidderCoreName: bidderAllowedByConsent,
+			gdpr:           SignalYes,
+			consent:        "",
+			passID:         false,
 		},
 		{
-			description:      "Don't allow PI - default vendor with Yes GDPR and non-empty consent",
-			bidderName:       bidderBlockedByConsent,
-			bidderCoreName:   bidderBlockedByConsent,
-			gdprDefaultValue: "1",
-			gdpr:             SignalYes,
-			consent:          vendor2AndPurpose2Consent,
-			passID:           false,
+			description:    "Don't allow PI - default vendor with Yes GDPR and non-empty consent",
+			bidderName:     bidderBlockedByConsent,
+			bidderCoreName: bidderBlockedByConsent,
+			gdpr:           SignalYes,
+			consent:        vendor2AndPurpose2Consent,
+			passID:         false,
 		},
 	}
 	vendorListData := MarshalVendorList(vendorList{
@@ -332,9 +318,12 @@ func TestAllowActivities(t *testing.T) {
 	}
 
 	for _, tt := range tests {
-		perms.gdprDefaultValue = tt.gdprDefaultValue
+		perms.aliasGVLIDs = tt.aliasGVLIDs
+		perms.consent = tt.consent
+		perms.gdprSignal = tt.gdpr
+		perms.publisherID = tt.publisherID
 
-		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName, tt.publisherID, tt.gdpr, tt.consent, tt.aliasGVLIDs)
+		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName)
 
 		assert.Nil(t, err, tt.description)
 		assert.Equal(t, tt.passID, permissions.PassID, tt.description)
@@ -455,6 +444,7 @@ func TestAllowActivitiesGeoAndID(t *testing.T) {
 			34: parseVendorListDataV2(t, vendorListData),
 			74: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
 	}
 
 	// COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA : full consents to purposes and vendors 2, 6, 8 and special feature 1 opt-in
@@ -547,8 +537,10 @@ func TestAllowActivitiesGeoAndID(t *testing.T) {
 			tcf2AggConfig.AccountConfig.BasicEnforcementVendorsMap = map[string]struct{}{string(td.bidder): {}}
 		}
 		perms.cfg = &tcf2AggConfig
+		perms.aliasGVLIDs = td.aliasGVLIDs
+		perms.consent = td.consent
 
-		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder, "", SignalYes, td.consent, td.aliasGVLIDs)
+		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder)
 		assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description)
 		assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description)
 		assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description)
@@ -557,6 +549,9 @@ func TestAllowActivitiesGeoAndID(t *testing.T) {
 }
 
 func TestAllowActivitiesWhitelist(t *testing.T) {
+	// user specifies consent and LI for all purposes, and purpose and LI vendor consent for vendors 2, 6 and 8
+	const fullConsentToPurposesAndVendorsTwoSixEight = "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA"
+
 	vendorListData := MarshalVendorList(buildVendorList34())
 	tcf2AggConfig := allPurposesEnabledTCF2Config()
 
@@ -572,10 +567,14 @@ func TestAllowActivitiesWhitelist(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			34: parseVendorListDataV2(t, vendorListData),
 		}),
+		aliasGVLIDs: map[string]uint16{},
+		consent:     fullConsentToPurposesAndVendorsTwoSixEight,
+		gdprSignal:  SignalYes,
+		publisherID: "appNexusAppID",
 	}
 
 	// Assert that an item that otherwise would not be allowed PI access, gets approved because it is found in the GDPR.NonStandardPublishers array
-	permissions, err := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus, "appNexusAppID", SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA", map[string]uint16{})
+	permissions, err := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus)
 	assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed")
 	assert.EqualValuesf(t, true, permissions.PassGeo, "PassGeo failure")
 	assert.EqualValuesf(t, true, permissions.PassID, "PassID failure")
@@ -596,6 +595,7 @@ func TestAllowActivitiesPubRestrict(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			15: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
 	}
 
 	// COwAdDhOwAdDhN4ABAENAPCgAAQAAv___wAAAFP_AAp_4AI6ACACAA - vendors 1-10 legit interest only,
@@ -640,7 +640,10 @@ func TestAllowActivitiesPubRestrict(t *testing.T) {
 	}
 
 	for _, td := range testDefs {
-		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder, "", SignalYes, td.consent, td.aliasGVLIDs)
+		perms.aliasGVLIDs = td.aliasGVLIDs
+		perms.consent = td.consent
+
+		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder)
 		assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description)
 		assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description)
 		assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description)
@@ -648,6 +651,8 @@ func TestAllowActivitiesPubRestrict(t *testing.T) {
 }
 
 func TestAllowSync(t *testing.T) {
+	const fullConsentToPurposesAndVendorsTwoSixEight = "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA"
+
 	vendorListData := MarshalVendorList(buildVendorList34())
 	tcf2AggConfig := allPurposesEnabledTCF2Config()
 
@@ -662,19 +667,22 @@ func TestAllowSync(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			34: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    fullConsentToPurposesAndVendorsTwoSixEight,
 	}
 
-	// COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA : full consensts to purposes and vendors 2, 6, 8
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assert.NoErrorf(t, err, "Error processing HostCookiesAllowed")
 	assert.EqualValuesf(t, true, allowSync, "HostCookiesAllowed failure")
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderRubicon, SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderRubicon)
 	assert.NoErrorf(t, err, "Error processing BidderSyncAllowed")
 	assert.EqualValuesf(t, true, allowSync, "BidderSyncAllowed failure")
 }
 
 func TestProhibitedPurposeSync(t *testing.T) {
+	const fullConsentToPurposesAndVendorsTwoSixEight = "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA"
+
 	vendorList34 := buildVendorList34()
 	vendorList34.Vendors["8"].Purposes = []int{7}
 	vendorListData := MarshalVendorList(vendorList34)
@@ -692,19 +700,22 @@ func TestProhibitedPurposeSync(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			34: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    fullConsentToPurposesAndVendorsTwoSixEight,
 	}
 
-	// COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA : full consents to purposes for vendors 2, 6, 8
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assert.NoErrorf(t, err, "Error processing HostCookiesAllowed")
 	assert.EqualValuesf(t, false, allowSync, "HostCookiesAllowed failure")
 
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderRubicon, SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderRubicon)
 	assert.NoErrorf(t, err, "Error processing BidderSyncAllowed")
 	assert.EqualValuesf(t, false, allowSync, "BidderSyncAllowed failure")
 }
 
 func TestProhibitedVendorSync(t *testing.T) {
+	const fullConsentToPurposesAndVendorsTwoSixEight = "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA"
+
 	vendorListData := MarshalVendorList(buildVendorList34())
 	tcf2AggConfig := allPurposesEnabledTCF2Config()
 
@@ -720,15 +731,17 @@ func TestProhibitedVendorSync(t *testing.T) {
 		fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 			34: parseVendorListDataV2(t, vendorListData),
 		}),
+		gdprSignal: SignalYes,
+		consent:    fullConsentToPurposesAndVendorsTwoSixEight,
 	}
 
 	// COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA : full consents to purposes for vendors 2, 6, 8
-	allowSync, err := perms.HostCookiesAllowed(context.Background(), SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err := perms.HostCookiesAllowed(context.Background())
 	assert.NoErrorf(t, err, "Error processing HostCookiesAllowed")
 	assert.EqualValuesf(t, false, allowSync, "HostCookiesAllowed failure")
 
 	// Permission disallowed due to consent string not including vendor 10.
-	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderOpenx, SignalYes, "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA")
+	allowSync, err = perms.BidderSyncAllowed(context.Background(), openrtb_ext.BidderOpenx)
 	assert.NoErrorf(t, err, "Error processing BidderSyncAllowed")
 	assert.EqualValuesf(t, false, allowSync, "BidderSyncAllowed failure")
 }
@@ -915,6 +928,9 @@ func TestAllowActivitiesBidRequests(t *testing.T) {
 			fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 				34: parseVendorListDataV2(t, vendorListData),
 			}),
+			aliasGVLIDs: td.aliasGVLIDs,
+			consent:     td.consent,
+			gdprSignal:  SignalYes,
 		}
 
 		tcf2AggConfig := allPurposesEnabledTCF2Config()
@@ -927,7 +943,7 @@ func TestAllowActivitiesBidRequests(t *testing.T) {
 		tcf2AggConfig.HostConfig.PurposeConfigs[consentconstants.Purpose(2)] = &tcf2AggConfig.HostConfig.Purpose2
 		perms.cfg = &tcf2AggConfig
 
-		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder, "", SignalYes, td.consent, td.aliasGVLIDs)
+		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder)
 		assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description)
 		assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description)
 		assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description)
@@ -944,9 +960,12 @@ func TestTCF1Consent(t *testing.T) {
 		vendorIDs: map[openrtb_ext.BidderName]uint16{
 			openrtb_ext.BidderAppnexus: 2,
 		},
+		aliasGVLIDs: map[string]uint16{},
+		consent:     tcf1Consent,
+		gdprSignal:  SignalYes,
 	}
 
-	permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderAllowedByConsent, bidderAllowedByConsent, "", SignalYes, tcf1Consent, map[string]uint16{})
+	permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderAllowedByConsent, bidderAllowedByConsent)
 
 	assert.Nil(t, err, "TCF1 consent - no error returned")
 	assert.Equal(t, false, permissions.AllowBidRequest, "TCF1 consent - bid request not allowed")
@@ -1024,6 +1043,9 @@ func TestAllowActivitiesVendorException(t *testing.T) {
 			fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 				34: parseVendorListDataV2(t, vendorListData),
 			}),
+			aliasGVLIDs: map[string]uint16{},
+			consent:     td.consent,
+			gdprSignal:  SignalYes,
 		}
 
 		tcf2AggConfig := allPurposesEnabledTCF2Config()
@@ -1034,7 +1056,7 @@ func TestAllowActivitiesVendorException(t *testing.T) {
 		tcf2AggConfig.HostConfig.PurposeConfigs[consentconstants.Purpose(3)] = &tcf2AggConfig.HostConfig.Purpose3
 		perms.cfg = &tcf2AggConfig
 
-		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder, "", SignalYes, td.consent, map[string]uint16{})
+		permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder)
 		assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description)
 		assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description)
 		assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description)
@@ -1086,6 +1108,8 @@ func TestBidderSyncAllowedVendorException(t *testing.T) {
 			fetchVendorList: listFetcher(map[uint16]vendorlist.VendorList{
 				34: parseVendorListDataV2(t, vendorListData),
 			}),
+			consent:    td.consent,
+			gdprSignal: SignalYes,
 		}
 
 		tcf2AggConfig := allPurposesEnabledTCF2Config()
@@ -1093,7 +1117,7 @@ func TestBidderSyncAllowedVendorException(t *testing.T) {
 		tcf2AggConfig.HostConfig.PurposeConfigs[consentconstants.Purpose(1)] = &tcf2AggConfig.HostConfig.Purpose1
 		perms.cfg = &tcf2AggConfig
 
-		allowSync, err := perms.BidderSyncAllowed(context.Background(), td.bidder, SignalYes, td.consent)
+		allowSync, err := perms.BidderSyncAllowed(context.Background(), td.bidder)
 		assert.NoErrorf(t, err, "Error processing BidderSyncAllowed for %s", td.description)
 		assert.EqualValuesf(t, td.allowSync, allowSync, "AllowSync failure on %s", td.description)
 	}