Skip to content
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

[Spec] Seller / bid nonce #1313

Merged
merged 12 commits into from
Nov 13, 2024
136 changes: 96 additions & 40 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -4557,14 +4557,17 @@ dictionary StorageInterestGroup : AuctionAdInterestGroup {

*This first introductory paragraph is non-normative.*

{{Window/navigator}}.{{Navigator/createAuctionNonce()}} creates an <dfn>auction nonce</dfn>, a
one-time [=version 4 UUID=] uniquely associated with a single call to
{{Window/navigator}}.{{Navigator/runAdAuction()}}. For multi-seller auctions, this ID is uniquely
associated with all {{AuctionAdConfig/componentAuctions}}. This nonce 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=],
for which the [=auction nonce=] will be included in each [=additional bid=] as a way of ensuring
that those bids are only used in the [=auctions=] for which they were intended.
{{Window/navigator}}.{{Navigator/createAuctionNonce()}} creates an <dfn>auction nonce</dfn>, which
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 (separate) auction nonce can be uniquely associated with each of the
caraitto marked this conversation as resolved.
Show resolved Hide resolved
{{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=], for which the auction
nonce will be included in each [=additional bid=] as a way of ensuring that those bids are only
used in the [=auctions=] for which they were intended. Alternatively, when using a [=signed
caraitto marked this conversation as resolved.
Show resolved Hide resolved
additional bid with metadata/seller nonce=], a bid nonce derrived from the auction nonce and seller
caraitto marked this conversation as resolved.
Show resolved Hide resolved
nonce will be included in each [=additional bid=] instead of the auction nonce.

<xmp class="idl">
[SecureContext]
Expand Down Expand Up @@ -4646,15 +4649,19 @@ a [=reporting context map=] |reportingContextMap|, and a [=global object=] |glob
1. Let |auctionNonce| be the [=string representation=] of |auctionConfig|'s
[=auction config/auction nonce=].
1. Let |capturedAdditionalBidsHeaders| be |global|'s [=associated Document's=]
[=node navigable's=] [=traversable navigable's=] [=captured additional bids headers=].
[=node navigable's=] [=traversable navigable's=] [=traversable navigable/captured ad auction
additional bids headers=].
1. Let |additionalBids| be a new [=list=] of [=decoded additional bids=].
1. [=list/For each=] |encodedSignedAdditionalBid| of |capturedAdditionalBidsHeaders|[|auctionNonce|]:
1. [=list/For each=] |encodedSignedAdditionalBidWithMetadata| of
|capturedAdditionalBidsHeaders|[|auctionNonce|]:
1. Let |signedAdditionalBid| be the result of running [=forgiving-base64 decode=] with
|encodedSignedAdditionalBid|.
|encodedSignedAdditionalBidWithMetadata|'s [=signed additional bid with metadata/signed
additional bid=].
1. If |signedAdditionalBid| is failure, then [=iteration/continue=].
1. Let |additionalBid| be the result of running [=parse a signed additional bid=] given
|signedAdditionalBid|, |reportingContextMap|, |auctionConfig|, |topLevelAuctionConfig|, and
|negativeTargetInfo|.
|signedAdditionalBid|, |reportingContextMap|, |encodedSignedAdditionalBidWithMetadata|'s
[=signed additional bid with metadata/seller nonce=], |auctionConfig|,
|topLevelAuctionConfig|, and |negativeTargetInfo|.
1. If |additionalBid| is not null:
1. [=list/Append=] |additionalBid| to |additionalBids|.
1. Let |bidCopy| be a clone of |additionalBid|.
Expand All @@ -4664,9 +4671,9 @@ a [=reporting context map=] |reportingContextMap|, and a [=global object=] |glob

<div algorithm>
To <dfn>parse a signed additional bid</dfn> given a [=byte sequence=] |signedAdditionalBid|,
a [=reporting context map=] |reportingContextMap|, an [=auction config=] |auctionConfig|,
an [=auction config=]-or-null |topLevelAuctionConfig|, and a [=negative target info=]
|negativeTargetInfo|:
a [=reporting context map=] |reportingContextMap|, a [=string=]-or-null |sellerNonce|, an [=auction
config=] |auctionConfig|, an [=auction config=]-or-null |topLevelAuctionConfig|, and a [=negative
target info=] |negativeTargetInfo|:

