Open martinthomson opened 1 year ago
I'm seeing some parallels here with the PendingBeacon proposal, which based on feedback, is now moving in the opposite direction: from a dedicated API to a fetch()
based one.
It'd be good to decide on an underlying design principle: when should new APIs extend fetch()
and when should they create a dedicated surface?
Beacons are necessarily tied to fetch, because that is what they do. That is not true here because, at its core, this is an API for accessing browser storage.
The only reason I can think of that might want explicit fetch decoration is if you wanted some sort of declarative API that you could use for frames or images so that the appropriate headers can be added in cases where you don't have access to script or access to script is unwieldy. That's a real possibility here, as this API is used for serving ads and ad serving is monstrously complex with tons of constraints on operation. But I want to say that fetch integration needs to be an option of last resort that is only used when a strong case is made for it. And only used for those places where it is necessary (as it might be for redemption). Even then, that integration should be build on top of platform primitives that can be expressed in terms of an API.
That is not true here because, at its core, this is an API for accessing browser storage.
Can you elaborate on that? The PrivacyPass protocol is by its nature a network protocol, isn't it?
A Privacy Pass Client does need to talk to Attesters, Issuers, and Origins, definitely. So yes, there is networking involved, because those roles can't be played by a single entity, by design.
But my central point is that this is not inherently bound to fetch. The protocol operates at a higher layer and could equally use WebTransport, forms, or any of the other mechanisms we use for that part.
The key part of this proposal is how it allows one site to create in-browser state that can be queried by other sites in a very limited fashion. An Origin site[^1] can request a token that has been deposited by an Issuer/Attester site. In that way, the key component of the feature is how the two sites interact with this new form of storage that the browser provides to sites. It is not about the details of how each site accesses resources or obtains the information that is being stored.
[^1]: Yes this is an odd use of terminology. When using Privacy Pass nomenclature, I use Origin in title case to refer to the Privacy Pass role, not a general Web origin.
The fetch integration in the specification is very complicated. It also appears to be unnecessary.
Imagine an API like this:
I've omitted the definition of options and some additional fields, which might include issuance protocol choice, expiration times, and other less significant details.
A site could then call
PrivateStateToken.challenge()
to request that the browser generate a challenge, which is a set of blinded nonces in some of the instantiations of the protocol. It would then receive a challenge in response. This could contain multiple challenges (blinded nonces) to allow for batching. The site then does whatever it needs to do to fulfill those challenges. This would normally involve contacting a server, but the details do not matter much here. CallingPstChallenge.fulfill()
would have the browser validate and store the tokens that are provided.Redemption involves asking for a token, identifying the issuer by its origin. This can reject if there are too many issuers, if there are insufficient tokens, or whatever.
Obviously, the current design is more fully featured (or, to be fair, it contains more of what is needed to be a viable design). Including attributes for signaling the type of token, expiration times, and other important characteristics is trivial and so I've omitted those.