-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional permissioning of id's & data #6240
Comments
@patmmccann - would like to flesh out the requirements a little more. Want to be clear about the scope and what you mention as "priority". The example you provide implies that eids are always secondary - they never show up if FPD is present. Prebid.js and Prebid Server, both of which control the data sent to bid adapters, may have data that is sensitive to publishers and their users. This data includes: User IDs, First Party Data, and specifically user segments and contextual segments within First Party Data.
Questions:
|
Re: Would some IDs be allowed to go to all bidders? Would the existence of those "open" IDs affect FPD? The example above imagines suppressIdWithData being an id specific setting, but not differing per bidder, either it is completely suppressed or available. I agree the idea of suppressDataWithId needs hashing out to which data and suppressIdWithData may need a concept of qualifying data. I was imagining any data in the user segment field, but I agree some further config may be needed to qualify it. |
One could imagine that the requirements here could be complicated like "if specific FPD attributes X,Y, or Z are present, then skip ID A". My sense is that we need to keep the Prebid feature simple or it should be implemented as publisher-specific logic in a BID_REQUEST event callback. Bid adapter modules obtain FPD and EIDs separately. EIDs is controlled per-bidder by default because they obtain it through the bidrequest:
FPD can be controlled per-bidder through the
and PBJS core will give them either the global or the bidder-specific config as appropriate. So here's a proposal that would allow two relatively simple requirements:
Proposed DetailsIn this approach, a publisher should avoid two-way permissions for the same bidder because it's confusing to specify both. The implication of the proposal is that FPD takes priority over EIDs if both "skip" instructions are specified. Anything more complicated than what's provided here can be implemented by the publisher as a BID_REQUEST event callback. Limiting FPD given EIDsUpdate PBS-core to support an optional 'skipIfEid' field on setBidderConfig:
When getConfig() is called from an adapter, it loops through the bidderConfig entries:
Limiting IDs given FPDUpdate the user ID core module to support a new skipIfOrtb2 field:
Before writing to bids.0.userIdAsEids or other output, the module should:
|
We should explain how buyers can calculate value if there is no ID present. For example, prior frequency of 2 is worth x, while prior frequency is worth y. Currently the machine learning algos calculate combinations of exposure information (context, geo, time, frequency, etc.) with marketer goals to back out the value associated with an impression and inform future bidding/direct buying. Thus, enabling engagement and suppression (like frequency capping) is important, but any impairment in buyers' value calculation will have a corresponding negative impact on publisher revenues. |
To ensure that this control has teeth, I suggest we also consider auditing ID systems and bidders before they can quality as compatible or 'honoring' this proposal. The risks I see are:
The use of passively-collected data elements (HTTP headers like IP address and referrer URL) should be documented by bidders and userIds. If publishers wish to technically enforce availability of these elements, we could explore use of Prebid server as a proxy that could truncate/aggregate/obfuscate/remove these elements. |
@joshuakoran as I spoke about in the meeting today, we’ll be addressing frequency capping and measurement through first party data signals in other issues. In fact, if you’d like to help build them out those or give feedback on proposals (like the Permutive fcapping proposal I’ve been looking for feedback for months on), I’m more than happy to put you in the right direction. But for now we’ll need this paired with other proposals to insure no publisher data leakage occurs to buyers. |
@slayser8 Yes please! Happy to help work with whichever teams are focused on completing the virtuous circle of engagement, measurement, optimization (to reallocate budgets or adjust bid prices to higher value placements). |
I would like to add functionality here that would allow for an RTD provider to become a permissioned, trusted third party. This approach would allow for a trusted module to handle first party data on behalf of the publisher and process it before it is handed upstream to the bid adapters. |
@anthonylauzon what is an example of such data and such processing? |
For instance, we would like to be able to allow for a universal bid adapter fpd access exclusion that would still allow for the fpd object to be read by an real-time data adapter. |
I would like to suggest that we use a storageManager like object for FPD. This would allow us to standardize on an interface that we can use to both query and set the data in FPD, as well as potentially allowing for some form of object-level permissioning. |
While this is a pretty good idea @anthonylauzon - we just did a dramatic change of the interface used by publishers, I'd like to avoid another such change. How about instead we develop a "mergeConfig()" convenience function that makes it easier for RTD modules to inject FPD and segments? |
What we are trying to push for if this proposal gets developed is module-level permissions, not just bid adapter level permissioning. My personal view is that code-level fpd permissions in the JavaScript could be messy and ineffective, but I just want to make sure that RTD modules are able to access permissioned FPD. |
Fair enough. GDPR set the precedence for "modulecode" as being broader than bid adapters -- includes modules of all types. |
@gmcgrath11 is this still a priority? |
@patmmccann we should prioritize this in the scope of the rest of the roadmap |
This topic came up in the Identity PMC today, and we are very much in favor of adding this functionality. |
I see this as priority based rule problem. Here is a proposed rule format which I feel can address most of the cases. Input Sample Data
Simple Priority Rule (Pass All segments and do not pass any user Ids & eids)
Filtered data after rule id = 1
Complex / Granular Priority Rule
Rules are executed in ascending order of Filtered data after execution of rule id 1
Filtered data after execution of rule id 2
Filtered data after execution of rule id 3
Rule Execution Details:
|
Hi @abhinavsinha001 does a none wildcard value in the |
Wildcard in values is used for matching criteria - keeping / removing logic works based on priority- whichever matching values have high priority will be kept, Lower priority will be discarded. If priority is the same both will be kept. |
Sorry @abhinavsinha001 , but I don't follow several aspects of the syntax you propose above.
|
|
Making more sense now with the text. Thanks @abhinavsinha001. But still questions:
Why is c.com missing from the example output when it says "publisher is ok with sending segments from dp2.com/segtax=1 along with source c.com in eids"? And then c.com re-appears in the example output of Rule 3. (?)
So this id and buyeruid are always removed, or only if there's any data in ortb2.user.eids or ortb2.user.data.segments? So here's how I'm gathering the algorithm:
close? |
|
Thanks for the clarifications Abhinav. Frankly I think this syntax is going to be hard to learn, write, and debug, but it's up to the the identity committee who will be documenting and supporting it. |
@abhinavsinha001 what is the effect of rule 2 in your example? if I try to run the pseudocode in my head, it has no effect? |
@dgirardi Yes correct it doesn't do anything - just wanted to showcase the behaviour where if object rules are at the same priority all the objects are retained / compatible and doesn't have any effect unless there is a lower priority object rule. The actual filtering is showcased in rule #3. |
I'm going to float an alternate proposal to see how it lands: if we define a way to encode simple predicates in JSON, we could offer it as a control over each item in function filter(ortb2, path, predicate) {
Object.entries(ortb2).forEach(([key, value]) => {
if (predicate({ortb2, path, key, value})) {
delete ortb2[key];
} else {
if (isObject(value)) {
filter(value, [...path, key], predicate);
}
}
})
} I was hoping to find a lightweight, JSON-friendly expression language ready to use for the predicate, but I had no luck. I came up with (inspired by cloudformation condition expressions): {
"bidders": ["bidderA", "bidderB"],
"filter": {
"OR": [
{
"AND": [
{
"EQ": [
{"REF": "path"},
["ortb2", "user", "data", "segments"]
]
},
{
"EQ": [
{"REF": "key"},
"dp1.com/segtax=1"
]
},
{
"EXISTS": {
"REF": ["ortb2", "user", "eids", "a.com"]
}
}
]
},
{
"AND": [
{
"EQ": [
{"REF": "path"},
["ortb2", "user"]
]
},
{
"IN": [
{"REF": "key"},
[
"id",
"buyeruid"
]
]
},
{
"OR": [
{
"!EMPTY": {
"REF": ["ortb2", "user", "eids"]
}
},
{
"!EMPTY": {
"REF": ["ortb2", "user", "data", "segments"]
}
}
]
}
]
}
]
}
} This is meant as an example recreating the same rule as in @abhinavsinha001's example above; the idea is to have something that can easily be "compiled" to a single predicate, in this case the equivalent of: function predicate({ortb2, path, key, value}) {
return (
deepEquals(path, ["ortb2", "user", "data", "segments"]) &&
deepEquals(key, "dp1.com/segtax=1") &&
ortb2["user"]["eids"]["a.com"] != null
) || (
deepEquals(path, ["ortb2", "user"]) &&
["id", "buyeruid"].includes(key) &&
(Object.keys(ortb2["user"]["eids"]).length !== 0 || Object.keys(ortb2["user"]["data"]["segments"]).length !== 0)
)
} The advantage would be that predicates are a more general concept and more likely to be applicable elsewhere; they are also (I believe) more intuitive for people with some technical background. The disadvantage is that to keep the "compilation" lightweight, the expression language might be too unwieldy. I'm sure that smarter people have come up with solutions prettier than mine - if you know of any bring them up! |
@dgirardi Thanks for proposing this generic rule template.
|
@abhinavsinha001 There's a tradeoff between language pleasantness and "compilation" complexity / overhead. The example I gave above would be all the way on the "ugly but fast" end of it, I don't think it'd be significantly heavier than the more ad-hoc system you proposed. But it's definitely more time consuming to read and write for the publisher - if you ignore the learning curve, which is what I am not sure about. My sense is that if you have any technical training at all, you can start writing predicate expressions very quickly - you don't need to learn about domain specific priority groups. But I don't know how technical of an audience this is likely to find. |
This is the proposal that has come out of the Privacy and Identity PMC, posting here for for comments. |
DataController feedback from the Taxonomy PMC and Identity PMC has been merged. Please add additional comments to the doc. |
Type of issue
Feature Request
In the publisher committee, it was expressed that several publishers may want to offer conditional permissioning, in which user segment and contextual segment data may be transmitted when id's are not available and vice versa, but not both together. These publishers would also prefer to specify a priority.
Closely related to #5814 and #3687 and #4472 and the concept of allowedBidders eg at
Prebid.js/test/spec/modules/prebidServerBidAdapter_spec.js
Line 1518 in f613117
One possible scheme, extending from #5814
ext: { prebid: { data: { eidpermissions: [ // prebid server will use this to filter user.ext.eids {"source": "sharedid.org", "bidders": ["*"], "suppressIdWithData" : true}, {"source": "neustar.biz", "bidders": ["bidderB"], "suppressDataWithId" : true}, {"source": "id5-sync.com", "bidders": ["bidderA","bidderC"]} ] } } } }
The text was updated successfully, but these errors were encountered: