These are personal notes on this paper under the lens of FedCM's delegated variation.

The paper starts with a basic introduction of the OIDP protocol:

And then quickly goes on to identify the two privacy problems it intends to address:

  • IDPs learn more than they should
  • RPs can collude and join the user's identities

To solve the first problem (while preventing the replay attack), the proposal starts by introducing a cooperative user agent.

The user agent is responsible for gathering the user's consent, which it can do with the help of metadata (e.g. names, redirect_uris) about the RP that has been signed by the IDP out-of-band in (0).

Post consent, the user agent then (5) creates a version of the RP's client_id by hashing it with a random value u_nonce, to be used as the JWT aud field. Because the hashing isn't invertable, the IDP can't learn what the client_id is.

Because the IDP trusts the user agent, it (7) signs the id_token with the opaque aud.

When the RP gets the id_token, it is also given the u_nonce, which it can then use to re-create the aud and verify that it was addressed correctly.

If everything checks out, the RP uses the sub field as the user's (signed) identifier.

The id_token still contains a global user identifier in the sub field, which leads us to the second problem.

To solve the second problem, the proposal uses a zero knowledge proof.

The user agent constructs the sub identifier in such a way that:

  1. It is guaranteed to be sharded by RP and
  2. The IDP can verify that it is associated with their current logged in user

The first problem is generally simple to solve: hash the user_id with the client_id, to shard the global identifier by RP.

The second problem, however, is harder (as we noted too), and the proposal constructs (a) a sub by hashing the sharded identifier and a second random nonce as well as (b) a zero-knowledge proof that it was constructed that way.

With the ZKP, the IDP can be confident that the sub is appropriately associated with their current logged in user and so (9) it signs an id_token.

The RP is now given (10) the id_token and both random nonces, which it can then use to (11) recompute the values and verify that they were constructed appropriately.

At the end (12) the user is logged in under their sharded identifier.


  1. If the sub is a function of the u_nounce, what happens when the u_nonce isn't available (e.g. you change user agents)?
  2. The proposal suggests the use of ZKBoo for the computation of the ZKP. How well understand that is? How fast is it? Are there reasonable implementations for it?
  3. Why does the user agent need to generate the sub rather than the IDP? Wouldn't H(user_id, masked_aud) suffice, given that the aud isn't invertible by the IDP?
  4. How does this proposal compare to OPRF based proposals?