3.  Issuers MUST provide two parameters for configuration: Issuer Request URI: A token request URL for generating access known/token-issuer-directory; see wkuri-reg for the registration information for this well-known URI. <del> 4. Clients receive challenges for tokens, as described in AUTHSCHEME. The basic token issuance protocols described in this document can be interactive or non-interactive, and per-origin or cross-origin. </del> 5. <del> The Privacy Pass issuance protocol is a two-message protocol that takes as input a TokenChallenge from the redemption protocol (AUTHSCHEME, Section 2.1) and produces a Token (AUTHSCHEME, Section 2.2), as shown in the figure below. This section describes a variant of this issuance protocol for producing privately verifiable tokens using the protocol in OPRF.  In particular, this variant of the issuance protocol uses the OPRF(P-384, SHA-384) ciphersuite. </del>  <del> In this variant, Issuers provide a Private and Public Key, denoted "skI" and "pkI" respectively, used to produce tokens as input to the protocol.  See issuer-configuration for how this key-pair is generated. </del>  Clients provide the following as input to the issuance protocol:  Issuer name: An identifier for the Issuer.  This is typically a host name that can be used to construct HTTP requests to the Issuer. The values "token_input" and "blinded_element" are stored locally and used later as described in private-finalize.  The Client then <del> generates an HTTP POST request to send to the Issuer, with the TokenRequest as the content.  The media type for this request is "application/private-token-request".  An example request is shown below. </del>  5.2. Clients provide the following as input to the issuance protocol:  Issuer name: An identifier for the Issuer.  This is typically a host name that can be used to construct HTTP requests to the Issuer. "blinded_msg" is the Nk-octet request defined above. <del> The Client then generates an HTTP POST request to send to the Issuer, with the TokenRequest as the content.  The media type for this request is "application/private-token-request".  An example request is shown below: </del>  6.2. blind RSA documents also apply in the Privacy Pass use-case. Considerations related to broader privacy and security concerns in a multi-Client and multi-Issuer setting are deferred to the <del> Architecture document ARCHITECTURE. </del>  Beyond these considerations, it is worth highlighting the fact that Client TokenRequest messages contain truncated token key IDs.  This browsing history.  Depending on the deployment model, separating these contexts can take different forms.  The Origin, Attester, and Issuer portrayed in fig-overview can be instantiated and deployed in <del> a number of ways.  This section covers some expected deployment models and their corresponding security and privacy considerations. </del>  The discussion below assumes non-collusion between entities that have access to the attestation context and entities that have access to 4.2. In this model, the Attester and Issuer are operated by the same <del> entity that is separate from the Origin, as shown in the figure below. </del>  This model is useful if an Origin wants to offload attestation and issuance to a trusted entity.  In this model, the Attester and Issuer In this model, the Origin and Issuer are operated by the same entity, separate from the Attester, as shown in the figure below.  The Issuer <del> accepts token requests that come from trusted Attesters.  Depending on the issuance protocol, the Attester may relay these requests between Client and Issuer over an authenticated channel, or trust may be established in some other manner. </del>  This model is useful for Origins that require Client-identifying attestation, e.g., through the use of application-layer account different entities, as shown in the figure below.  As with the joint Origin and Issuer model, the Issuer accepts token requests that come from trusted Attesters, and the details of that trust establishment <del> depend on the issuance protocol. </del>  This is the most general deployment model, and is necessary for some types of issuance protocols where the Attester plays a role in token

Split attesters and issuers are not required for the basic issuance protocol, but we should explain (in a sentence or so) that if you are using a split attester, the client sends the request to the attester, and the attester forwards the request to the issuer if it accepts the client.
For better clarity and consistency, I recommend adding a sequence diagram depicting this model considering the sequence diagrams that outline other models.
Agreed. This would be a good thing to include. I'll take this and add it.
In a split attester/issuer scenario, the issuer needs to authenticate the attester in some way (e.g., TLS client cert). In a combined attester/issuer scenario, the actual protocol might be something proprietary (or covered by an as-yet-unwritten spec) that extends the base issuance protocol, e.g., adding an attestation header, user login cookie, or adding extra challenge/response rounds to confirm identity. If these issues are "in scope" then they should be defined here. If they are "out of scope" then it would be helpful context to reader to describe what is expected to be handled by a proprietary extension.
NAME we discuss these things in the architecture document where deployment models are discussed. But we should mention the impact that different deployment models have on the basic issuance protocol in the -protocol spec.

3. <ins> The issuance protocols defined in this document embody the core of Privacy Pass.  Clients receive TokenChallenge inputs from the redemption protocol (AUTHSCHEME, Section 2.1) and use the issuance protocols to produce corresponding Token values (AUTHSCHEME, Section 2.2).  The issuance protocol describes how Clients and Issuers interact to compute a token using a one-round protocol consisting of a TokenRequest from the Client and TokenResponse from the Issuer.  This interaction is shown below. The TokenChallenge inputs to the issuance protocols described in this document can be interactive or non-interactive, and per-origin or cross-origin. The issuance protocols defined in this document are compatible with any deployment model defined in Section 4 of ARCHITECTURE.  The details of attestation are outside the scope of the issuance protocol; see Section 4 of ARCHITECTURE for information about how attestation can be implemented in each of the relevant deployment models. This document describes two variants of the issuance protocol: one that is privately verifiable (private-flow) using the issuance private key based on the oblivious pseudorandom function from OPRF, and one that is publicly verifiable (public-flow) using the issuance public key based on the blind RSA signature scheme BLINDRSA. 4. </ins> Issuers MUST provide two parameters for configuration: Issuer Request URI: A token request URL for generating access known/token-issuer-directory; see wkuri-reg for the registration information for this well-known URI.  5.  <ins> The privately verifiable issuance protocol allows Clients to produce Token values that verify using the Issuer Private Key. This protocol is based on the oblivious pseudorandom function from OPRF. </ins>  <ins> Issuers provide a Private and Public Key, denoted "skI" and "pkI" respectively, used to produce tokens as input to the protocol.  See issuer-configuration for how this key pair is generated. </ins> Clients provide the following as input to the issuance protocol: <ins> Issuer Request URI: A URI to which token request messages are sent.  This can be a URL derived from the "issuer-request-uri" value in the Issuer's directory resource, or it can be another Client-configured URL.  The value of this parameter depends on the Client configuration and deployment model.  For example, in the 'Joint Origin and Issuer' deployment model, the Issuer Request URI might be correspond to the Client's configured Attester, and the Attester is configured to relay requests to the Issuer. </ins> Issuer name: An identifier for the Issuer.  This is typically a host name that can be used to construct HTTP requests to the Issuer. The values "token_input" and "blinded_element" are stored locally and used later as described in private-finalize.  The Client then  <ins> generates an HTTP POST request to send to the Issuer Request URI, with the TokenRequest as the content.  The media type for this request is "application/private-token-request".  An example request is shown below. </ins> 5.2. Clients provide the following as input to the issuance protocol: <ins> Issuer Request URI: A URI to which token request messages are sent.  This can be a URL derived from the "issuer-request-uri" value in the Issuer's directory resource, or it can be another Client-configured URL.  The value of this parameter depends on the Client configuration and deployment model.  For example, in the 'Split Origin, Attester, Issuer' deployment model, the Issuer Request URI might be correspond to the Client's configured Attester, and the Attester is configured to relay requests to the Issuer. </ins> Issuer name: An identifier for the Issuer.  This is typically a host name that can be used to construct HTTP requests to the Issuer. "blinded_msg" is the Nk-octet request defined above.  <ins> The Client then generates an HTTP POST request to send to the Issuer Request URI, with the TokenRequest as the content.  The media type for this request is "application/private-token-request".  An example request is shown below: </ins> 6.2. blind RSA documents also apply in the Privacy Pass use-case. Considerations related to broader privacy and security concerns in a multi-Client and multi-Issuer setting are deferred to the  <ins> Architecture document ARCHITECTURE.  Moreover, deployment-specific considerations regarding Client privacy when running the issuance protocol, especially with respect to Client-specific identifiers such as IP addresses that are revealed to the Attester and Issuer during issuance, are also discussed in Section 4 of ARCHITECTURE. </ins> Beyond these considerations, it is worth highlighting the fact that Client TokenRequest messages contain truncated token key IDs.  This browsing history.  Depending on the deployment model, separating these contexts can take different forms.  The Origin, Attester, and Issuer portrayed in fig-overview can be instantiated and deployed in  <ins> a number of ways. This section covers some expected deployment models and their corresponding security and privacy considerations.  Each deployment model is described in terms of the trust relationships and communication patterns between Client, Attester, Issuer, and Origin. </ins> The discussion below assumes non-collusion between entities that have access to the attestation context and entities that have access to 4.2. In this model, the Attester and Issuer are operated by the same  <ins> entity that is separate from the Origin.  The Origin trusts the joint Attester and Issuer to perform attestation and issue Tokens.  Clients interact with the joint Attester and Issuer for attestation and issuance.  This arrangement is shown in the figure below. </ins> This model is useful if an Origin wants to offload attestation and issuance to a trusted entity.  In this model, the Attester and Issuer In this model, the Origin and Issuer are operated by the same entity, separate from the Attester, as shown in the figure below.  The Issuer  <ins> accepts token requests that come from trusted Attesters.  Since the Attester and Issuer are separate entities, the Attester must authenticate itself to the Issuer.  In settings where the Attester is a Client-trusted service, one way Attesters can authenticate to Issuers is via mutually-authenticated TLS.  However, alernative authentication mechanisms are possible.  This arrangement is shown below. </ins> This model is useful for Origins that require Client-identifying attestation, e.g., through the use of application-layer account different entities, as shown in the figure below.  As with the joint Origin and Issuer model, the Issuer accepts token requests that come from trusted Attesters, and the details of that trust establishment  <ins> depend on the issuance protocol and relationship between Attester and Issuer. </ins> This is the most general deployment model, and is necessary for some types of issuance protocols where the Attester plays a role in token