1. [=Assert=] that these steps are running [=in parallel=].
1. Let |parsedSignedAdditionalBid| be the result of running [=parse a JSON string to an infra value=]
Expand Down Expand Up @@ -4696,8 +4703,8 @@ an [=auction config=]-or-null |topLevelAuctionConfig|, and a [=negative target i
1. [=list/Append=] |signature| to |signatures|.
1. If |decodeSignatureFailed| is true, then return null.
1. Let |decodedAdditionalBid| be the result of [=decode an additional bid json=] given
|parsedSignedAdditionalBid|["bid"], |reportingContextMap|, |auctionConfig| and
|topLevelAuctionConfig|.
|parsedSignedAdditionalBid|["bid"], |reportingContextMap|, |auctionConfig|,
|topLevelAuctionConfig|, and |sellerNonce|.
1. Return null if any of the following conditions hold:
* |decodedAdditionalBid| is failure;
* The result of [=checking a currency tag=] with |decodedAdditionalBid|'s
Expand All @@ -4717,21 +4724,34 @@ an [=auction config=]-or-null |topLevelAuctionConfig|, and a [=negative target i

<div algorithm>
To <dfn>decode an additional bid json</dfn> given a [=string=] |additionalBidJson|,
a [=reporting context map=] |reportingContextMap|, an [=auction config=] |auctionConfig|, and an
[=auction config=]-or-null |topLevelAuctionConfig|:
a [=reporting context map=] |reportingContextMap|, an [=auction config=] |auctionConfig|, an
[=auction config=]-or-null |topLevelAuctionConfig|, and a [=string=]-or-null |sellerNonce|:

1. [=Assert=] that these steps are running [=in parallel=].
1. Let |parsedAdditionalBid| be the result of [=parse a JSON string to an infra value=] given
|additionalBidJson|.
1. If |parsedAdditionalBid| is not a [=map=], then return failure.
1. Let |result| be a new [=decoded additional bid=].
1. Return failure if any of the following conditions hold:
* |parsedAdditionalBid|["auctionNonce"] does not [=map/exist=];
* |parsedAdditionalBid|["auctionNonce"] is not the [=string representation=] of
|auctionConfig|'s [=auction config/auction nonce=];
* |parsedAdditionalBid|["auctionNonce"] [=map/exists=] and |parsedAdditionalBid|["bidNonce"]
[=map/exists=];
* |parsedAdditionalBid|["auctionNonce"] does not [=map/exist=] and
|parsedAdditionalBid|["bidNonce"] does not [=map/exist=];
* |parsedAdditionalBid|["seller"] does not [=map/exist=];
* The result of running the [=parse an https origin=] with |parsedAdditionalBid|["seller"] is
failure, or not [=same origin=] with |auctionConfig|'s [=auction config/seller=].
1. If |sellerNonce| is not null:
1. Return failure if any of the following conditions hold:
1. |parsedAdditionalBid|["bidNonce"] does not [=map/exist=];
1. |parsedAdditionalBid|["bidNonce"] is not the result of [=calculate expected bid nonce=]
given the [=string representation=] of |auctionConfig|'s [=auction config/auction nonce=]
and |sellerNonce|.
1. Otherwise:
1. Return failure if any of the following conditions hold:
* |parsedAdditionalBid|["auctionNonce"] does not [=map/exist=];
* |parsedAdditionalBid|["auctionNonce"] is not the [=string representation=] of
|auctionConfig|'s [=auction config/auction nonce=];

1. If |topLevelAuctionConfig| is null:
1. If |parsedAdditionalBid|["topLevelSeller"] [=map/exists=], then return failure.
1. Otherwise:
Expand Down Expand Up @@ -4856,6 +4876,15 @@ a [=reporting context map=] |reportingContextMap|, an [=auction config=] |auctio
1. Return |result|.
</div>

<div algorithm>
To <dfn>calculate expected bid nonce</dfn> given a [=string=] |auctionNonce| and a [=string=]
|sellerNonce|:

1. Return the result of [=forgiving-base64 encoding=] the [=SHA-256=] hash of the result of
[=string/concatenating=] «|auctionNonce|, |sellerNonce|».

</div>

A <dfn>signed additional bid signature</dfn> is a [=struct=] with the following [=struct/items=]:
<dl dfn-for="signed additional bid signature">
: <dfn>key</dfn>
Expand All @@ -4875,10 +4904,6 @@ A <dfn>decoded additional bid</dfn> is a [=struct=] with the following [=struct/
[=decoded additional bid/negative target interest group names=].
</dl>

Each [=traversable navigable=] has a <dfn>captured additional bids headers</dfn>, which is a [=map=]
whose [=map/keys=] are [=strings=] for [=auction nonces=], and whose values are [=list=] of
[=strings=] for encoded additional bids.

## Negative Targeting ## {#negative-targeting-section}

*This first introductory paragraph is non-normative.*
Expand All @@ -4892,7 +4917,7 @@ Protected Audience [=auctions=], each [=additional bid=] is allowed to identify
that specifies no [=negative interest groups=] is always accepted into the [=auction=].

<div algorithm>
To <dfn>check whether negative targeted</dfn> given an [=decoded additional bid=] |additionalBid|, a
To <dfn>check whether negative targeted</dfn> given a [=decoded additional bid=] |additionalBid|, a
[=set=] of [=byte sequences=] |verifiedSignatureKeys|, and a [=negative target info=]
|negativeTargetInfo|:

Expand Down Expand Up @@ -6861,7 +6886,7 @@ request with the <{iframe/adauctionheaders}>

Each [=traversable navigable=] has a <dfn for="traversable navigable">captured ad auction additional
bids headers</dfn>, which is a [=map=] whose [=map/keys=] are [=auction nonces=] and whose
[=map/values=] are [=strings=].
[=map/values=] are [=lists=] of [=signed additional bid with metadata=].

NOTE: This is only captured during a [=request=] whose [=request/initiator type=] is `"fetch"`, made
with the {{RequestInit/adAuctionHeaders}} option set to `true`, or during an
Expand All @@ -6873,11 +6898,11 @@ Each [=traversable navigable=] has a <dfn for="traversable navigable">saved Bidd
and Auction request context</dfn>, which is a [=map=] whose [=map/keys=] are
the [=string representation=] of a [=version 4 UUID=] and whose [=map/values=]
are [=server auction request contexts=].
</div>

Each [=traversable navigable=] has a <dfn for="traversable navigable">captured ad auction result
headers</dfn>, which is a [=map=] whose [=map/keys=] are [=origins=] and [=map/values=] are
[=strings=].
</div>

<div algorithm="fetch capture adAuctionHeaders boolean patch">
Modify the definition of a [=request=]:
Expand Down Expand Up @@ -6968,9 +6993,12 @@ component, and top-level auctions may specify which signals to load by the `adSl
HTTP response header.</h3>

The \`<dfn http-header><code>Ad-Auction-Additional-Bid</code></dfn>\` response header provides value
of a string in the format of `<auction nonce>:<base64-encoding of the signed additional bid>`, which
corresponds to a single [=additional bid=]. The response may include more than one [=additional bid=]
by specifying multiple instances of the [:Ad-Auction-Additional-Bid:] response header.
of a string in the format of `<auction nonce>:<seller nonce>:<base64-encoding of the signed
caraitto marked this conversation as resolved.
Show resolved Hide resolved
additional bid>`, or the legacy format of `<auction nonce>:<base64-encoding of the signed additional
bid>`, either of which corresponds to a single [=additional bid=]. In the format that provides a
seller nonce, the seller nonce must be as described in [=signed additional bid with metadata/seller
nonce=]. The response may include more than one [=additional bid=] by specifying multiple instances
of the [:Ad-Auction-Additional-Bid:] response header.
</div>

<h3 id=ad-auction-result-header>The \`<a http-header><code>Ad-Auction-Result</code></a>\`
Expand Down Expand Up @@ -7047,11 +7075,24 @@ The following algorithm will be added to the [[FETCH#fetching]] section:
that is, scripts making the {{WindowOrWorkerGlobalScope/fetch()}} request aren't able to load
the header value.
1. [=list/For each=] |bid| of |additionalBids|:
1. Let |nonceAndAdditionalBid| be the result of [=strictly splitting=] |bid| on U+003A (:).
1. If |nonceAndAdditionalBid|'s [=list/size=] is not 2, then [=iteration/continue=].
1. Let |nonce| be |nonceAndAdditionalBid|[0].
1. If |nonce|'s [=string/length=] is not 36, then [=iteration/continue=].
1. Set |storedAdditionalBidsHeaders|[|nonce|] to |nonceAndAdditionalBid|[1].
1. Let |parts| be the result of [=strictly splitting=] |bid| on U+003A (:).
1. Let |bidWithMetadata| be a new [=signed additional bid with metadata=].
1. If |parts|'s [=list/size=] is 3:
1. Let |auctionNonce| be |parts|[0].
1. If |auctionNonce|'s [=string/length=] is not 36, then [=iteration/continue=].
1. Let |sellerNonce| be |parts|[1].
1. If |sellerNonce|'s [=string/length=] is not 36, then [=iteration/continue=].
1. Let |bidWithMetadata|'s [=signed additional bid with metadata/seller nonce=] be
|sellerNonce|.
1. Let |bidWithMetadata|'s [=signed additional bid with metadata/signed additional bid=] be
|parts|[2].
1. Set |storedAdditionalBidsHeaders|[|auctionNonce|] to |bidWithMetadata|.
caraitto marked this conversation as resolved.
Show resolved Hide resolved
1. Otherwise, if |parts|'s [=list/size=] is 2:
1. Let |auctionNonce| be |parts|[0].
caraitto marked this conversation as resolved.
Show resolved Hide resolved
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
|parts|[1].
1. Set |storedAdditionalBidsHeaders|[|auctionNonce|] to |bidWithMetadata|.
caraitto marked this conversation as resolved.
Show resolved Hide resolved

1. Let |adAuctionResults| be the result of [=header list/getting, decoding, and splitting=]
[:Ad-Auction-Result:] from |responseHeaders|.
Expand Down Expand Up @@ -7728,8 +7769,9 @@ An <dfn export>auction config</dfn> is a [=struct=] with the following [=struct/
uniquely associated with all {{AuctionAdConfig/componentAuctions}}.
This must come from a prior call to {{Window/navigator}}.{{Navigator/createAuctionNonce()}}.
This is only required for auctions that provide [=additional bids=], and each of those
[=additional bids=] must use the same auction nonce to ensure that each of them was intended for
this and only this auction.
[=additional bids=] must use the same auction nonce (or the bid nonce derived from that auction
caraitto marked this conversation as resolved.
Show resolved Hide resolved
nonce as computed by [=calculate expected bid nonce=]) to ensure that each of them was intended
for this and only this auction.
: <dfn>expects additional bids</dfn>
:: A [=boolean=] or failure, initially false.
Specifies whether some bids will be provided as signed exchanges. Sets to failure if the
Expand Down Expand Up @@ -8637,6 +8679,20 @@ A <dfn>direct from seller signals</dfn> is a [=struct=] with the following [=str
JSON data passed to corresponding buyer's [=script runner=].
</dl>

<h3 id=additional-bids-structs-section>Additional bids</h3>

A <dfn>signed additional bid with metadata</dfn> is a [=struct=] with the following
[=struct/items=]:

<dl dfn-for="signed additional bid with metadata">
: <dfn>signed additional bid</dfn>
:: A [=string=] for an encoded additional bid.
: <dfn>seller nonce</dfn>
:: Null or a [=string=]. If present, represents the randomly-generated seller nonce returned in
the [:Ad-Auction-Additional-Bid:] response header. This must be 36 characters, and should be the
caraitto marked this conversation as resolved.
Show resolved Hide resolved
canonoical [=string=] representation of a [=version 4 UUID=].
</dl>

<h3 id=score-ad-output-header>Score ad output</h3>

The output of running a Protected Audience `scoreAd()` script, is represented using the following type:
Expand Down
Loading