Skip to content

Some followup changes regarding epochs #126

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

Merged
merged 10 commits into from
May 19, 2025
109 changes: 75 additions & 34 deletions api.bs
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ for=PrivateAttribution>measureConversion()</a> method to find matching

<p class=note>
Though this API enables the storage of data by sites,
this does not use a [=storage key=].
the [=impression store=] does not use a [=storage key=].


### Contents ### {#impression-store-contents}
Expand Down Expand Up @@ -920,8 +920,8 @@ The <dfn>privacy budget store</dfn> is a [=map=] whose keys are
A <dfn>privacy budget key</dfn> is a [=tuple=] consisting of the following items:

<dl dfn-for="privacy budget key">
: <dfn ignore>epoch</dfn>
:: A [=privacy budget epoch=]
: <dfn ignore>epoch index</dfn>
:: An [=epoch index=]
: <dfn ignore>site</dfn>
:: A [=site=]

Expand Down Expand Up @@ -960,21 +960,63 @@ The <dfn>epoch start store</dfn> is a [=map=] keyed by [=site=]
with values that are [=moments=]
from the [=wall clock=].

A <dfn local-lt=epoch>privacy budget epoch</dfn> (or [=epoch=])
identifies a period of time.
The length of an [=epoch=] is fixed at one week or 7 [=days=],
where a <dfn>day</dfn> is defined as 86400 seconds.