Rewrite parts of intro Clean up protocol overview Rewrite API functions Rewrite protocol instantiation Update ciphersuites (This is a big change, apologies!) cc NAME NAME for reviews (will also notify mailing list).
API has been updated at URL quite substantially.
SecretKey, to me, implies a symmetric key. Can we make this PrivateKey? That's the terminology used (mostly) in RFC7748, at least.
Done in

6.3.2. <ins> For this functionality, note that we supply multiple tokens in "msg" to "Evaluate".  This allows batching a single proof object for multiple evaluations.  While the construction in I-D.irtf-cfrg-voprf only permits a single input, we follow the advice for providing vectors of inputs. </ins> 6.3.3. <ins> Similarly to "Issue", we follow the advice for providing vectors of inputs to the "Unblind" function for verifying the batched proof object. </ins> 6.3.4. 6.3.5.


5.3. <del> This setting is inspired by recently proposed APIs such as TRUST.  It is similar to the SIFV configuration, except that the verifiers V no longer interact with the issuer S.  Only C interacts with S, and this is done asynchronously to the trust attestation request from V. Hence "Asynchronous-Verifier" (SIAV). </del>  When V invokes a redemption for C, C then invokes a redemption exchange with S in a separate session.  If verification is carried one time is highly preferable (leading to a maximum of 64 possible user segregations).  However, as highlighted in parametrization, having a very large user base (> 5 million users), could potentially <del> allow for larger values (for example, up to 8 issuers).  Issuer replacements should only occur with the same frequency as config rotations as they can lead to similar losses in privacy if clients still hold redemption tokens for previously active issuers. </del>  In addition, we RECOMMEND that trusted registries indicate at all times which issuers are deemed to be active.  If a client is asked to redemption tokens in storage and then stores the newly acquired tokens.  6.2. <del> While redemption tokens themselves encode no information about the client redeeming them, problems may occur if too many redemptions are allowed in a short burst.  For instance, in the Internet setting, this may allow non-terminating verifiers to learn more information from the metadata that the client may hold (such as first-party cookies for other domains).  Mitigations for this issue are similar to those proposed in issuers for tackling the problem of having large number of issuers. </del>  In SIAV, cached SRRs and their associated issuer public keys have a similar tracking potential to first party cookies in the browser single reference point for those implementing the protocol. Firstly, let U be the total number of users, I be the total number of <del> issuers.  Assuming that each user accept tokens from a uniform sampling of all the possible issuers, as a worst-case analysis, this segregates users into a total of 2^I buckets.  As such, we see an exponential reduction in the size of the anonymity set for any given user.  This allows us to specify the privacy constraints of the protocol below, relative to the setting of A. </del>  8.1. We make the following assumptions in these parameter choices. Inferring the identity of a user in a 5000-strong anonymity set is <del> difficult </del>  After 2 weeks, all clients in a system will have rotated to the <del> new key </del>  <del> The maximum choice of I is based on the equation 1/2 * U/2^I = A. This is because I issuers lead to 2^I segregations of the total user- base U.  By reducing I we limit the possibility of performing the attacks mentioned in segregation. </del>  We must also account for each user holding issued data for more then one possible active keys.  While this may also be a vector for Using the specification above, we can give some example parameterizations.  For example, the current Privacy Pass browser <del> extension PPEXT has over 150,000 active users (from Chrome and Firefox).  As a result, log_2(U/A) is approximately 5 and so the maximum value of I should be 4. </del>  If the value of U is much bigger (e.g. 5 million) then this would <del> permit I = log_2(5000000/5000)-1 = 8 issuers. </del>  9. 11.2. <del> The Trust Token API TRUST has been devised as a generic API for providing Privacy Pass functionality in the browser setting.  The API is intended to be implemented directly into browsers so that server's can directly trigger the Privacy Pass workflow. </del>  11.3. requests, and is necessary for achieving the unforgeability requirement.  6. In this section, we show how to instantiate the functional API in pp-

Add allowances in protocol doc for redemption metadata Provide privacy analysis of including metadata to architecture doc Update privacy parametrizations cc NAME NAME NAME (I don't know everyone's github usernames, so feel free to add others who will be interested in reviewing).
LGTM
The main protocol document assumes that VOPRF is the main instantiation of PrivacyPass. It also has support for ciphersuites that augment this particular instantiation. It's not clear how we'd "extend" this protocol to support other features, such as public verifiability or the k-bits of metadata. These seem to be separate "modes" or "configurations" of PrivacyPass. (I don't think it makes sense to try and cast the metadata bit variant as a different ciphersuite for the main instantiation.) I propose we add some text describing different configurations. A configuration is an instantiation of the PrivacyPass API with certain properties. A configuration may (should?) also be extensible where applicable, e.g., in the ServerUpdate message or IssuanceRequest/Response messages. Interoperability across configurations would be unsupported, as they have would like have fundamentally different properties. Some initial configurations that come to mind are: PrivacyPass with no metadata bits (VOPRF construction) PrivacyPass with k metadata bits (Google's design) PrivacyPass with public verifiability (blind signatures?) cc NAME
Added some more information about supporting additional metadata in . As discussed elsewhere, I think the way to go here is for extensions to just specify new ciphersuites with associated privacy/security guarantees.
A number of applications expect the Servers to be able to add a small amount of metadata to the Privacy Pass protocol. We should add a discussion on how metadata should be added to tokens, and then describe the subsequent impact that this would have on the client's expected privacy budget. Generally speaking, adding a bit of metadata to tokens is likely to have a very similar impact to introducing an extra Issuer, and so this is something that will have to be covered in the general parametrization guidelines in the architecture document. Specific mechanisms for adding metadata to tokens are yet to be proposed, but may appear as alternative instantiations in the protocol document, or be specified separately as individual extensions.
LGTM. We’ll need to work through the extensibility support for the metadata bit variant next.

5.3.  <ins> This setting is inspired by recently proposed APIs such as TrustTokenAPI.  It is similar to the SIFV configuration, except that the verifiers V no longer interact with the issuer S.  Only C interacts with S, and this is done asynchronously to the trust attestation request from V.  Hence "Asynchronous-Verifier" (SIAV). </ins> When V invokes a redemption for C, C then invokes a redemption exchange with S in a separate session.  If verification is carried one time is highly preferable (leading to a maximum of 64 possible user segregations).  However, as highlighted in parametrization, having a very large user base (> 5 million users), could potentially  <ins> allow for larger values.  Issuer replacements should only occur with the same frequency as config rotations as they can lead to similar losses in privacy if clients still hold redemption tokens for previously active issuers. </ins> In addition, we RECOMMEND that trusted registries indicate at all times which issuers are deemed to be active.  If a client is asked to redemption tokens in storage and then stores the newly acquired tokens. <ins> 6.1.3. In draft-davidson-pp-protocol, it is permissible to add public and private metadata bits to redemption tokens.  While the core protocol instantiation that is described does not include additional metadata, future instantiations may use this functionality to provide redemption verifiers with additional information about the user. Note that any arbitrary bits of information can be used to further segment the size of the user's anonymity set.  Any issuer that wanted to track a single user could add a single metadata bit to user tokens.  For the tracked user it would set the bit to "1", and "0" otherwise.  Adding additional bits provides an exponential increase in tracking granularity similarly to introducing more issuers (though with more potential targeting). For this reason, the amount of metadata used by an issuer in creating redemption tokens must be taken into account together with the bits of information that issuer's may learn about clients from the means listed above.  We discuss this more in parametrization. </ins> 6.2.  <ins> Privacy losses may be encountered if too many redemptions are allowed in a short burst.  For instance, in the Internet setting, this may allow non-terminating verifiers to learn more information from the metadata that the client may hold (such as first-party cookies for other domains).  Mitigations for this issue are similar to those proposed in issuers for tackling the problem of having large number of issuers. </ins> In SIAV, cached SRRs and their associated issuer public keys have a similar tracking potential to first party cookies in the browser single reference point for those implementing the protocol. Firstly, let U be the total number of users, I be the total number of  <ins> issuers.  We let M be the total number of metadata bits that are allowed to be added by any given issuer.  Assuming that each user accept tokens from a uniform sampling of all the possible issuers, as a worst-case analysis, this segregates users into a total of 2^I buckets.  As such, we see an exponential reduction in the size of the anonymity set for any given user.  This allows us to specify the privacy constraints of the protocol below, relative to the setting of A. </ins> 8.1. We make the following assumptions in these parameter choices. Inferring the identity of a user in a 5000-strong anonymity set is  <ins> difficult. </ins> After 2 weeks, all clients in a system will have rotated to the  <ins> new key. In terms of additional metadata, the only concrete applications of Privacy Pass that use additional metadata require just a single bit. Therefore, we set the ceiling of permitted metadata to 1 bit for now, this may be revisited in future revisions. </ins>  <ins> The maximum choice of I is based on the equation 1/2 * U/2^(2I) = A. This is derived from the fact that permitting I issuers lead to 2^I segregations of the total user-base U.  Moreover, if we permit M = 1, then this effectively halves the anonymity set for each issuer, and thus we incur a factor of 2I in the exponent.  By reducing I, we limit the possibility of performing the attacks mentioned in segregation. </ins> We must also account for each user holding issued data for more then one possible active keys.  While this may also be a vector for Using the specification above, we can give some example parameterizations.  For example, the current Privacy Pass browser  <ins> extension PPEXT has nearly 300000 active users (from Chrome and Firefox).  As a result, log_2(U/A) is approximately 6 and so the maximum value of I should be 3. </ins> If the value of U is much bigger (e.g. 5 million) then this would  <ins> permit I = (log_2(5000000/5000)-1)/2 ~= 4 issuers. </ins> 9. 11.2.  <ins> The Trust Token API TrustTokenAPI has been devised as a generic API for providing Privacy Pass functionality in the browser setting.  The API is intended to be implemented directly into browsers so that server's can directly trigger the Privacy Pass workflow. </ins> 11.3. requests, and is necessary for achieving the unforgeability requirement. <ins> 5.4. Some use-cases of the Privacy Pass protocol benefit from associating a limited amount of metadata with tokens that can be read by the Issuer when a token is redeemed.  Adding metadata to tokens can be used as a vector to segment the anonymity of the protocol Clients. Therefore, it is important that any metadata that is added is heavily limited. Any additional metadata that can be added to redemption tokens should be described in the specific protocol instantiation.  Note that any additional metadata will have to be justified in light of the privacy concerns raised above.  For more details on the impacts associated with segmenting user privacy, see draft-davidson-pp-architecture. Any metadata added to tokens will be considered either "public" or "private".  Public metadata corresponds to unmodifiable bits that a client can read.  Private metadata corresponds to unmodifiable private bits that should be obscured to the client. Note that the instantiation in voprf-protocol provides randomized redemption tokens with no additional metadata for an Issuer with a single key. </ins> 6. In this section, we show how to instantiate the functional API in pp-


