diff --git a/spec.bs b/spec.bs
index 348af1b1b..c418de323 100644
--- a/spec.bs
+++ b/spec.bs
@@ -1846,6 +1846,7 @@ To generate and score bids given an [=auction config=] |auctionConfig
and a [=real time reporting contributions map=] |realTimeContributionsMap|:
1. [=Assert=] that these steps are running [=in parallel=].
1. Let |settings| be |global|'s [=relevant settings object=].
+1. Let |policyContainer| be |settings|'s [=environment settings object/policy container=].
1. Let |topLevelOrigin| be |settings|'s [=environment/top-level origin=].
1. Let |seller| be |auctionConfig|'s [=auction config/seller=].
1. Let |auctionStartTime| be the [=current coarsened wall time=].
@@ -1887,13 +1888,13 @@ and a [=real time reporting contributions map=] |realTimeContributionsMap|:
[=score and rank a bid=] with |auctionConfig|, |reportingContextMap|[|auctionConfig|],
|compWinnerInfo|'s [=leading bid info/leading bid=], |leadingBidInfo|,
|decisionLogicFetcher|, |trustedScoringSignalsBatcher|, null, "top-level-auction", null,
- and |topLevelOrigin|.
+ |topLevelOrigin|, |realTimeContributionsMap|, and |policyContainer|.
1. If |compWinnerInfo|'s [=leading bid info/leading non-k-anon-enforced bid=]
is not null, then run [=score and rank a bid=] with |auctionConfig|, |reportingContextMap|[
|auctionConfig|], |compWinnerInfo|'s [=leading bid info/leading non-k-anon-enforced bid=],
|leadingBidInfo|, |decisionLogicFetcher|, |trustedScoringSignalsBatcher|,
|topLevelDirectFromSellerSignalsForSeller|, null, "top-level-auction", null, |topLevelOrigin|,
- and |realTimeContributionsMap|.
+ |realTimeContributionsMap|, and |policyContainer|.
1. Decrement |pendingComponentAuctions| by 1.
1. Wait until |pendingComponentAuctions| is 0.
1. If |auctionConfig|'s [=auction config/aborted=] is true, return failure.
@@ -1971,7 +1972,8 @@ and a [=real time reporting contributions map=] |realTimeContributionsMap|:
1. [=Score and rank a bid=] with |auctionConfig|, |reportingContext|
|additionalBid|'s [=decoded additional bid/bid=], |leadingBidInfo|, |decisionLogicFetcher|,
|trustedScoringSignalsBatcher|, |directFromSellerSignalsForSeller|, null, |auctionLevel|,
- |componentAuctionExpectedCurrency|, |topLevelOrigin|, and |realTimeContributionsMap|.
+ |componentAuctionExpectedCurrency|, |topLevelOrigin|, |realTimeContributionsMap|, and
+ |policyContainer|.
1. Decrement |pendingAdditionalBids| by 1.
1. [=map/For each=] |buyer| → |perBuyerGenerator| of |bidGenerators|,
[=parallel queue/enqueue steps|enqueue the following steps=] to |queue|:
@@ -2035,7 +2037,7 @@ and a [=real time reporting contributions map=] |realTimeContributionsMap|:
1. [=list/For each=] |ig| of |groups|:
1. [=Batch or fetch trusted bidding signals=] given |trustedBiddingSignalsBatcher|,
|ig|, |signalsUrl|, |buyerExperimentGroupId|, |topLevelOrigin|, |slotSizeQueryParam|,
- and |settings|'s [=environment settings object/policy container=].
+ and |policyContainer|.
1. [=Fetch the current outstanding trusted signals batch=] given |trustedBiddingSignalsBatcher|,
|signalsUrl|, |buyer|, |buyerExperimentGroupId|, |topLevelOrigin|, and |slotSizeQueryParam|.
1. [=Fetch the trusted key value signals batch=] given |trustedBiddingSignalsBatcher|,
@@ -2150,7 +2152,8 @@ and a [=real time reporting contributions map=] |realTimeContributionsMap|:
1. [=Score and rank a bid=] with |auctionConfig|, |reportingContext|, |bidToScore|,
|leadingBidInfo|, |decisionLogicFetcher|, |trustedScoringSignalsBatcher|,
|directFromSellerSignalsForSeller|, |dataVersion|, |auctionLevel|,
- |componentAuctionExpectedCurrency|, |topLevelOrigin|, and |realTimeContributionsMap|.
+ |componentAuctionExpectedCurrency|, |topLevelOrigin|, |realTimeContributionsMap|,
+ and |policyContainer|.
1. [=Update cumulative buyer time metrics=] given |metrics| and |cumulativeTimeoutTracker|.
1. Decrement |pendingBuyers| by 1.
1. Wait until both |pendingBuyers| and |pendingAdditionalBids| are 0.
@@ -2357,12 +2360,14 @@ a [=trusted scoring signals batcher=] |trustedScoringSignalsBatcher|
a {{DirectFromSellerSignalsForSeller}} |directFromSellerSignalsForSeller|, an {{unsigned long}}-or-null
|biddingDataVersion|, an enum |auctionLevel|, which is "single-level-auction", "top-level-auction",
or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, an [=origin=]
-|topLevelOrigin|, and a [=real time reporting contributions map=] |realTimeContributionsMap|:
+|topLevelOrigin|, a [=real time reporting contributions map=] |realTimeContributionsMap|, and
+a [=policy container=] |policyContainer|:
1. Let «|trustedScoringSignalsAreCrossOrigin|, |sameOriginTrustedScoringSignals|,
|crossOriginTrustedScoringSignals|, |scoringDataVersion|» be the result of [=fetch and
decode trusted scoring signals=] given |trustedScoringSignalsBatcher|, |auctionConfig|,
- |generatedBid|, |decisionLogicFetcher|, |topLevelOrigin|, and |realTimeContributionsMap|.
+ |generatedBid|, |decisionLogicFetcher|, |topLevelOrigin|, |realTimeContributionsMap|,
+ and |policyContainer|.
1. Let |adMetadata| be |generatedBid|'s [=generated bid/ad=].
1. Let |bidValue| be |generatedBid|'s [=generated bid/bid=].
1. If |generatedBid|'s [=generated bid/modified bid=] is not null, then set |bidValue| to
@@ -2663,7 +2668,8 @@ is a [=structured header=] whose value must be an [=structured header/integer=].
To fetch trusted signals given a [=URL=] |url|, an [=origin=] |scriptOrigin|, a
-[=policy container=] |policyContainer|, and a [=boolean=] |isBiddingSignal|:
+[=policy container=] |policyContainer|, and a [=boolean=] |isBiddingSignal|. They return a
+[=tuple=] consisting of ([=ordered map=] or null, [=ordered map=] or null, integer or null):
1. Let |request| be a new [=request=] with the following properties:
: [=request/URL=]
@@ -2709,19 +2715,19 @@ To fetch trusted signals given a [=URL=] |url|, an [=origin=] |script
[:X-fledge-bidding-signals-format-version:] and "`item`" from |headers|.
1. Set |signals| to the result of [=parsing JSON bytes to an Infra value=] |responseBody|.
1. Wait for |signals| to be set.
- 1. If |signals| is a parsing exception, or if |signals| is not an [=ordered map=], return « null,
- null, null ».
+ 1. If |signals| is a parsing exception, or if |signals| is not an [=ordered map=], return a
+ [=tuple=] (null, null, null).
1. If |formatVersion| is 2:
- 1. If |signals|["`keys`"] does not [=map/exist=], return « null, null ».
+ 1. If |signals|["`keys`"] does not [=map/exist=], [=tuple=] (null, null, null ).
1. Set |signals| to |signals|["`keys`"].
- 1. If |signals| is not an [=ordered map=], return « null, null ».
+ 1. If |signals| is not an [=ordered map=], return a [=tuple=] (null, null, null).
1. If |signals|["`perInterestGroupData`"] [=map/exists=] and is an [=ordered map=]:
1. [=Assert=] |isBiddingSignal| is true.
1. Let |perInterestGroupData| be |signals|["`perInterestGroupData`"].
1. [=map/For each=] |key| → |value| of |signals|:
1. [=map/Set=] |signals|[|key|] to the result of [=serializing an Infra value to a JSON string=]
given |value|.
- 1. Return « |signals|, |perInterestGroupData|, |dataVersion| ».
+ 1. Return a [=tuple=] (|signals|, |perInterestGroupData|, |dataVersion|).
@@ -3025,7 +3031,7 @@ and a [=global object=] |global|:
to |winner|'s [=generated bid/selected buyer and seller reporting ID=].
1. If |igAd|'s [=interest group ad/buyer and seller reporting ID=] is not null, [=map/set=]
|browserSignals|["{{ReportingBrowserSignals/buyerAndSellerReportingId}}"] to it.
- 1. Otherwise, if the result of running [=query reporting ID k-anonymity count=] with |winner|'s
+ 1. Otherwise, if the result of running [=query reporting ID k-anonymity count=] with |winner|'s
[=generated bid/interest group=], |igAd|, and null is true:
1. If |igAd|'s [=interest group ad/buyer and seller reporting ID=] is not null, [=map/set=]
|browserSignals|["{{ReportingBrowserSignals/buyerAndSellerReportingId}}"] to it.
@@ -3188,8 +3194,8 @@ a [=list=] of [=interest groups=] |bidIgs|, and a [=reporting context map=]
1. Let |requestId| be the value of |auctionConfig|'s [=auction config/server response id=].
1. Let |requestContexts| be the value of |global|'s [=associated Document's=] [=node navigable's=]
[=traversable navigable's=] [=traversable navigable/saved Bidding and Auction request context=].
-1. If |requestContexts|[|requestId|] does not [=map/exist=], return null.
-1. Let |requestContext| be |requestContexts|[|requestId|].
+1. If |requestContexts|[(|seller|,|requestId|)] does not [=map/exist=], return null.
+1. Let |requestContext| be |requestContexts|[(|seller|,|requestId|)].
1. Let |response| be the [=server auction response=] which is the result of
deserializing |auctionConfig|'s [=auction config/server response=]
with |requestContext| according to [Section 2.3.5 of the Bidding and Auction Services IETF standard](https://privacysandbox.github.io/draft-ietf-bidding-and-auction-services/draft-ietf-bidding-and-auction-services.html#name-parsing-a-response).
@@ -3485,19 +3491,33 @@ The response along with the request ID can be then passed as part of an auction
[SecureContext]
partial interface Navigator {
- Promise getInterestGroupAdAuctionData(AdAuctionDataConfig config);
+ Promise getInterestGroupAdAuctionData(optional AdAuctionDataConfig config = {});
+};
+
+dictionary AdAuctionPerSellerData {
+ required USVString seller;
+ Uint8Array request;
+ DOMString error;
};
dictionary AdAuctionData {
- required Uint8Array request;
required USVString requestId;
+ Uint8Array request;
+ sequence requests;
};
-dictionary AdAuctionDataConfig {
+dictionary AdAuctionOneSeller {
required USVString seller;
- required USVString coordinatorOrigin;
+ USVString coordinatorOrigin;
+};
+
+dictionary AdAuctionDataConfig {
+ USVString seller;
+ USVString coordinatorOrigin;
+ sequence sellers;
+
unsigned long requestSize;
record perBuyerConfig;
};
@@ -3507,10 +3527,23 @@ dictionary AdAuctionDataConfig {
{{AdAuctionDataConfig/seller}}
The seller that will be used as the {{AuctionAdConfig/seller}} in the
following {{AuctionAdConfig}} passed to {{Window/navigator}}.{{Navigator/runAdAuction()}}.
+ Can not be specified with the {{AdAuctionDataConfig/sellers}} field. Exactly
+ one of {{AdAuctionDataConfig/seller}} and {{AdAuctionDataConfig/sellers}}
+ must be specified.
{{AdAuctionDataConfig/coordinatorOrigin}}
The origin of the coordinator hosting public encryption keys for the server
running the ad auction. The [=origin/scheme=] must be "`https`". An implementation
may select which coordinators are acceptable.
+ Can not be specified with the {{AdAuctionDataConfig/sellers}} field.
+ {{AdAuctionDataConfig/sellers}}
+ A list of seller origins and, optionally, their corresponding coordinators.
+ When present, the {{AdAuctionData}} provided when the {{Promise}} returned
+ by {{Navigator/getInterestGroupAdAuctionData}} resolves contains the
+ {{AdAuctionData/requests}} field instead of the {{AdAuctionData/request}} field.
+ Can not be specified with the {{AdAuctionDataConfig/seller}} or
+ {{AdAuctionDataConfig/coordinatorOrigin}} fields. Exactly
+ one of {{AdAuctionDataConfig/seller}} and {{AdAuctionDataConfig/sellers}}
+ must be specified.
{{AdAuctionDataConfig/requestSize}}
The desired size for the returned {{AdAuctionData/request}}. If any buyers are specified in
{{AdAuctionDataConfig/perBuyerConfig}}, this will be the exact size of the returned {{AdAuctionData/request}}.
@@ -3715,26 +3748,11 @@ The getInterestGroupAdAuctionData(|configIDL|) m
1. If |global|'s [=associated Document=] is not [=allowed to use=] the "[=run-ad-auction=]"
[=policy-controlled feature=], then [=exception/throw=] a "{{NotAllowedError}}" {{DOMException}}.
1. Let |settings| be [=this=]'s [=relevant settings object=].
-1. Let |config| be the result of running [=parse and verify ad auction data config=]
+1. Let |configs| be the result of running [=parse and verify ad auction data config=]
on |configIDL| and |settings|'s [=environment/top-level origin=].
1. Let |p| be [=a new promise=].
1. Let |queue| be the result of [=starting a new parallel queue=].
1. [=parallel queue/enqueue steps|Enqueue the following steps=] to |queue|:
- 1. If |config|'s [=auction data config/coordinator=] is not one of the [=implementation-defined=]
- coordinators supported by this [=user agent=]:
- 1. [=Queue a global task=] on the [=DOM manipulation task source=], given |global|, to
- [=reject=] |p| with a {{TypeError}}.
- 1. Abort these steps.
- 1. Let |keyInfo| be the result of [=looking up the server encryption key=]
- with |config|'s [=auction data config/seller=] and |config|'s
- [=auction data config/coordinator=].
- 1. If |keyInfo| is failure:
- 1. [=Queue a global task=] on the [=DOM manipulation task source=], given |global|, to
- [=reject=] |p| with a {{TypeError}}.
- 1. Abort these steps.
- 1. Let (|key|, |keyId|) be |keyInfo|.
- 1. Set |config|'s [=auction data config/encryption key=] to |key|.
- 1. Set |config|'s [=auction data config/encryption key id=] to |keyId|.
1. Let |igMap| be a new [=map=] whose [=map/keys=] are [=origins=] and [=map/values=] are [=lists=].
1. Let |igPAggCoordinatorMap| be a new [=map=] whose [=map/keys=] are tuples of ([=origins=], [=strings=])
and [=map/values=] are [=origins=].
@@ -3743,9 +3761,6 @@ The getInterestGroupAdAuctionData(|configIDL|) m
1. If |ig|'s [=interest group/ads=] is null or [=list/is empty=], [=iteration/continue=].
1. Let |owner| be |ig|'s [=interest group/owner=].
1. Let |name| be |ig|'s [=interest group/name=].
- 1. If |config|'s [=auction data config/per buyer config=] [=map/is not empty=] and
- |config|'s [=auction data config/per buyer config=][|owner|] does not
- [=map/exist=], then [=iteration/continue=].
1. If |igMap|[|owner|] does not [=map/exist=], then [=map/set=] |igMap|[|owner|] to a new [=list=].
1. Let |ads| be a new [=list=].
1. [=list/For each=] |ad| in |ig|'s [=interest group/ads=], [=list/append=] |ad|'s [=interest group ad/ad render ID=] to |ads|.
@@ -3794,20 +3809,67 @@ The getInterestGroupAdAuctionData(|configIDL|) m
1. [=list/Append=] |serverIg| to |igMap|[|owner|].
1. If |ig|'s [=interest group/Private Aggregation coordinator=] is not null, then [=map/set=]
|igPAggCoordinatorMap|[(|owner|, |name|)] to it.
- 1. Let |result| be a new {{AdAuctionData}}.
+ 1. Let |results| be a new [=list=] of [=auction data per seller results=].
1. Let |requestId| be the [=string representation=] of a [=version 4 UUID=].
- 1. [=map/Set=] |result|["{{AdAuctionData/requestId}}"] to |requestId|.
- 1. Let (|requestBlob|, |context|) be the result of serializing |igMap| with |config| and
- |igPAggCoordinatorMap|. The serialization method may follow that described in
- [Section 2.2.4 of Bidding and Auction Services](https://privacysandbox.github.io/draft-ietf-bidding-and-auction-services/draft-ietf-bidding-and-auction-services.html#name-generating-a-request).
- 1. Set |result|["{{AdAuctionData/request}}"] to |requestBlob|.
+ 1. [=list/For each=] |config| of |configs|:
+ 1. Let |seller| be |config|'s [=auction data config/seller=].
+ 1. If |config|'s [=auction data config/coordinator=] is not one of the [=implementation-defined=]
+ Bidding and Auction Services coordinators supported by this [=user agent=]:
+ 1. Let |result| be a new [=auction data per seller result=] with the following [=struct/items=]:
+ : [=auction data per seller result/seller=]
+ :: |seller|
+ : [=auction data per seller result/error=]
+ :: "invalid coordinator"
+ 1. [=list/Append=] |result| to |results|.
+ 1. [=iteration/Continue=].
+ 1. Let |keyInfo| be the result of [=looking up the server encryption key=]
+ with |config|'s [=auction data config/seller=] and |seller|'s [=auction data config/coordinator=].
+ 1. If |keyInfo| is failure:
+ 1. Let |result| be a new [=auction data per seller result=] with the following [=struct/items=]:
+ : [=auction data per seller result/seller=]
+ :: |seller|
+ : [=auction data per seller result/error=]
+ :: "key lookup failed"
+ 1. [=list/Append=] |result| to |results|.
+ 1. [=iteration/Continue=].
+ 1. Let (|key|, |keyId|) be |keyInfo|.
+ 1. Set |config|'s [=auction data config/encryption key=] to |key|.
+ 1. Set |config|'s [=auction data config/encryption key id=] to |keyId|.
+ 1. Let (|requestBlob|, |context|) be the result of serializing |igMap| with |config| and
+ |igPAggCoordinatorMap|. The serialization method may follow that described in
+ [Section 2.2.4 of Bidding and Auction Services](https://privacysandbox.github.io/draft-ietf-bidding-and-auction-services/draft-ietf-bidding-and-auction-services.html#name-generating-a-request).
+ 1. Let |result| be a new [=auction data per seller result=] with the following [=struct/items=]:
+ : [=auction data per seller result/seller=]
+ :: |seller|
+ : [=auction data per seller result/request=]
+ :: |requestBlob|
+ 1. [=list/Append=] |result| to |results|.
+ 1. Let |requestContext| be a new [=server auction request context=].
+ 1. Set |requestContext|'s [=server auction request context/request ID=] field to |requestId|.
+ 1. Set |requestContext|'s [=server auction request context/request context=] field to |context|.
+ 1. [=map/Set=] |global|'s [=associated Document's=] [=node navigable's=]
+ [=traversable navigable's=] [=traversable navigable/saved Bidding and Auction request context=][(|seller|,|requestId|)] to |requestContext|.
+ 1. Let |IDLresults| be a new {{AdAuctionData}}.
+ 1. [=map/Set=] |IDLresults|["{{AdAuctionData/requestId}}"] to |requestId|.
+ 1. If |configIDL|[{{AdAuctionDataConfig/seller}}] [=map/exists=]:
+ 1. Let |sellerResult| be |results|[0].
+ 1. If |sellerResult|'s [=auction data per seller result/error=] is not null:
+ 1. [=Queue a global task=] on the [=DOM manipulation task source=], given |global|, to
+ [=reject=] |p| with a {{TypeError}}.
+ 1. Abort these steps.
+ 1. Set |IDLresults|["{{AdAuctionData/request}}"] to |requestBlob|.
+ 1. Otherwise:
+ 1. [=list/For each=] |sellerResult| in |results|:
+ 1. Let |IDLresult| be a new {{AdAuctionPerSellerData}} whose {{AdAuctionPerSellerData/seller}}
+ is the [=serialization of an origin|serialization=] of |sellerResult|'s [=auction data per seller result/seller=].
+ 1. If |sellerResult|'s [=auction data per seller result/error=] is not null:
+ 1. Set |IDLresult|["{{AdAuctionPerSellerData/error}}"] to |sellerResult|'s [=auction data per seller result/error=].
+ 1. [=list/Append=] |IDLresult| to |IDLresults|["{{AdAuctionData/requests}}"].
+ 1. Otherwise:
+ 1. Set |IDLresult|["{{AdAuctionPerSellerData/request}}"] to |sellerResult|'s [=auction data per seller result/request=].
+ 1. [=list/Append=] |IDLresult| to |IDLresults|["{{AdAuctionData/requests}}"].
1. [=Queue a global task=] on the [=DOM manipulation task source=], given |global|, to
- resolve |p| with |result|.
- 1. Let |requestContext| be a new [=server auction request context=].
- 1. Set |requestContext|'s [=server auction request context/request ID=] field to |result|["{{AdAuctionData/requestId}}"].
- 1. Set |requestContext|'s [=server auction request context/request context=] field to |context|.
- 1. [=map/Set=] |global|'s [=associated Document's=] [=node navigable's=]
- [=traversable navigable's=] [=traversable navigable/saved Bidding and Auction request context=][|requestId|] to |requestContext|.
+ resolve |p| with |IDLresults|.
1. Return p.
@@ -3816,32 +3878,65 @@ The getInterestGroupAdAuctionData(|configIDL|) m
To parse and verify ad auction data config given an
{{AdAuctionDataConfig}} |configIDL| and [=origin=] |top_level_origin|:
- 1. Let |seller| be the result of running [=parse an https origin=] on
- |configIDL|["{{AdAuctionDataConfig/seller}}"].
- 1. Let |coordinator| be the result of running [=parse an https origin=] on
- |configIDL|["{{AdAuctionDataConfig/coordinatorOrigin}}"].
- 1. If |seller| or |coordinator| are failure, then [=exception/throw=] a {{TypeError}}.
- 1. Let |config| be a new [=auction data config=] with the following [=struct/items=]:
- : [=auction data config/publisher=]
- :: |top_level_origin|
- : [=auction data config/seller=]
- :: |seller|
- : [=auction data config/coordinator=]
- :: |coordinator|
- : [=auction data config/request size=]
- :: |configIDL|["{{AdAuctionDataConfig/requestSize}}"] if it [=map/exists=], null otherwise
- : [=auction data config/per buyer config=]
- :: The result of running [=parse per buyer auction data configs=] on
- |configIDL|["{{AdAuctionDataConfig/perBuyerConfig}}"]
- 1. If |config|'s [=auction data config/per buyer config=] [=map/is not empty=]
- and |config|'s [=auction data config/request size=] is null:
- 1. Let |requestSize| be 0.
- 1. [=list/For each=] |buyerConfig| of |config|'s [=auction data config/per buyer config=]'s [=map/values=]:
+ 1. Let |configs| be a new [=list=] of [=auction data configs=].
+ 1. Let |perBuyerConfigs| be the result of running [=parse per buyer auction data configs=] on
+ |configIDL|["{{AdAuctionDataConfig/perBuyerConfig}}"].
+ 1. Let |requestSize| be |configIDL|["{{AdAuctionDataConfig/requestSize}}"] if it [=map/exists=], null otherwise.
+ 1. If |perBuyerConfigs| [=map/is not empty=] and |requestSize| is null:
+ 1. Set |requestSize| to 0.
+ 1. [=list/For each=] |buyerConfig| of |perBuyerConfigs|'s [=map/values=]:
1. If |buyerConfig|'s [=auction data buyer config/size=] is null,
then [=exception/throw=] a {{TypeError}}.
1. Set |requestSize| to |requestSize| + |buyerConfig|'s [=auction data buyer config/size=].
- 1. Set |config|'s [=auction data config/request size=] to |requestSize|.
- 1. Return |config|.
+ 1. If |configIDL|["{{AdAuctionDataConfig/seller}}"] [=map/exists=]:
+ 1. Let |seller| be the result of running [=parse an https origin=] on
+ |configIDL|["{{AdAuctionDataConfig/seller}}"].
+ 1. If |configIDL|["{{AdAuctionDataConfig/coordinatorOrigin}}"] [=map/exists=]:
+ 1. Let |coordinator| be the result of running [=parse an https origin=] on
+ |configIDL|["{{AdAuctionDataConfig/coordinatorOrigin}}"].
+ 1. Otherwise
+ 1. Let |coordinator| be the [=user agent=]'s default Bidding and Auction Services coordinator.
+ 1. If |seller| or |coordinator| are failure, then [=exception/throw=] a {{TypeError}}.
+ 1. Let |config| be a new [=auction data config=] with the following [=struct/items=]:
+ : [=auction data config/publisher=]
+ :: |top_level_origin|
+ : [=auction data config/seller=]
+ :: |seller|
+ : [=auction data config/coordinator=]
+ :: |coordinator|
+ : [=auction data config/request size=]
+ :: |requestSize|
+ : [=auction data config/per buyer config=]
+ :: |perBuyerConfigs|
+ 1. [=list/Append=] |config| to |configs|.
+ 1. Otherwise:
+ 1. If |configIDL|["{{AdAuctionDataConfig/sellers}}"] does not [=map/exist=], then [=exception/throw=] a {{TypeError}}.
+ 1. If |configIDL|["{{AdAuctionDataConfig/coordinatorOrigin}}"] [=map/exists=], then [=exception/throw=] a {{TypeError}}.
+ 1. [=list/For each=] |sellerConfig| in |configIDL|["{{AdAuctionDataConfig/sellers}}"]:
+ 1. Let |seller| be the result of running [=parse an https origin=] on
+ |sellerConfig|["{{AdAuctionOneSeller/seller}}"].
+ 1. If |configs| [=list/contains=] an [=auction data config=] whose
+ [=auction data config/seller=] is equal to |seller|, then
+ [=exception/throw=] a {{TypeError}}.
+ 1. If |sellerConfig|["{{AdAuctionOneSeller/coordinatorOrigin}}"] [=map/exists=]:
+ 1. Let |coordinator| be the result of running [=parse an https origin=] on
+ |sellerConfig|["{{AdAuctionOneSeller/coordinatorOrigin}}"].
+ 1. Otherwise:
+ 1. Let |coordinator| be the [=user agent=]'s default Bidding and Auction Services coordinator.
+ 1. If |seller| or |coordinator| are failure, then [=exception/throw=] a {{TypeError}}.
+ 1. Let |config| be a new [=auction data config=] with the following [=struct/items=]:
+ : [=auction data config/publisher=]
+ :: |top_level_origin|
+ : [=auction data config/seller=]
+ :: |seller|
+ : [=auction data config/coordinator=]
+ :: |coordinator|
+ : [=auction data config/request size=]
+ :: |requestSize|
+ : [=auction data config/per buyer config=]
+ :: |perBuyerConfigs|
+ 1. [=list/Append=] |config| to |configs|.
+ 1. Return |configs|.
@@ -4744,19 +4839,15 @@ an [=auction config=] |auctionConfig| and a [=reporting context=] |reportingCont
|reportType|:
: "`interestGroupCount`"
- :: The number of interest groups in the [=user agent=]'s interest group set whose owner is
- |buyerOrigin|.
+ :: The number of interest groups in the [=user agent=]'s [=interest
+ group set=] whose [=interest group/owner=] is |buyerOrigin|.
: "`bidCount`"
- :: The number of valid bids generated by interest groups whose owner is
- |buyerOrigin|.
+ :: The number of valid bids generated by interest groups whose
+ [=interest group/owner=] is |buyerOrigin|.
: "`totalGenerateBidLatency`"
:: The sum of execution time in milliseconds for all `generateBid()`
- calls in the auction for interest groups whose owner is
- |buyerOrigin|.
+ calls in the auction for interest groups whose
+ [=interest group/owner=] is |buyerOrigin|.
: "`totalSignalsFetchLatency`"
:: The total time spent fetching trusted buyer signals in
milliseconds, or 0 if the interest group didn't fetch any
@@ -4785,9 +4876,8 @@ an [=auction config=] |auctionConfig| and a [=reporting context=] |reportingCont
:: 0
Issue: Consider allowing the filtering ID to be set here.
- 1. [=map/For each=] |ig| of the [=user agent=]'s
- interest group set whose
- owner is |buyerOrigin|:
+ 1. [=map/For each=] |ig| of the [=user agent=]'s [=interest group set=] whose
+ [=interest group/owner=] is |buyerOrigin|:
1. If seller capabilities of |ig| don't allow this reporting, [=iteration/continue=].
Issue: Align behavior with seller capabilities handling once
: "[=signal base value/bid-reject-reason=]
"
:: 1. If the bid did not succeed purely because it didn't meet the required
- k-anonymity threshold, return 8.
+ [=k-anonymity threshold=], return 8.
1. Let |bidRejectReason| be "`not-available`".
1. If the seller provided a reject reason, set |bidRejectReason| to that
value.
@@ -5137,7 +5227,7 @@ dictionary StorageInterestGroup : AuctionAdInterestGroup {
is a one-time canonical [=string=] representation of a [=version 4 UUID=] that is uniquely
associated with a single call to {{Window/navigator}}.{{Navigator/runAdAuction()}}. For multi-seller
auctions, a distinct auction nonce can be uniquely associated with each of the
-{{AuctionAdConfig/componentAuctions}}. The auction nonce(s) will need to be passed back in via a
+{{AuctionAdConfig/componentAuctions}}. The auction nonce(s) will need to be passed back in via a
subsequent call to {{Window/navigator}}.{{Navigator/runAdAuction()}} via the {{AuctionAdConfig}}.
This is currently only needed for [=auctions=] that use [=additional bids=], in which the auction
nonce is combined with a [=signed additional bid with metadata/seller nonce=] to construct a bid
@@ -5617,17 +5707,17 @@ from querying the server during an auction.
1. If [=query k-anonymity cache=] for |adHashCode| returns true:
1. If |igAd|'s [=interest group ad/selectable buyer and seller reporting IDs=] is not null:
1. Let |kAnonRestrictedSelectableReportingIds| be a new empty [=list=] of [=string=]s.
- 1. [=list/For each=] |selectableReportingId| in |igAd|'s
+ 1. [=list/For each=] |selectableReportingId| in |igAd|'s
[=interest group ad/selectable buyer and seller reporting IDs=]:
1. Let |reportingHashCode| be the result of [=query reporting ID k-anonymity count=]
- given |ig|, |igAd|, and |selectableReportingId|.
+ given |ig|, |igAd|, and |selectableReportingId|.
1. If [=query k-anonymity cache=] for |reportingHashCode| returns true, then
[=list/append=] |selectableReportingId| to |kAnonRestrictedSelectableReportingIds|.
1. Set |igAd|'s [=interest group ad/selectable buyer and seller reporting IDs=] to
|kAnonRestrictedSelectableReportingIds|.
1. [=list/Append=] |igAd| to |kAnonRestrictedIG|'s [=interest group/ads=].
1. If |ig|'s [=interest group/ad components=] is not null:
- 1. Set |kAnonRestrictedIG|'s [=interest group/ad components=] to an empty [=list=] of
+ 1. Set |kAnonRestrictedIG|'s [=interest group/ad components=] to an empty [=list=] of
[=interest group ad=].
1. [=list/For each=] |igAdComponent| of |ig|'s [=interest group/ad components=]:
1. Let |adComponentHashCode| be the result of running [=compute the key hash of component ad=] given |ig| and
@@ -5692,11 +5782,11 @@ from querying the server during an auction.
* "SelectedBuyerAndSellerReportId"
* |middle|
* The result of [=compute the key part for one of multiple reporting ids=] given |selectedReportingId|
- * The result of [=compute the key part for one of multiple reporting ids=] given |igAd|'s
+ * The result of [=compute the key part for one of multiple reporting ids=] given |igAd|'s
[=interest group ad/buyer and seller reporting ID=]
* The result of [=compute the key part for one of multiple reporting ids=] given |igAd|'s
[=interest group ad/buyer reporting ID=]
- 1. Otherwise:
+ 1. Otherwise:
1. If |igAd|'s [=interest group ad/buyer and seller reporting ID=] is not null, set |keyString|
to be the [=string/concatenation=] of the following strings separated with U+000A (LF):
* "BuyerAndSellerReportId"
@@ -7514,8 +7604,9 @@ request with the <{iframe/adauctionheaders}> content attribute
set to `true`, as described in the [:Ad-Auction-Additional-Bid:] header description.
Each [=traversable navigable=] has a saved Bidding
-and Auction request context, which is a [=map=] whose [=map/keys=] are
-the [=string representation=] of a [=version 4 UUID=] and whose [=map/values=]
+and Auction request context, which is a [=map=]. The [=map=]'s [=map/keys=] are
+[=tuples=] consisting of the seller ([=origin=]) and the request ID
+([=string representation=] of a [=version 4 UUID=]). The [=map=]'s [=map/values=]
are [=server auction request contexts=].
Each [=traversable navigable=] has a captured ad auction result
@@ -7706,7 +7797,7 @@ The following algorithm will be added to the [[FETCH#fetching]] section:
1. Let |bidWithMetadata|'s [=signed additional bid with metadata/signed additional bid=] be
|parts|[2].
1. [=list/Append=] |bidWithMetadata| to |storedAdditionalBidsHeaders|[|auctionNonce|].
- 1. Otherwise, if |parts|'s [=list/size=] is 2:
+ 1. Otherwise, if |parts|'s [=list/size=] is 2:
1. Let |auctionNonce| be |parts|[0].
1. If |auctionNonce|'s [=string/length=] is not 36, then [=iteration/continue=].
1. Let |bidWithMetadata|'s [=signed additional bid with metadata/signed additional bid=] be
@@ -7884,12 +7975,12 @@ dictionary ReportingBrowserSignals {
and that value was [=query reporting ID k-anonymity count|jointly k-anonymous=] combined with
interest group owner, bidding script URL, [=ad creative=] URL, and null.
* Set if the wining bid had a [=generated bid/selected buyer and seller reporting ID=] and the
- winning ad had a [=interest group ad/buyer and seller reporting ID=] set in its listing in the
+ winning ad had a [=interest group ad/buyer and seller reporting ID=] set in its listing in the
interest group, and that value was [=query reporting ID k-anonymity count|jointly k-anonymous=]
combined with interest group owner, bidding script URL, [=ad creative=] URL, the and winning bid's
[=generated bid/selected buyer and seller reporting ID=].
- {{ReportingBrowserSignals/selectedBuyerAndSellerReportingId}}
-
- A selected reporting id returned by "`generateBid()`".
+
- A selected reporting id returned by "`generateBid()`".
Set if the winning bid had a [=generated bid/selected buyer and seller reporting ID=] set,
and that value was [=query reporting ID k-anonymity count|jointly k-anonymous=] combined with
[=interest group ad/buyer and seller reporting ID=], interest group owner,
@@ -7958,7 +8049,7 @@ enum KAnonStatus { "passedAndEnforced", "passedNotEnforced", "belowThreshold", "
and that value was [=query reporting ID k-anonymity count|jointly k-anonymous=] combined with
interest group owner, bidding script URL, [=ad creative=] URL, and null.
* Set if the wining bid had a [=generated bid/selected buyer and seller reporting ID=] and the
- winning ad had a [=interest group ad/buyer reporting ID=] set in its listing in the
+ winning ad had a [=interest group ad/buyer reporting ID=] set in its listing in the
interest group, and that value was [=query reporting ID k-anonymity count|jointly k-anonymous=]
combined with interest group owner, bidding script URL, [=ad creative=] URL,
[=interest group ad/buyer and seller reporting ID=], and
@@ -8147,9 +8238,9 @@ An interest group ad is a [=struct=] with the following [=struct/item
: buyer and seller reporting ID
:: Null or a [=string=]. Will be passed in place of interest group name or
[=interest group ad/buyer reporting ID=], or alongside the
- [=generated bid/selected buyer and seller reporting ID=], to [=report win=] and
- [=report result=], subject to [=k-anonymity=] checks. Also passed alongside
- [=generated bid/selected buyer and seller reporting ID=] to `scoreAd()` if
+ [=generated bid/selected buyer and seller reporting ID=], to [=report win=] and
+ [=report result=], subject to [=k-anonymity=] checks. Also passed alongside
+ [=generated bid/selected buyer and seller reporting ID=] to `scoreAd()` if
[=generated bid/selected buyer and seller reporting ID=] is present. Only meaningful in
[=interest group/ads=], but ignored in [=interest group/ad components=].
: selectable buyer and seller reporting IDs
@@ -8703,7 +8794,7 @@ together in the signals response. It's a [=struct=] with the following [=struct/
group.
-A
bidding partition is a collection of [=trusted bidding signals batcher/keys=] and
+A
bidding partition is a collection of [=trusted bidding signals batcher/keys=] and
[=trusted bidding signals batcher/ig names=] that can be processed together by the service without
any potential privacy leakage. It's a [=struct=] with the following [=struct/items=]:
@@ -8936,7 +9027,7 @@ an {{unsigned short}}-or-null |experimentGroupId|, an [=origin=] |topLevelOrigin
|coordinator|.
1. If |keyInfo| is failure, then return « null, null, null ».
1. Let (|requestBlob|, |context|) be the result of generating request with |keyInfo|, |metadata| and
- |compressionGroups|. The generation method may follow that described in
+ |compressionGroups|. The generation method may follow that described in
[Section 2.2.4 of the Protected Audience Key Value Services](https://privacysandbox.github.io/draft-ietf-protected-audience-key-value-service/draft-ietf-protected-audience-key-value-services.html#name-generating-a-request).
1. Return « |requestBlob|, |interestGroupIdMap|, |context| ».
@@ -9046,7 +9137,7 @@ together in the signals response. It's a [=struct=] with the following [=struct/
group.
-A
scoring partition is a collection of [=trusted scoring signals request/render URLs=] and
+A
scoring partition is a collection of [=trusted scoring signals request/render URLs=] and
[=trusted scoring signals request/ad component URLs=] that can be processed together by the service
without any potential privacy leakage. It's a [=struct=] with the following [=struct/items=]:
@@ -9055,7 +9146,7 @@ without any potential privacy leakage. It's a [=struct=] with the following [=st
:: An integer indicates the index of this partition.
:
namespace
:: A [=map=], whose [=map/keys=] are [=strings=] and [=map/values=] are [=list=] of
- [=strings=]. A namespace contains all [=trusted scoring signals request/render URLs=] and
+ [=strings=]. A namespace contains all [=trusted scoring signals request/render URLs=] and
[=trusted scoring signals request/ad component URLs=] in the partition.
:
metadata
:: A [=map=], whose [=map/keys=] and [=map/values=] are [=strings=].
@@ -9376,11 +9467,11 @@ result of [=evaluating a bidding script=], or an [=additional bid=] provided by
in the auction. Must be null if the interest group making this bid has a null
[=interest group/ad components=] field.
:
selected buyer and seller reporting ID
- :: Null or [=string=]. The selected reporting id from the
+ :: Null or [=string=]. The selected reporting id from the
[=interest group ad/selectable buyer and seller reporting IDs=] within the
[=generated bid/interest group=]. If present, this will be:
* Passed alongside [=interest group ad/buyer reporting ID=] and
- [=interest group ad/buyer and seller reporting ID=] to [=report win=]
+ [=interest group ad/buyer and seller reporting ID=] to [=report win=]
subject to [=k-anonymity=] checks.
* Passed alongside [=interest group ad/buyer and seller reporting ID=]
to [=report result=] subject to [=k-anonymity=] checks.
@@ -9457,13 +9548,13 @@ To
adjust bid list based on k-anonymity given a [=list=] of [=generat
1. [=Apply any component ads target to a bid=] given |bidCopy|.
1. [=list/Append=] |bidCopy| to |bidsToScore|
1. Let |selectedReportingId| be a [=string=]-or-null that is set to null.
- 1. If |generatedBid|'s [=generated bid/selected buyer and seller reporting ID=] is not null, set
+ 1. If |generatedBid|'s [=generated bid/selected buyer and seller reporting ID=] is not null, set
|selectedReportingId| to it.
1. Let |igAd| be the [=interest group ad=] from |generatedBid|'s [=generated bid/interest group=]'s
[=interest group/ads=] whose [=interest group ad/render url=] is |generatedBid|'s
[=generated bid/ad descriptor=]'s [=ad descriptor/url=].
1. Let |isBidKAnon| be the result of [=query generated bid k-anonymity count=] given |generatedBid|.
- 1. If |isBidKAnon| is true and running [=query reporting ID k-anonymity count=] with |generatedBid|'s
+ 1. If |isBidKAnon| is true and running [=query reporting ID k-anonymity count=] with |generatedBid|'s
[=generated bid/interest group=], |igAd|, |selectedReportingId| is true:
1. [=list/Append=] |generatedBid| to |bidsToScore|.
@@ -9827,10 +9918,10 @@ An
auction data config is a [=struct=] with the following [=struct/it
:: The origin of the coordinator hosting public encryption keys for the server
running the ad auction. The [=origin/scheme=] must be "`https`".
:
encryption key
- :: A [=byte sequence=]. The public [[RFC9180|HPKE]] encryption key to be used
+ :: Null or a [=byte sequence=]. The public [[RFC9180|HPKE]] encryption key to be used
to encrypt the request.
:
encryption key id
- :: A [=byte=] containing the key ID corresponding to the [=auction data config/encryption key=].
+ :: Null or a [=byte=] containing the key ID corresponding to the [=auction data config/encryption key=].
:
request size
:: {{unsigned long}} or null. An optional field, containing the desired size
for the returned encrypted request blob.
@@ -9838,6 +9929,20 @@ An
auction data config is a [=struct=] with the following [=struct/it
:: A [=map=] whose [=map/keys=] are [=origins=] and [=map/values=] are [=auction data buyer config=].
+An
auction data per seller result is a [=struct=] with the following [=struct/items=]:
+
+ : seller
+ :: The [=origin=] of the seller that this result corresponds to. Will match one of the provided
+ [=auction data configs=]'s [=auction data config/seller=].
+ : request
+ :: Null or a [=byte sequence=]. The encrypted request generated for this
+ [=auction data per seller result/seller=]. Null indicates an error occured and
+ the [=auction data per seller result/error=] field will contain additional information.
+ : error
+ :: Null or a [=string=]. Null when the request succeeds. Otherwise contains
+ additional information about the failure.
+
+
An
auction data buyer config is a [=struct=] with the following [=struct/items=]:
: size