The exact time span for an [=epoch=] is different
for each combination of [=user agent=] and [=site=].
The start time for a given pair of [=user agent=] and [=site=]
is chosen randomly by the [=user agent=] when an epoch is first needed--
as a side effect of invoking the [=get the current epoch=] algorithm.
The [=epochs=] for a given [=site=] will change
if the [=user agent=] clears browsing history;
see [[#clear-browsing-history]].

An <dfn local-lt="epoch indices">epoch index</dfn> is an integer
that refers to a given [=epoch=].
An [=epoch index=] is used to access
the [=impression store|impression=]
and [=epoch start store|epoch start=] stores.

<div class=note>
In the same way that a [=moment=] is an abstract concept
that can only be expressed as a [=duration=]
relative to another [=moment=],
[=epochs=] are abstract.

[=Epoch indices=] are stored as integers
relative to a set reference point.
The [=epoch indices=] in this specification
use the values from the [=epoch start store=]
as a reference point.
A [=user agent=] could choose to use a different [=moment=]
to indicate a "zero" or reference [=epoch=].
</div>

The algorithms in this specification all use concrete [=epoch indices=],
rather than the more abstract [=epoch=].
[=moment|Points in time=] are translalated to an [=epoch index=]
for the corresponding [=epoch=]
using the [=get the current epoch=] algoritm.

To <dfn>get the current epoch</dfn>
given a [=site=] |site|,
and [=moment=] |now|:
and [=moment=] |t|,
returning an [=epoch index=]:

1. Let |period| be the [=duration=] of one [=epoch=].

1. If the [=epoch start store=] does not [=map/contain=] |site|, [=map/set=]
its value to |now|, minus a [=duration=]
its value to |t|, minus a [=duration=]
that is randomly selected
from between 0 (inclusive) and |period| (exclusive).

1. Let |start| be the result of [=map/get|getting the value=] of |site|
from the [=epoch start store=].

1. Let |elapsed| be (|now| - |start|) / |period|.
1. Let |elapsed| be (|t| - |start|) / |period|.

1. Return |elapsed| as an integer, rounded towards negative Infinity.

Expand All @@ -990,24 +1032,9 @@ when any [=site=]-level state is cleared
at the request of a [=user=].
The value is initially unset.

<div class=note>
A [=user agent=] that offers selective deletion of history,
such as the removal of state for a single site,
could partition this value so that other sites remain unaffected.
However, any choice to partition leaks some information
that might reveal that a specific site had been visited
to any entity that can access stored data.
Strictly limiting the number of partitions
might make this information less useful
in terms of revealing that a particular site was visited.

This specification describes algorithms that do not including partition.
This guarantees that stored data does not reveal anything
about browsing history.
</div>

As an optional optimization,
updating the [=last browsing history clear=] can be skipped if:
updating the [=last browsing history clear=] can be skipped if
all of the following are true:

* All interactions that are cleared are with [=sites=]
that have other uncleared interactions.
Expand All @@ -1020,7 +1047,8 @@ the [=last browsing history clear=] does not need to be updated.
Instead, the [=privacy budget store=] must be updated
by [=map/set|setting=] a value of 0
for all [=privacy budget key=] combinations that can be formed
from every affected [=site=] and [=epoch=].
from every affected [=site=] and [=epoch=]
(using the [=get the current epoch|corresponding=] [=epoch index=]).

<p class=note>
This optimization relies on the [=user agent=]
Expand All @@ -1029,14 +1057,23 @@ about interactions with affected [=sites=]
in the affected [=epochs=].
This only works because any of the retained interactions
could have resulted in exhausting the budget.
Resetting the budget is necessary to ensure
that no information about the gap in browsing history
is exposed.

To <dfn>get the starting epoch for attribution</dfn>
given [=site=] site:
given [=site=] site,
returning an [=epoch index=]:

1. Let |startEpoch| be a [=user agent=]-defined value
for the earliest [=epoch=]
for the earliest [=epoch index=]
that is supported for attribution.

<p class=note>
This value is not a constant [=epoch index=].
A value is chosen for each site
based on [=user agent=] preferences or configuration.

1. If the [=last browsing history clear=] is set,
perform the following steps:

Expand Down Expand Up @@ -1197,8 +1234,8 @@ To <dfn>create an all-zero histogram</dfn>, given an integer |size|:
### Common Impression Matching Logic ### {#logic-matching}

To perform <dfn>common matching logic</dfn>, given
<a dictionary lt=PrivateAttributionConversionOptions>|options|</a>,
[=site=] |topLevelSite|, [=epoch=] |epoch|, and [=moment=] |now|:
<a dictionary lt=PrivateAttributionConversionOptions>|options|</a>,
[=site=] |topLevelSite|, [=epoch index=] |epoch|, and [=moment=] |now|:

1. Let |matching| be an [=set/is empty|empty=] [=set=].

Expand Down Expand Up @@ -1545,10 +1582,8 @@ to protect against those attacks.

Sites receive a separate differential privacy budget
that is used to query [=impressions=] recorded
in each time interval.
This period is called a <dfn local-lt=epoch>privacy budget epoch</dfn>
(or simply [=epoch=])
and its duration is one week (7 days), where a <dfn>day</dfn> is 86400 seconds.
in each [=privacy budget epoch=]
(or [=epoch=]).

This budget applies to the [=impressions=]
that are registered with the [=user agent=]
Expand Down Expand Up @@ -1976,12 +2011,18 @@ to ensure that [=privacy budgets=] are not inadvertently exceeded.

### Clearing Site Data ### {#clear-site-data}

When clearing site data,
When clearing site data at the request of a [=user=],
but retaining browsing history,
a [=user agent=] can [=map/set=] the value
in the [=privacy budget store=] to 0 for all [=epochs=]
for all affected [=sites=].

When clearing site data at the request of a [=site=],
through the use of the [:Clear-Site-Data:] header,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to address the points from #125 (comment)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the discussion there suggests - to me at least - that we need to keep that issue open and do a little more work. This is probably enough for now, given that.

A [=user agent=] only [[#removing-impressions|removes impressions]],
without altering either the [=privacy budget store=]
or the [=epoch start store=] for affected [=sites=].


### Clearing Browsing History ### {#clear-browsing-history}

Expand Down Expand Up @@ -2058,7 +2099,7 @@ A [=conversion site=] that has had state cleared
will not be able to use these [=impressions=].

[=Impressions=] that have a [=same site|matching=] [=impression/intermediary site=]
may be cleared.
may be retained.


## Choice of Clock ## {#why-wall-clock}
Expand Down
Loading