type indicates the issuance protocol used to generate the token. Values are registered in an IANA registry, token-types. Challenges with unsupported token_type values MUST be ignored.  "issuer_name" is a string containing the name of the issuer.  This is a hostname that is used to identify the issuer that is allowed The structure fields are defined as follows: "token_type" is a 2-octet integer, in network byte order.  This <del> value must match the value in the challenge (challenge). </del>  "nonce" is a 32-octet message containing a client-generated random nonce. Name: Name of the issuance protocol  Publicly Verifiable: A Y/N value indicating if the output tokens are publicly verifiable Name: Private Use  Publicly Verifiable: N/A Public Metadata: N/A Name: VOPRF (P-384, SHA-384)  Publicly Verifiable: N Public Metadata: N Name: Blind RSA (2048-bit)  Publicly Verifiable: Y Public Metadata: N The Privacy Pass architecture consists of four logical entities - Client, Origin, Issuer, and Attester - that work in concert for token redemption and issuance.  This section describes the purpose of token <del> redemption and issuance and the requirements on the relevant participants. </del>  The typical interaction flow for Privacy Pass uses the following steps: opportunistically present Token values to Origins without a corresponding TokenChallenge.  The challenge provides the client with the information necessary to obtain tokens that the server might subsequently accept in the redemption context.  There are a number of ways in which the token redemption protocol (AUTHSCHEME, Section 2.1) and produces a Token (AUTHSCHEME, Section 2.2), as shown in the figure below.  Clients interact with the Attester and Issuer to produce a token in response to a challenge.  The context in which an Attester vouches for a Client during issuance is referred to as the attestation

The token_type field in and determines the remainder of each of these structures. This isn't explicitly stated anywhere, but I think it's an implicit assumption we've all been making.

type indicates the issuance protocol used to generate the token. Values are registered in an IANA registry, token-types. Challenges with unsupported token_type values MUST be ignored. <ins> This value determines the structure and semantics of the rest of the structure. </ins> "issuer_name" is a string containing the name of the issuer.  This is a hostname that is used to identify the issuer that is allowed The structure fields are defined as follows: "token_type" is a 2-octet integer, in network byte order.  This  <ins> value must match the value in the challenge (challenge).  This value determines the structure and semantics of the rest of the structure. </ins> "nonce" is a 32-octet message containing a client-generated random nonce. Name: Name of the issuance protocol <ins> Token Structure: The contents of the Token structure TokenChallenge Structure: The contents of the TokenChallenge structure </ins> Publicly Verifiable: A Y/N value indicating if the output tokens are publicly verifiable Name: Private Use <ins> Token Structure: As defined in TokenChallenge Structure: As defined in </ins> Publicly Verifiable: N/A Public Metadata: N/A Name: VOPRF (P-384, SHA-384) <ins> Token Structure: As defined in TokenChallenge Structure: As defined in </ins> Publicly Verifiable: N Public Metadata: N Name: Blind RSA (2048-bit) <ins> Token Structure: As defined in TokenChallenge Structure: As defined in </ins> Publicly Verifiable: Y Public Metadata: N The Privacy Pass architecture consists of four logical entities - Client, Origin, Issuer, and Attester - that work in concert for token redemption and issuance.  This section describes the purpose of token  <ins> the redemption and issuance protocols and the requirements on the relevant participants. </ins> The typical interaction flow for Privacy Pass uses the following steps: opportunistically present Token values to Origins without a corresponding TokenChallenge. <ins> The structure and semantics of the TokenChallenge and Token messages depend on the issuance protocol and token type being used; see AUTHSCHEME for more information. </ins> The challenge provides the client with the information necessary to obtain tokens that the server might subsequently accept in the redemption context.  There are a number of ways in which the token redemption protocol (AUTHSCHEME, Section 2.1) and produces a Token (AUTHSCHEME, Section 2.2), as shown in the figure below. <ins> The structure and semantics of the TokenRequest and TokenResponse messages depend on the issuance protocol and token type being used; see ISSUANCE for more information. </ins> Clients interact with the Attester and Issuer to produce a token in response to a challenge.  The context in which an Attester vouches for a Client during issuance is referred to as the attestation


Privacy Pass is an architecture for authorization based on privacy- preserving authentication mechanisms.  Typical approaches for <del> authorizing clients, such as through the use of long-term cookies, are not privacy-friendly since they allow servers to track clients across sessions and interactions.  Privacy Pass takes a different approach: instead of presenting linkable state-carrying information to servers, e.g., a cookie indicating whether or not the client is an authorized user or has completed some prior challenge, clients present unlinkable proofs that attest to this information.  These proofs, or tokens, are private in the sense that a given token cannot be linked to the protocol interaction where that token was initially issued. </del>  At a high level, the Privacy Pass architecture consists of two protocols: redemption and issuance.  The redemption protocol, The typical interaction flow for Privacy Pass uses the following steps: <del> A Client interacts with an Origin by sending an HTTP request.  The Origin sends an HTTP response that contains a token challenge that indicates a specific Issuer to use.  Note that the request might be made as part of accessing a resource normally, or with the specific intent of triggering a token challenge. </del>  If the Client already has a token available that satisfies the token challenge, e.g., because the Client has a cache of

The interaction model here doesn't really need to use HTTP as far as I can tell. Obviously, the specific protocols need to be more concrete, but the architecture works without specifically saying that the interactions use HTTP. The overview specifically mentions HTTP only with respect to the Client-Origin interactions, not other interactions, but I can't see how this is necessary.
No, it doesn't need to use HTTP. The auth scheme document that instantiates the challenges and redemption does use HTTP, but other mechanisms can be used.
I'm OK de-emphasizing HTTP in the architecture if it helps simplify the presentation. Beyond it overly restrictive, was there another reason that led to this issue, NAME
Only that I know that this has obvious applications beyond HTTP and the architecture has no direct need to use it.
Request/response is still a bit implying HTTP, but I'm OK with this change.

Privacy Pass is an architecture for authorization based on privacy- preserving authentication mechanisms.  Typical approaches for  <ins> authorizing clients, such as through the use of long-term state (cookies), are not privacy-friendly since they allow servers to track clients across sessions and interactions.  Privacy Pass takes a different approach: instead of presenting linkable state-carrying information to servers, e.g., a cookie indicating whether or not the client is an authorized user or has completed some prior challenge, clients present unlinkable proofs that attest to this information. These proofs, or tokens, are private in the sense that a given token cannot be linked to the protocol interaction where that token was initially issued. </ins> At a high level, the Privacy Pass architecture consists of two protocols: redemption and issuance.  The redemption protocol, The typical interaction flow for Privacy Pass uses the following steps:  <ins> A Client interacts with an Origin by sending a request or otherwise interacting with the Origin in a way that triggers a response containing a token challenge.  The token challenge indicates a specific Issuer to use. </ins> If the Client already has a token available that satisfies the token challenge, e.g., because the Client has a cache of


An entity that issues tokens to Clients for properties attested to by the Attester. <del> An entity that attests to properties of Client for the purposes of token issuance. </del>  3. Attester, then a Client may use either of these trusted Attesters to issue and redeem tokens for origin.example.  However, origin.example neither explicitly specifies nor learns the <del> Attesters or their attestation formats used for token issuance. </del>  Redemption context.  Challenges can be bound to a given redemption context, which influences a client's ability to pre-fetch and state include the Client's geographic region and whether the Client has a valid application-layer account. <del> Attesters may support different types of attestation procedures.  A type of attestation procedure is also referred as an attestation format. </del>  <del> In general, each attestation format has different security </del>  properties.  For example, attesting to having a valid account is different from attesting to running on trusted hardware.  In general, <del> minimizing the set of attestation formats helps minimize the amount of information leaked through a token. </del>  <del> Each attestation format also has an impact on the overall system </del>  privacy.  Requiring a conjunction of attestation types could decrease the overall anonymity set size.  For example, the number of Clients that have solved a CAPTCHA in the past day, that have a valid and require configuration changes to address the underlying cause. For example, if attestation is compromised because of a zero-day exploit on compliant devices, then the corresponding attestation <del> format should be untrusted until the exploit is patched.  Addressing changes in attestation quality is therefore a deployment-specific task.  In Split Attester and Issuer deployments (see deploy-split), Issuers can choose to remove compromised Attesters from their trusted set until the compromise is patched. </del>  3.2.2.

From Section 3.2.1: This is a pretty wild equivalence. I stumbled badly on this one. It's very much like saying "in this context a verb is sometimes referred to as a noun". Is the goal here to say that "there is a attestation process by which the Attester determines whether a Client meets the requirements for issuance; if successful, the Attester captures this information using an attestation format" ? That seems to be the case, but that's not what this says.
I think we might just drop the equivalence to avoid confusion, but in the interest of transparency, here's where it came from. Consider the two following types of attestation procedures: Attestation based on , where the client and attester use this mechanism to prove that the client's device is valid. Attestation based on , perhaps where the signature is computed in some client enclave, where the client authenticates its token request with such a ring signature. In (1), attestation is some procedure that takes place between client and attester, whereas in (2) attestation is sort of non-interactive mechanism for producing an attestation format or proof of sorts. Since we don't specify the details of attestation, the text was written in a way to be maximally accommodating to these types of things. In any case, I think it's probably fine to just treat attestation as a procedure_, be it interactive or non-interactive or whatever, and that procedure has certain properties associated with it. I'll propose text.

An entity that issues tokens to Clients for properties attested to by the Attester.  <ins> An entity that attests to properties of Clients for the purposes of token issuance. The procedure by which an Attester determines whether or not a Client is trusted with a specific set of properties for token issuance. </ins> 3. Attester, then a Client may use either of these trusted Attesters to issue and redeem tokens for origin.example.  However, origin.example neither explicitly specifies nor learns the  <ins> Attesters or their specific attestation procedures used for token issuance. </ins> Redemption context.  Challenges can be bound to a given redemption context, which influences a client's ability to pre-fetch and state include the Client's geographic region and whether the Client has a valid application-layer account.  <ins> Attesters may support different types of attestation procedures. </ins>  <ins> In general, each attestation procedure has different security </ins> properties.  For example, attesting to having a valid account is different from attesting to running on trusted hardware.  In general,  <ins> minimizing the set of supported attestation procedures helps minimize the amount of information leaked through a token. </ins>  <ins> Each attestation procedure also has an impact on the overall system </ins> privacy.  Requiring a conjunction of attestation types could decrease the overall anonymity set size.  For example, the number of Clients that have solved a CAPTCHA in the past day, that have a valid and require configuration changes to address the underlying cause. For example, if attestation is compromised because of a zero-day exploit on compliant devices, then the corresponding attestation  <ins> procedure should be untrusted until the exploit is patched. Addressing changes in attestation quality is therefore a deployment- specific task.  In Split Attester and Issuer deployments (see deploy- split), Issuers can choose to remove compromised Attesters from their trusted set until the compromise is patched. </ins> 3.2.2.


Attesters SHOULD not admit attestation types that result in small anonymity sets. <del> The trustworthiness of Attesters depends on their ability to correctly and reliably perform attestation during the issuance protocol.  Indeed, Issuers trust Attesters to correctly and reliably perform attestation.  However, certain types of attestation can vary in value over time, e.g., if the attestation process is compromised or maliciously automated.  These are considered exceptional events and require configuration changes to address the underlying cause. For example, if attestation is compromised because of a zero-day exploit on compliant devices, then the corresponding attestation procedure should be untrusted until the exploit is patched. Addressing changes in attestation quality is therefore a deployment- specific task.  In Split Attester and Issuer deployments (see deploy- split), Issuers can choose to remove compromised Attesters from their trusted set until the compromise is patched. </del>  3.2.2.

Section 3.2.1 talks about the need for issuers to trust attesters. This is probably the main trust relationship (see ) involved regarding attestation. The other trust basis is the extent to which the attester trusts the client, though the point is probably that the attester starts out being extremely skeptical about the client and so acts to validate them. This is fine (though I would delete the first sentence of the last paragraph of this section). However, the remainder of this text talks about how to handle an attester that goes bad. None of this acknowledges the real problem, which is that in a setting where an issuer works with multiple attesters, but issues from a single key, a failure in one attester cannot result in tokens being invalidated for just that attester. The information about which attester was involved in token issuance is erased by the issuer, deliberately. It might even be the case (thanks to consistency requirements) that the issuer cannot revoke tokens at all. The only recourse is the one that is noted, which is that the attester cannot be used for future issuance. The doc should probably talk about those tokens that were issued though.
Talking about tokens in circulation post-attestation-compromise is a good suggestion. I'll take this issue and propose text.
Approved pending one comment

Attesters SHOULD not admit attestation types that result in small anonymity sets.  <ins> Issuers trust Attesters to correctly and reliably perform attestation.  However, certain types of attestation can vary in value over time, e.g., if the attestation procedure is compromised.  Broken attestation procedures are considered exceptional events and require configuration changes to address the underlying cause.  For example, if attestation is compromised because of a zero-day exploit on compliant devices, then the corresponding attestation procedure should be untrusted until the exploit is patched.  Addressing changes in attestation quality is therefore a deployment-specific task.  In Split Attester and Issuer deployments (see deploy-split), Issuers can choose to remove compromised Attesters from their trusted set until the compromise is patched. From the perspective of an Origin, tokens produced by an Issuer with at least one compromised Attester cannot be trusted assuming the Origin does not know which attestation procedure was used for issuance.  This is because the Origin cannot distinguish between tokens that were issued via compromised Attesters and tokens that were issued via uncompromised Attesters absent some distinguishing information in the tokens themselves or from the Issuer.  As a result, until the attestation procedure is fixed, the Issuer cannot be trusted by Origins.  Moreover, as a consequence, any tokens issued by an Issuer with a compromised attester may no longer be trusted by Origins, even if those tokens were issued to Clients interacting with an uncompromised Attester. </ins> 3.2.2.


of contexts: The interactions and set of information shared between the Client <del> and Origin.  This context includes all information associated with redemption, such as the timestamp of the event, Client visible information (including the IP address), and the Origin name. </del>  The interactions and set of information shared between the Client, <del> Attester, and Issuer.  This context includes all information associated with issuance, such as the timestamp of the event, any Client visible information (including the IP address), and the Origin name (if revealed during issuance). </del>  The interactions and set of information shared between the Client and Attester only, for the purposes of attesting the vailidity of <del> the Client.  This context includes all information associated with attestation, such as the timestamp of the event and any Client visibile information, including information needed for the attestation procedure to complete. </del>  The privacy goals of Privacy Pass are oriented around unlinkability based on these contexts.  In particular, Privacy Pass aims to achieve Origin-Client, Issuer-Client, and Attester-Origin unlinkability requires that issuance and redemption events be separated over time, <del> such as through the use of tokens with an empty redemption context, or be separated over space, such as through the use of an anonymizing proxy when connecting to the Origin. </del>  4.2.

The definition of the redemption/issuance/attestation contexts seem to exist primarily to support the different unlinkability goals in the document. Let's take the redemption one, which is defined as: A digression on perspective Note that "Client visible" is probably ambiguous here; it could mean information about the client that is visible (though to whom?) or information that is visible to the client. This suggests that your goal is establish a point of reference or perspective for these: in this case, the relevant perspective is that of an Origin. But this was not my main point... The corresponding unlinkability definition says: This is a little confusing, because you might conceive of the defines the context as enclosing a single interaction between the Client and Origin, but this implies that a context encompasses multiple interactions with either the same client or different clients (all of which are indistinguishable). That makes the definition of the context seem like it lacks something. Does this refer to the information that is provided within that context that might be used to identify a client, from the perspective of the server? Finally, there is mention of an "an empty redemption context" in Section 3.1. I had no idea how to interpret this claim. Does empty refer to the set of clients? The set of interactions? The information provided in that context?
The empty redemption context comment is talking about the field of the challenge being empty / zero-length.
Basically, yeah, this is the idea. Perhaps framing it this way would be a more clear description. NAME regarding "empty redemption context," maybe we just say "an empty token challenge redemption context," or something, to make it clear that this is referring to the challenge field described in Section 3.1?

of contexts: The interactions and set of information shared between the Client  <ins> and Origin, i.e., the information that is provided or otherwise available to the Origin during redemption that might be used to identify a Client and construct a token challenge.  This context includes all information associated with redemption, such as the timestamp of the event, Client visible information (including the IP address), and the Origin name. </ins> The interactions and set of information shared between the Client,  <ins> Attester, and Issuer, i.e., the information that is provided or otherwise available to Attester and Issuer during issuance that might be used to identify a Client.  This context includes all information associated with issuance, such as the timestamp of the event, any Client visible information (including the IP address), and the Origin name (if revealed during issuance).  This does not include the token challenge in its entirety, as that is kept secret from the Issuer during the issuance protocol. </ins> The interactions and set of information shared between the Client and Attester only, for the purposes of attesting the vailidity of  <ins> the Client, that is provided or otherwise available during attestation that might be used to identify the Client.  This context includes all information associated with attestation, such as the timestamp of the event and any Client visibile information, including information needed for the attestation procedure to complete. </ins> The privacy goals of Privacy Pass are oriented around unlinkability based on these contexts.  In particular, Privacy Pass aims to achieve Origin-Client, Issuer-Client, and Attester-Origin unlinkability requires that issuance and redemption events be separated over time,  <ins> such as through the use of tokens that correspond to token challenges with an empty redemption context (see redemption), or be separated over space, such as through the use of an anonymizing proxy when connecting to the Origin. </ins> 4.2.


The Privacy Pass issuance protocol, described in ISSUANCE, is a two- message protocol that takes as input a TokenChallenge from the redemption protocol (AUTHSCHEME, Section 2.1) and produces a Token <del> (AUTHSCHEME, Section 2.2), as shown in the figure below. </del>  The structure and semantics of the TokenRequest and TokenResponse messages depend on the issuance protocol and token type being used; 4.1. In this model, the Origin, Attester, and Issuer are all operated by <del> the same entity, as shown in the figure below. </del>  This model represents the initial deployment of Privacy Pass, as described in PrivacyPassCloudflare.  In this model, the Attester, entity that is separate from the Origin.  The Origin trusts the joint Attester and Issuer to perform attestation and issue Tokens.  Clients interact with the joint Attester and Issuer for attestation and <del> issuance.  This arrangement is shown in the figure below. </del>  This model is useful if an Origin wants to offload attestation and issuance to a trusted entity.  In this model, the Attester and Issuer authenticate itself to the Issuer.  In settings where the Attester is a Client-trusted service, one way Attesters can authenticate to Issuers is via mutually-authenticated TLS.  However, alernative <del> authentication mechanisms are possible.  This arrangement is shown below. </del>  This model is useful for Origins that require Client-identifying attestation, e.g., through the use of application-layer account Origin and Issuer model, the Issuer accepts token requests that come from trusted Attesters, and the details of that trust establishment depend on the issuance protocol and relationship between Attester and <del> Issuer. </del>  This is the most general deployment model, and is necessary for some types of issuance protocols where the Attester plays a role in token

This is a little hard to process... An inbound PR I have proposes a change to the first diagram that might help here. A little work on this is probably necessary. !
A few things: When drawing arrows on lines, the line will connect with the line neatly if there is a connector or if there is an arrow adjacent to the line: This puts the arrow on the line, which renders a gap in the line. Avoid this: The bottom-left corner here is not curved, because the detection of corners needs three characters: the corner and a line either side of that, so... Not:
NAME can you say more about how it's hard to process? As we recently discussed, we're burdened by being too close to this work, so it's hard for me to see a substantial difference between the diagram in this issue and that which you proposed in the recently merged PR. Is it not clear who touches or sees each message? Part of the challenge in this particular diagram -- and any in which the attester is party to the protocol -- is that the attester may be inline or may not be! The architecture does not require the attester to be inline, it really only requires that the token request from a client be somehow blessed by the attester. I'll think about ways to better visualize this, but clarification about the source of confusion would be super helpful.
For me, the hardest part of these diagrams is that the start and end of the end of the arrows aren't really attached to anything in particular. You rely on horizontal alignment a fair bit (the arrow starts approximately under the label "Issuer", so it's probably a message from the issuer). In comparison, the diagram I provided had lines and boxes connecting them. This is probably a more illustrative example: ! Are the TokenRequest and TokenResponse labels on the lines? Where do these arrows start? Is the Client/Attester/Issuer box a single entity (obviously, no) given how the challenge arrows hit it. Which entities perform attestation? Then there are the formatting issues, some of which I will concede are specific to aasvg, see the above comment.
Thanks -- that's helpful. I think should resolve the confusion.

The Privacy Pass issuance protocol, described in ISSUANCE, is a two- message protocol that takes as input a TokenChallenge from the redemption protocol (AUTHSCHEME, Section 2.1) and produces a Token  <ins> (AUTHSCHEME, Section 2.2), as shown in fig-overview. </ins> The structure and semantics of the TokenRequest and TokenResponse messages depend on the issuance protocol and token type being used; 4.1. In this model, the Origin, Attester, and Issuer are all operated by  <ins> the same entity, as shown in fig-deploy-shared. </ins> This model represents the initial deployment of Privacy Pass, as described in PrivacyPassCloudflare.  In this model, the Attester, entity that is separate from the Origin.  The Origin trusts the joint Attester and Issuer to perform attestation and issue Tokens.  Clients interact with the joint Attester and Issuer for attestation and  <ins> issuance.  This arrangement is shown in fig-deploy-joint-issuer. </ins> This model is useful if an Origin wants to offload attestation and issuance to a trusted entity.  In this model, the Attester and Issuer authenticate itself to the Issuer.  In settings where the Attester is a Client-trusted service, one way Attesters can authenticate to Issuers is via mutually-authenticated TLS.  However, alernative  <ins> authentication mechanisms are possible.  This arrangement is shown in fig-deploy-joint-origin. </ins> This model is useful for Origins that require Client-identifying attestation, e.g., through the use of application-layer account Origin and Issuer model, the Issuer accepts token requests that come from trusted Attesters, and the details of that trust establishment depend on the issuance protocol and relationship between Attester and  <ins> Issuer.  This arrangement is shown in fig-overview. </ins> This is the most general deployment model, and is necessary for some types of issuance protocols where the Attester plays a role in token


1. The Privacy Pass protocol as described in draft-davidson-pp-protocol <del> can be integrated with a number of different settings, from server to server communication to browsing the internet. </del>  In this document, we will provide an API to use for integrating Privacy Pass with an HTTP framework.  Providing the format of HTTP 1.1. <del> The following terms are used throughout this document. Server: A service that provides the server-side functionality required by the protocol documented here (typically denoted S). Client: An entity that seeks authorization from a server that supports interactions in the Privacy Pass protocol (typically denoted C). Key: The secret key used by the Server for authorizing client data. Commitment: Alternative name for Server's public key corresponding to the secret key that they hold. </del>  We assume that all protocol messages are encoded into raw byte format before being sent.  We use the TLS presentation language RFC8446 to wrapping: Describes the wrapping of messages within HTTP requests/ responses. <del> server-config: Describes how HTTP clients retrieve server </del>  configurations and key commitments. issuance: Describes how issuance requests are performed via a HTTP 2. <del> Messages from HTTP-based clients to HTTP-based servers are performed </del>  as GET and POST requests.  The messages are sent via the "Sec- Privacy-Pass" header. Note that the requests may contain addition Headers, request data and URL parameters that are not specified here, these extra fields should <del> be ignored, though may be used by the server to determine whether to </del>  fulfill the requested issuance/redemption. 3. <del> A client SHOULD fetch the server configuration and current key </del>  commitments prior to performing issuance and redemption.  This configuration is accessible via a "CONFIG_ENDPOINT", either provided <del> by the server or by a global registry that provides consistency and </del>  anonymization guarantees. 3.1. <del> To ensure that a server isn't providing different views of their key material/commitments to different users, servers are expected to write their commitments to a verifiable data structure. </del>  Using a verifiable log-backed map (verifiable-data-structures), the <del> server can publish their commitments to the log in a way that clients can detect when the server is attempting to provide a split-view of their key commitments to different clients. </del>  The key to the map is the "server_origin", with the value being: The addition to the log is made via a signed message to the log operator, which verifies the authenticity against a public key <del> associated with that server origin (either via the Web PKI or a out- of-band key). </del>  <del> The server SHOULD then store an inclusion proof of the current key </del>  commitment so that it can present it when delivering the key <del> commitment directly to the client or when the key commitment is being </del>  delivered by a delegated party (other registries/preloaded configuration lists/etc). <del> The client can then perform a request for the key commitment against either the global registry or the server as described key-commitment. </del>  <del> To avoid user segregation as a result of server configuration/ </del>  commitment rotation, the log operator SHOULD enforce limits on how many active commitments exist and how quickly the commitments are being rotated.  Clients SHOULD reject configurations/commitments that 3.2. <del> Inputs: - "server_origin": The origin to retrieve a server </del>  configuration for. No outputs. <del> The client makes an anonymous GET request to </del>  "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type "fetch-config" and a body of: <del> The server looks up the configuration associated with the origin </del>  "server_origin" and responds with a message of type "config" and a body of: <del> The client then stores the associated configuration state under </del>  the corresponding "server_origin". (TODO: This might be mergable with key commitment retrieval if 4. <del> The client SHOULD retrieve server key commitments prior to both an </del>  issuance and redemption to verify the consistency of the keys and to monitor for key rotation between issuance and redemption events. No outputs. <del> The client fetches the configuration state "server_id", </del>  "ciphersuite", "commitment_id" associated with "server_origin". <del> The client makes an anonymous GET request to </del>  "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type "fetch-commitment" and a body of: <del> The server looks up the current configuration, and constructs a </del>  list of commitments to return, noting whether a key commitment is valid for issuance or redemption or both. <del> The server then responds with a message of type "commitment" and a </del>  body of: <del> The client then verifies the signature for each key commitment and stores the list of commitments to the current scope.  The client </del>  SHOULD NOT cache the commitments beyond the current scope, as new commitments should be fetched for each independent issuance and <del> redemption request.  The client SHOULD verify the </del>  "inclusion_proofs" to confirm that the key commitment has been <del> submitted to a trusted registry. </del>  5. Outputs: - "tokens": A list of tokens that have been signed via the Privacy Pass protocol. <del> When a client wants to request tokens from a server, it should </del>  first fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment". <del> The client should then call the "CLIENT_ISSUE_GEN" interface requesting "count" tokens storing the resulting "c_data", "i_data", "g_data". </del>  <del> The client then makes a POST request to <"server_origin">/.well- </del>  known/privacy-pass with a message of type "request-issuance" and a body of: <del> The server, upon receipt of the "request" should call the "SERVER_ISSUE" interface with the value of "i_data" with a result of "server_issue_resp". </del>  <del> The server should then respond to the POST request with a message </del>  of type "issue" and a body of: <del> The client should then should call the "CLIENT_ISSUE_FINISH" interface with the resulting "ciphersuite", ```evals","proof", and stored"g_data"to extract a list of"tokens``. </del>  <del> The client should store the "public_key" associated with these tokens and the elements of "tokens" under storage partitioned by the "server_origin", accessible only via the Privacy Pass API. </del>  6. There are two forms of Privacy Pass redemption that could function under the HTTP API.  Either passing along a token directly to the target endpoint, which would perform its own redemption token- <del> redemption, or the client redeeming the token and passing the result </del>  along to the target endpoint.  These two methods are described below. 6.1. <del> Inputs: - "server_id": The server ID to redeem a token against.  - </del>  "ciphersuite": The ciphersuite for this token.  - "public_key": The <del> public key associated with this token.  - "token": A Privacy Pass token.  - "additional_data": Additional data to bind to this token </del>  redemption. Outputs: - "result": The result of the redemption from the server. <del> The client should call the "CLIENT_REDEEM" interface with "server_id", "ciphersuite", "public_key", "token" and auxiliary data of "additional_data" storing the resulting "data" and "tag". </del>  <del> The client makes a POST request to <"server_origin">/.well-known/ </del>  privacy-pass with a message of type "token-redemption" and a body of: <del> The server, upon receipt of "request" should call the "SERVER_REDEEM" interface with the "data", "tag", "aux" storing the resulting "resp". </del>  <del> The server should then respond to the POST request with a message </del>  of type "redemption-result" and a signed body of: <del> The client upon receipt of this message should verify the </del>  "signature" using the "verification_key" from the configuration and return the "result". 6.2. <del> Inputs: - "server_origin": The server origin to redeem a token for. </del>  - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. <del> When a client wants to redeem tokens for a server, it should first </del>  fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment". <del> The client should then look up the storage partition associated with "server_origin" and fetch a "token" and "public_key". </del>  <del> The client should verify that the "public_key" is in the current </del>  "commitment".  If not, it should discard the token and fail the redemption attempt. <del> As part of the request to "target", the client will include the </del>  token as part of the request in the "Sec-Privacy-Pass" header along with whatever other parameters are being passed as part of the request to "target".  The header will contain a message of 6.3. <del> Inputs: - "server_origin": The server origin to redeem a token for. </del>  - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. <del> When a client wants to redeem tokens for a server, it should first </del>  fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment". <del> The client should then look up the storage partition associated with "server_origin" and fetch a "token" and "public_key". </del>  <del> The client should verify that the "public_key" is in the current </del>  "commitment".  If not, it should discard the token and fail the redemption attempt. <del> The client constructs a bytestring "aux" made up of the "target", </del>  the current "timestamp", and "additional_data": <del> The client then performs a token redemption as described in token- </del>  redemption.  Storing the resulting "redemption-result" message. <del> As part of the request to "target", the client will include the </del>  redemption result as part of the request in the "Sec-Privacy-Pass" header along with whatever other parameters are being passed as part of the request to "target".  The header will contain a message of type "signed-redemption-result" with a body of: At this point, the "target" can verify the integrity of <del> "signed_redemption.aux" based on the values of "target", "timestamp", and "additional_data" and verify the signature of the redemption result by querying the current configuration of the Privacy Pass server.  The inclusion of "target" and "timestamp" proves that the server attested to the validity of the token in relation to this particular request. </del>  7.

cc NAME for review. Mainly just removing the interfaces that were previously present and using the API functions from the protocol directly. I've also changed some of the wording around the key registry, and replaced client -> Client and server -> Server. Let me know if there is anything that you think I've missed.
We currently have interfaces in the architecture document that lay out how messages should be sent and received. I think the architecture document should be solely focused on the building of the ecosystem in a way that maintains the utility of the privacy and security guarantees made by the protocol. The interfaces are mainly used by the HTTP API doc, and so I think this will be a better home for them.
I've removed the interfaces from the architecture doc () and used the protocol API directly in the HTTP doc ()

1. The Privacy Pass protocol as described in draft-davidson-pp-protocol  <ins> can be integrated with a number of different settings, from Server to Server communication to browsing the internet. </ins> In this document, we will provide an API to use for integrating Privacy Pass with an HTTP framework.  Providing the format of HTTP 1.1.  <ins> We use the same definition of Server and Client that is used in draft-davidson-pp-protocol and draft-davidson-pp-architecture. </ins> We assume that all protocol messages are encoded into raw byte format before being sent.  We use the TLS presentation language RFC8446 to wrapping: Describes the wrapping of messages within HTTP requests/ responses.  <ins> server-config: Describes how HTTP Clients retrieve server </ins> configurations and key commitments. issuance: Describes how issuance requests are performed via a HTTP 2.  <ins> Messages from HTTP-based Clients to HTTP-based Servers are performed </ins> as GET and POST requests.  The messages are sent via the "Sec- Privacy-Pass" header. Note that the requests may contain addition Headers, request data and URL parameters that are not specified here, these extra fields should  <ins> be ignored, though may be used by the Server to determine whether to </ins> fulfill the requested issuance/redemption. 3.  <ins> A Client SHOULD fetch the Server configuration and current public key </ins> commitments prior to performing issuance and redemption.  This configuration is accessible via a "CONFIG_ENDPOINT", either provided  <ins> by the Server or by a global registry that provides consistency and </ins> anonymization guarantees. 3.1.  <ins> To ensure that a Server isn't providing different views of their public key material to different users, Servers are expected to write their commitments to a verifiable data structure. </ins> Using a verifiable log-backed map (verifiable-data-structures), the  <ins> Server can publish their commitments to the log in a way that Clients can detect when the Server is attempting to provide a split-view of their key commitments to different Clients. </ins> The key to the map is the "server_origin", with the value being: The addition to the log is made via a signed message to the log operator, which verifies the authenticity against a public key  <ins> associated with that Server origin (either via the Web PKI or a out- of-band key).  The signature should be computed under a long-term signing key that is associated with the Server identity. </ins>  <ins> The Server SHOULD then store an inclusion proof of the current key </ins> commitment so that it can present it when delivering the key  <ins> commitment directly to the Client or when the key commitment is being </ins> delivered by a delegated party (other registries/preloaded configuration lists/etc).  <ins> The Client can then perform a request for the key commitment against either the global registry or the Server as described in key- commitment.  Note that the signature should be verified by the Client to ensure that the key material is owned by the Server.  This requires that the Client know the public verification key that is associated with the Server. </ins>  <ins> To avoid user segregation as a result of Server configuration/ </ins> commitment rotation, the log operator SHOULD enforce limits on how many active commitments exist and how quickly the commitments are being rotated.  Clients SHOULD reject configurations/commitments that 3.2.  <ins> Inputs: - "server_origin": The origin to retrieve a Server </ins> configuration for. No outputs.  <ins> The Client makes an anonymous GET request to </ins> "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type "fetch-config" and a body of:  <ins> The Server looks up the configuration associated with the origin </ins> "server_origin" and responds with a message of type "config" and a body of:  <ins> The Client then stores the associated configuration state under </ins> the corresponding "server_origin". (TODO: This might be mergable with key commitment retrieval if 4.  <ins> The Client SHOULD retrieve Server key commitments prior to both an </ins> issuance and redemption to verify the consistency of the keys and to monitor for key rotation between issuance and redemption events. No outputs.  <ins> The Client fetches the configuration state "server_id", </ins> "ciphersuite", "commitment_id" associated with "server_origin".  <ins> The Client makes an anonymous GET request to </ins> "CONFIG_ENDPOINT"/.well-known/privacy-pass with a message of type "fetch-commitment" and a body of:  <ins> The Server looks up the current configuration, and constructs a </ins> list of commitments to return, noting whether a key commitment is valid for issuance or redemption or both.  <ins> The Server then responds with a message of type "commitment" and a </ins> body of:  <ins> The Client then verifies the signature for each key commitment and stores the list of commitments to the current scope.  The Client </ins> SHOULD NOT cache the commitments beyond the current scope, as new commitments should be fetched for each independent issuance and  <ins> redemption request.  The Client SHOULD verify the </ins> "inclusion_proofs" to confirm that the key commitment has been  <ins> submitted to a trusted registry.  Once the Client receives the "ciphersuite" for the Server, it should implement all Privacy Pass API functions (as detailed in draft-davidson-pp-protocol) using this ciphersuite. </ins> 5. Outputs: - "tokens": A list of tokens that have been signed via the Privacy Pass protocol.  <ins> When a Client wants to request tokens from a server, it should </ins> first fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment".  <ins> The Client should then call the "Generate" function requesting "count" tokens storing the resulting "input" data. </ins>  <ins> The Client then makes a POST request to <"server_origin">/.well- </ins> known/privacy-pass with a message of type "request-issuance" and a body of:  <ins> The server, upon receipt of the "request" should call the "Issue" function with the "public_key", "secret_key" and the value of "msg" with a result of "resp". </ins>  <ins> The Server should then respond to the POST request with a message </ins> of type "issue" and a body of:  <ins> The Client should then should call the "Process" function with the "public_key", stored "inputs" and resulting "resp", to extract a list of "redemption_tokens". </ins>  <ins> The Client should store the "public_key" associated with these tokens and the elements of "redemption_tokens" under storage partitioned by the "server_origin", accessible only via the Privacy Pass API. </ins> 6. There are two forms of Privacy Pass redemption that could function under the HTTP API.  Either passing along a token directly to the target endpoint, which would perform its own redemption token-  <ins> redemption, or the Client redeeming the token and passing the result </ins> along to the target endpoint.  These two methods are described below. 6.1.  <ins> Inputs: - "server_id": The Server ID to redeem a token against.  - </ins> "ciphersuite": The ciphersuite for this token.  - "public_key": The  <ins> public key associated with this token.  - "redemption_token": A Privacy Pass token.  - "info": Additional data to bind to this token </ins> redemption. Outputs: - "result": The result of the redemption from the server.  <ins> The Client should call the "Redeem" function with "redemption_token" and additional data of "info" storing the resulting "data" and "tag". </ins>  <ins> The Client makes a POST request to <"server_origin">/.well-known/ </ins> privacy-pass with a message of type "token-redemption" and a body of:  <ins> The server, upon receipt of "request" should call the "Verify" interface with "public_key", "secret_key" and the received "data", "tag", "info" storing the resulting "resp". </ins>  <ins> The Server should then respond to the POST request with a message </ins> of type "redemption-result" and a signed body of:  <ins> The Client upon receipt of this message should verify the </ins> "signature" using the "verification_key" from the configuration and return the "result". 6.2.  <ins> Inputs: - "server_origin": The Server origin to redeem a token for. </ins> - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request.  <ins> When a Client wants to redeem tokens for a server, it should first </ins> fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment".  <ins> The Client should then look up the storage partition associated with "server_origin" and fetch a "redemption_token" and "public_key". </ins>  <ins> The Client should verify that the "public_key" is in the current </ins> "commitment".  If not, it should discard the token and fail the redemption attempt.  <ins> As part of the request to "target", the Client will include the </ins> token as part of the request in the "Sec-Privacy-Pass" header along with whatever other parameters are being passed as part of the request to "target".  The header will contain a message of 6.3.  <ins> Inputs: - "server_origin": The Server origin to redeem a token for. </ins> - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request.  <ins> When a Client wants to redeem tokens for a server, it should first </ins> fetch a key commitment from the issuer via the process described in key-commitment and keep the result as "commitment".  <ins> The Client should then look up the storage partition associated with "server_origin" and fetch a "redemption_token" and "public_key". </ins>  <ins> The Client should verify that the "public_key" is in the current </ins> "commitment".  If not, it should discard the token and fail the redemption attempt.  <ins> The Client constructs a bytestring "info" made up of the "target", </ins> the current "timestamp", and "additional_data":  <ins> The Client then performs a token redemption as described in token- </ins> redemption.  Storing the resulting "redemption-result" message.  <ins> As part of the request to "target", the Client will include the </ins> redemption result as part of the request in the "Sec-Privacy-Pass" header along with whatever other parameters are being passed as part of the request to "target".  The header will contain a message of type "signed-redemption-result" with a body of: At this point, the "target" can verify the integrity of  <ins> "signed_redemption.info" based on the values of "target", "timestamp", and "additional_data" and verify the signature of the redemption result by querying the current configuration of the Privacy Pass server.  The inclusion of "target" and "timestamp" proves that the Server attested to the validity of the token in relation to this particular request. </ins> 7.


on a fairly regular cycle to reduce the harmfulness of a server key compromise.  7.2. Similarly to the server rotation dynamic that is raised above, if 8.2. <del> We highlighted previously that short key-cycles can be used to reduce client privacy.  However, regular key rotations of the issuing key are still recommended to maintain good server key hygiene. We recommend that Privacy Pass issuing keys are rotated from anywhere between 1 and 12 weeks.  With an active user-base, a week gives a fairly large window for clients to participate in the Privacy Pass protocol and thus enjoy the anonymity guarantees of being part of a larger group.  The low ceiling of 12 weeks prevents a key compromise from being too destructive.  If a server realizes that a key compromise has occurred then the server should sample a new key and upload the public key to the key registry; invoking any revocation procedures that may apply for the old key. 8.3. </del> When a client holds tokens for an server, it is possible for any verifier to invoke that client to redeem tokens for that server. This can lead to an attack where a malicious verifier can force a need be, by providing an expiry date or by signaling that records from a particular window need to be refreshed. <del> 8.4. </del>  [[OPEN ISSUE: explain potential and mitigations for server centralization]]

cc NAME NAME
Yeah, I agree. Something to bring up for discussion.
LGTM, 1 week might still be too small of a window for actively malicious servers, but I think that ties in to the open issue regarding malicious servers rather than the generic key rotation considerations.

on a fairly regular cycle to reduce the harmfulness of a server key compromise. <ins> With an active user-base, a week gives a fairly large window for clients to participate in the Privacy Pass protocol and thus enjoy the anonymity guarantees of being part of a larger group.  The low ceiling of 12 weeks prevents a key compromise from being too destructive.  If a server realizes that a key compromise has occurred then the server should sample a new key, and upload the public key to the key registry; invoking any revocation procedures that may apply for the old key. </ins> 7.2. Similarly to the server rotation dynamic that is raised above, if 8.2.  When a client holds tokens for an server, it is possible for any verifier to invoke that client to redeem tokens for that server. This can lead to an attack where a malicious verifier can force a need be, by providing an expiry date or by signaling that records from a particular window need to be refreshed.  <ins> 8.3. </ins> [[OPEN ISSUE: explain potential and mitigations for server centralization]]


The public keys that are active for the server. <del> For reasons that we address later in privacy, the way that the server publishes and maintains this information impacts the effective privacy of the clients.  In this section, we describe the main policies that need to be satisfied for a key management system in a Privacy Pass ecosystem. </del>  <del> Note that we only specify a set of guidelines and recommendations for operating a public key registry in this document.  Actual specification of such a registry and how it operates will be covered elsewhere. </del>  <del> 4.1. </del>  <del> Server's must provide their public keys to clients along with details about the cryptographic ciphersuite that they are using.  In privacy, we address the importance of providing clients with sources of truth for learning the server's key configuration. In particular, server key material MUST be publicly available in a tamper-proof data structure, which we refer to as a key registry.  A registry must be globally consistent.  Clients using the same registry should coordinate in some way to ensure they have a consistent view of said registry.  This can be done via gossiping or some other mechanism.  The exact mechanism for this coordination will be described elsewhere.  It is assumed there will be at least one such mechanism. It is RECOMMENDED that each key registry is an append-only data structure, such as a Merkle Tree.  The key registry should be operated independently of any server that publishes key material to the registry.  This ensures that any client can make better judgements on whether to trust the registry and, transitively, each server. While there may be multiple key registries for a given ecosystem, a server MUST only publish its key material to a single registry.  This ensures that the server is keeping a consistent view of its key material. </del>  <del> 4.2. </del>  Token issuance associates all issued tokens with a particular choice of key.  If a server issues tokens with many keys, then this may harm possess has been issued under. To prevent against this, servers MUST only use one private key for <del> issuing tokens at any given time.  Servers may use two or more keys </del>  for redemption to allow servers for seamless key rotation. <del> Key rotations must be limited in frequency for similar reasons.  See parametrization for guidelines on what frequency of key rotations are permitted. </del>  <del> 4.3. </del>  Since a server is only permitted to have a single active issuing key, this implies that only a single ciphersuite is allowed per issuance construction from Kreuter et al.  KLOR20 or the attribute-based VOPRF from Huang et al.  HIJK21.  6.1. Note that any metadata bits of information can be used to further

Replace suggested registry with list of other options. The rationale is that a registry may be sufficient but not necessary. There are other options that might work. I suggest we work with NAME on a draft describing these techniques in more detail. cc NAME
There's currently no text around token expiration. Minimally, we could say that tokens expire when issuer (and verifier) keys rotate. Do we also want to bake in mechanisms for expiration to be cryptographically bound to issued tokens? For example, one might imagine using PMB-like constructions to encode an expiration "epoch" into the metadata bits. The single metadata bit variant would allow two epochs that way. NAME NAME what do you think?
I'm not sure what baking the expiry into the tokens gives that can't be managed by rotating the issuer/verifier keys (or using public metadata (which is effectively the key used to sign))? That way issuers that care about more fine grained token expiration use the key rotation for that and issuers that only care about coarse token expiration use it for other metadata, allowing the protocol to treat both in the same way?
Yeah, I think the only two options are (a) rotate keys or (b) include the expiry information as public metadata (and need not be tied to the key used to sign). I'm not advocating for one or the other. Sure, that's reasonable. We should probably have text on this point. (That's partly why I filed this issue.)
We should also make sure to note that the validity window does narrow the anonymity set.
This LGTM. Agreed that working on a document that tackles these questions specifically would be worthwhile.

The public keys that are active for the server.  <ins> The way that the server publishes and maintains this information impacts the effective privacy of the clients; see privacy for more details.  The fundamental requirement for key management and discovery is that servers must be unable to target specific clients with unique keys without detection.  There are a number of ways in which this might be implemented: </ins>  <ins> Servers use a verifiable, tamper-free registry from which clients discover keys.  Similar to related mechanisms and protocols such as Certificate Transparency RFC6962, this may require external auditors or additional client behavior to ensure the registry state is consistent for all clients. </ins>  <ins> Clients use an anonymity-preserving tool such as Tor to discover keys from multiple network vantage points.  This is done to ensure consistent keys to seemingly different clients. </ins>  <ins> Clients embed server keys into software. </ins>  <ins> Specific mechanisms for key management and discovery are out of scope for this document. 4.1. </ins> Token issuance associates all issued tokens with a particular choice of key.  If a server issues tokens with many keys, then this may harm possess has been issued under. To prevent against this, servers MUST only use one private key for  <ins> issuing tokens at any given time.  Servers MAY use one or more keys </ins> for redemption to allow servers for seamless key rotation.  <ins> Servers may rotate keys as a means of revoking tokens issued under old or otherwise expired keys.  Alternatively, servers may include expiration information as metadata alongside the token; See metadata for more discussion about metadata constraints.  Both techinques are equivalent since they cryptographically bind expiration to individual tokens. </ins>  <ins> Key rotations should be limited in frequency for similar reasons. See parametrization for guidelines on what frequency of key rotations are permitted. 4.2. </ins> Since a server is only permitted to have a single active issuing key, this implies that only a single ciphersuite is allowed per issuance construction from Kreuter et al.  KLOR20 or the attribute-based VOPRF from Huang et al.  HIJK21. <ins> Metadata may also be arbitrarily long or bounded in length.  The amount of permitted metadata may be determined by application or by the underlying cryptographic protocol. </ins> 6.1. Note that any metadata bits of information can be used to further


1. <del> The Privacy Pass protocol as described in draft-davidson-pp-protocol can be integrated with a number of different settings, from server to server communication to browsing the internet. </del>  In this document, we will provide an API to use for integrating Privacy Pass with an HTTP framework.  Providing the format of HTTP 1.1. We use the same definition of server and client that is used in <del> draft-davidson-pp-protocol and draft-davidson-pp-architecture. </del>  We assume that all protocol messages are encoded into raw byte format before being sent.  We use the TLS presentation language RFC8446 to many active commitments exist and how quickly the commitments are being rotated.  Clients SHOULD reject configurations/commitments that violate their requirements for avoiding user segregation.  These <del> considerations are discussed as part of draft-davidson-pp- </del>  architecture. 3.2. "inclusion_proofs" to confirm that the key commitment has been submitted to a trusted registry.  Once the client receives the "ciphersuite" for the server, it should implement all Privacy Pass <del> API functions (as detailed in draft-davidson-pp-protocol) using this ciphersuite. </del>  5. redemption, or the client redeeming the token and passing the result along to the target endpoint.  These two methods are described below.  6.1. <del> Inputs: - "server_id": The server ID to redeem a token against.  - "ciphersuite": The ciphersuite for this token.  - "public_key": The public key associated with this token.  - "redemption_token": A Privacy Pass token.  - "info": Additional data to bind to this token redemption. </del>  Outputs: - "result": The result of the redemption from the server.  The client should call the "Redeem" function with "redemption_token" and additional data of "info" storing the resulting "data" and "tag". 6.2. <del> Inputs: - "server_origin": The server origin to redeem a token for. - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. </del>  When a client wants to redeem tokens for a server, it should first fetch a key commitment from the server via the process described 6.3. <del> Inputs: - "server_origin": The server origin to redeem a token for. - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. </del>  When a client wants to redeem tokens for a server, it should first fetch a key commitment from the server via the process described 7. <del> Security considerations for Privacy Pass are discussed in draft- davidson-pp-architecture. </del>  8. <del> 8.1. </del>  This specification registers a new well-known URI. this trade-off is important in deciding the effective anonymity of each client in the system.  8.3. If there are multiple key registries, or if a key registry colludes

Initial work for fixing .
NAME
As discussed during IETF 110, the architecture document should provide guidance on how redemption contexts can be used and how they impact privacy. This is a bit of the calculus we don't yet have. cc NAME NAME
Yeah, this likely needs to be embedded both into the Architecture draft for the generic concept of a context, and then an actual instantiation of redemption contexts in the HTTP API doc.
Yep should we split out the HTTP work into a separate issue?
Thanks NAME This looks good, I have mostly just a few nits to resolve.

1.  <ins> The Privacy Pass protocol as described in draft-ietf-privacypass- protocol can be integrated with a number of different settings, from server to server communication to browsing the internet. </ins> In this document, we will provide an API to use for integrating Privacy Pass with an HTTP framework.  Providing the format of HTTP 1.1. We use the same definition of server and client that is used in  <ins> draft-ietf-privacypass-protocol and draft-ietf-privacypass- architecture. </ins> We assume that all protocol messages are encoded into raw byte format before being sent.  We use the TLS presentation language RFC8446 to many active commitments exist and how quickly the commitments are being rotated.  Clients SHOULD reject configurations/commitments that violate their requirements for avoiding user segregation.  These  <ins> considerations are discussed as part of draft-ietf-privacypass- </ins> architecture. 3.2. "inclusion_proofs" to confirm that the key commitment has been submitted to a trusted registry.  Once the client receives the "ciphersuite" for the server, it should implement all Privacy Pass  <ins> API functions (as detailed in draft-ietf-privacypass-protocol) using this ciphersuite. </ins> 5. redemption, or the client redeeming the token and passing the result along to the target endpoint.  These two methods are described below. <ins> In the HTTP ecosystem, redemption contexts should generally be keyed by the same privacy boundary used for cookies and other local storage.  Generally this is the top-level origin.  Any redemption context should be built following the principles outlined in draft- ietf-privacypass-architecture and later in privacy. </ins> 6.1.  <ins> Inputs: - "context": The request context to use.  - "server_id": The server ID to redeem a token against.  - "ciphersuite": The ciphersuite for this token.  - "public_key": The public key associated with this token.  - "redemption_token": A Privacy Pass token.  - "info": Additional data to bind to this token redemption. </ins> Outputs: - "result": The result of the redemption from the server. <ins> The client should check whether the "server_id" is present in the "context".  If it isn't and the size of the "context" is beneath the client's limit, it should be added. </ins> The client should call the "Redeem" function with "redemption_token" and additional data of "info" storing the resulting "data" and "tag". 6.2.  <ins> Inputs: - "context": The request context to use.  - "server_origin": The server origin to redeem a token for.  - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. </ins> When a client wants to redeem tokens for a server, it should first fetch a key commitment from the server via the process described 6.3.  <ins> Inputs: - "context": The request context to use.  - "server_origin": The server origin to redeem a token for.  - "target": The target endpoint to send the token to.  - "additional_data": Additional data to bind to this redemption request. </ins> When a client wants to redeem tokens for a server, it should first fetch a key commitment from the server via the process described 7.  <ins> Security considerations for Privacy Pass are discussed in draft-ietf- privacypass-architecture. </ins> 8.  <ins> General privacy considerations for Privacy Pass are discussed in draft-ietf-privacypass-architecture. In order to implement this API with redemption contexts, a client needs to maintain strong privacy boundaries between different redemption contexts to avoid privacy leakage from redemptions across them.  Notably in the web/HTTP world, cross-site tracking and fingerprinting will need to be considered and mitigated in order to maintain these privacy boundaries. 9. 9.1. </ins> This specification registers a new well-known URI. this trade-off is important in deciding the effective anonymity of each client in the system. <ins> 8.2.1.1. Another option to allow a large number of servers in the ecosystem, while preventing the joining of a number of different tokens is for the client to maintain sharded "redemption contexts".  This would allow the client to redeem the tokens it wishes to use in a particular context, while still allowing the client to maintain a large variety of tokens from many servers.  Within a redemption context, the client limits the number of different servers used to a small number to maintain the privacy properties the client requires. As long as each redemption context maintains a strong privacy boundary with each other, the verifier will only be able to learn a number of bits of information up to the limits within that "redemption context". To support this strategy, the client keeps track of a "context" which contains the set of servers that redemptions have been attempted against.  An empty redemption is returned when the limit has been hit: </ins> 8.3. If there are multiple key registries, or if a key registry colludes