Skip to main content

Private Access Tokens
draft-private-access-tokens-00

The information below is for an old version of the document.
Document Type
This is an older version of an Internet-Draft whose latest revision state is "Replaced".
Authors Scott Hendrickson , Jana Iyengar , Tommy Pauly , Steven Valdez , Christopher A. Wood
Last updated 2021-10-25
Replaced by draft-ietf-privacypass-protocol, draft-ietf-privacypass-auth-scheme, draft-ietf-privacypass-rate-limit-tokens
RFC stream (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-private-access-tokens-00
Network Working Group                                     S. Hendrickson
Internet-Draft                                                Google LLC
Intended status: Standards Track                              J. Iyengar
Expires: 28 April 2022                                            Fastly
                                                                T. Pauly
                                                              Apple Inc.
                                                               S. Valdez
                                                              Google LLC
                                                               C.A. Wood
                                                              Cloudflare
                                                         25 October 2021

                         Private Access Tokens
                     draft-private-access-tokens-00

Abstract

   This document defines a protocol for issuing and redeeming privacy-
   preserving access tokens.  These tokens can adhere to an issuance
   policy, allowing a service to limit access according to the policy
   without tracking client identity.

Discussion Venues

   This note is to be removed before publishing as an RFC.

   Source for this draft and an issue tracker can be found at
   https://github.com/tfpauly/privacy-proxy.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 28 April 2022.

Hendrickson, et al.       Expires 28 April 2022                 [Page 1]
Internet-Draft            Private Access Tokens             October 2021

Copyright Notice

   Copyright (c) 2021 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Simplified BSD License text
   as described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Simplified BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  Motivation  . . . . . . . . . . . . . . . . . . . . . . .   4
       1.1.1.  Rate-limited Access . . . . . . . . . . . . . . . . .   4
       1.1.2.  Client Geo-Location . . . . . . . . . . . . . . . . .   5
       1.1.3.  Private Client Authentication . . . . . . . . . . . .   5
     1.2.  Architecture  . . . . . . . . . . . . . . . . . . . . . .   5
     1.3.  Properties and Requirements . . . . . . . . . . . . . . .   7
     1.4.  Client Identity . . . . . . . . . . . . . . . . . . . . .   9
     1.5.  User Interaction  . . . . . . . . . . . . . . . . . . . .  10
   2.  Notation and Terminology  . . . . . . . . . . . . . . . . . .  10
   3.  Configuration . . . . . . . . . . . . . . . . . . . . . . . .  12
   4.  Token Challenge and Redemption Protocol . . . . . . . . . . .  13
     4.1.  Token Challenge . . . . . . . . . . . . . . . . . . . . .  14
     4.2.  Token Redemption  . . . . . . . . . . . . . . . . . . . .  15
   5.  Issuance Protocol . . . . . . . . . . . . . . . . . . . . . .  16
     5.1.  State Requirements  . . . . . . . . . . . . . . . . . . .  17
       5.1.1.  Client State  . . . . . . . . . . . . . . . . . . . .  17
       5.1.2.  Mediator State  . . . . . . . . . . . . . . . . . . .  18
       5.1.3.  Issuer State  . . . . . . . . . . . . . . . . . . . .  19
     5.2.  Issuance HTTP Headers . . . . . . . . . . . . . . . . . .  19
     5.3.  Client-to-Mediator Request  . . . . . . . . . . . . . . .  20
     5.4.  Mediator-to-Issuer Request  . . . . . . . . . . . . . . .  23
     5.5.  Issuer-to-Mediator Response . . . . . . . . . . . . . . .  24
     5.6.  Mediator-to-Client Response . . . . . . . . . . . . . . .  25
     5.7.  Encrypting Origin Names . . . . . . . . . . . . . . . . .  26
     5.8.  Non-Interactive Schnorr Proof of Knowledge  . . . . . . .  27
   6.  Instantiating Uses Cases  . . . . . . . . . . . . . . . . . .  28
     6.1.  Rate-limited Access . . . . . . . . . . . . . . . . . . .  28
     6.2.  Client Geo-Location . . . . . . . . . . . . . . . . . . .  29
     6.3.  Private Client Authentication . . . . . . . . . . . . . .  29
   7.  Security Considerations . . . . . . . . . . . . . . . . . . .  29
     7.1.  Client Identity . . . . . . . . . . . . . . . . . . . . .  30

Hendrickson, et al.       Expires 28 April 2022                 [Page 2]
Internet-Draft            Private Access Tokens             October 2021

     7.2.  Denial of Service . . . . . . . . . . . . . . . . . . . .  30
     7.3.  Channel Security  . . . . . . . . . . . . . . . . . . . .  30
   8.  Privacy Considerations  . . . . . . . . . . . . . . . . . . .  30
     8.1.  Client Token State and Origin Tracking  . . . . . . . . .  30
     8.2.  Origin Verification . . . . . . . . . . . . . . . . . . .  31
     8.3.  Client Identification with Unique Keys  . . . . . . . . .  31
     8.4.  Collusion Among Different Entities  . . . . . . . . . . .  32
   9.  Deployment Considerations . . . . . . . . . . . . . . . . . .  32
     9.1.  Origin Key Rollout  . . . . . . . . . . . . . . . . . . .  32
   10. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  32
     10.1.  Authentication Scheme  . . . . . . . . . . . . . . . . .  32
     10.2.  HTTP Headers . . . . . . . . . . . . . . . . . . . . . .  33
     10.3.  Media Types  . . . . . . . . . . . . . . . . . . . . . .  33
       10.3.1.  "message/access-token-request" media type  . . . . .  33
       10.3.2.  "message/access-token-response" media type . . . . .  34
   11. References  . . . . . . . . . . . . . . . . . . . . . . . . .  35
     11.1.  Normative References . . . . . . . . . . . . . . . . . .  35
     11.2.  Informative References . . . . . . . . . . . . . . . . .  36
   Appendix A.  Related Work: Privacy Pass . . . . . . . . . . . . .  36
   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  37

1.  Introduction

   Servers commonly use passive and persistent identifiers associated
   with clients, such as IP addresses or device identifiers, for
   enforcing access and usage policies.  For example, a server might
   limit the amount of content an IP address can access over a given
   time period (referred to as a "metered paywall"), or a server might
   rate-limit access from an IP address to prevent fraud and abuse.
   Servers also commonly use the client's IP address as a strong
   indicator of the client's geographic location to limit access to
   services or content to a specific geographic area (referred to as
   "geofencing").

   However, passive and persistent client identifiers can be used by any
   entity that has access to it without the client's express consent.  A
   server can use a client's IP address or its device identifier to
   track client activity.  A client's IP address, and therefore its
   location, is visible to all entities on the path between the client
   and the server.  These entities can trivially track a client, its
   location, and servers that the client visits.

   A client that wishes to keep its IP address private can hide its IP
   address using a proxy service or a VPN.  However, doing so severely
   limits the client's ability to access services and content, since
   servers might not be able to enforce their policies without a stable
   and unique client identifier.

Hendrickson, et al.       Expires 28 April 2022                 [Page 3]
Internet-Draft            Private Access Tokens             October 2021

   This document describes an architecture for Private Access Tokens
   (PATs), using RSA Blind Signatures as defined in [BLINDSIG], as an
   explicit replacement for these passive client identifiers.  These
   tokens are privately issued to clients upon request and then redeemed
   by servers in such a way that the issuance and redemption events for
   a given token are unlinkable.

   At first glance, using PATs in lieu of passive identifiers for policy
   enforcement suggests that some entity needs to know both the client's
   identity and the server's policy, and such an entity would be
   trivially able to track a client and its activities.  However, with
   appropriate mediation and separation between the parties involved in
   the issuance and the redemption protocols, it is possible to
   eliminate this information concentration without any functional
   regressions.  This document describes such a protocol.

   The relationship of this work to Privacy Pass
   ([I-D.ietf-privacypass-protocol]) is discussed in Appendix A.

1.1.  Motivation

   This section describes classes of use cases where an origin would
   traditionally use a stable and unique client identifier for enforcing
   attribute-based policy.  Hiding these identifiers from origins would
   therefore require an alternative for origins to continue enforcing
   their policies.  Using the Privacy Address Token architecture for
   addressing these use cases is described in Section 6.

1.1.1.  Rate-limited Access

   An origin provides rate-limited access to content to a client over a
   fixed period of time.  The origin does not need to know the client's
   identity, but needs to know that a requesting client has not exceeded
   the maximum rate set by the origin.

   One example of this use case is a metered paywall, where an origin
   limits the number of page requests to each unique user over a period
   of time before the user is required to pay for access.  The origin
   typically resets this state periodically, say, once per month.  For
   example, an origin may serve ten (major content) requests in a month
   before a paywall is enacted.  Origins may want to differentiate quick
   refreshes from distinct accesses.

Hendrickson, et al.       Expires 28 April 2022                 [Page 4]
Internet-Draft            Private Access Tokens             October 2021

   Another example of this use case is rate-limiting page accesses to a
   client to help prevent fraud.  Operations that are sensitive to
   fraud, such as account creation on a website, often employ rate-
   limiting as a defense in depth strategy.  Captchas or additional
   verification can be required by these pages when a client exceeds a
   set rate-limit.

   Origins routinely use client IP addresses for this purpose.

1.1.2.  Client Geo-Location

   An origin provides access to or customizes content based on the geo-
   location of the client.  The origin does not need to know the
   client's identity, but needs to know the geo-location, with some
   level of accuracy, for providing service.

   A specific example of this use case is "geo-fencing", where an origin
   restricts the available content it can serve based on the client's
   geographical region.

   Origins almost exclusively use client IP addresses for this purpose.

1.1.3.  Private Client Authentication

   An origin provides access to content for clients that have been
   authorized by a delegated or known mediator.  The origin does not
   need to know the client's identity.

   A specific example of this use case is a federated service that
   authorizes users for access to specific sites, such as a federated
   news service or a federated video streaming service.  The origin
   trusts the federator to authorize users and needs proof that the
   federator authorized a particular user, but it does not need the
   user's identity to provide access to content.

   Origins could currently redirect clients to a federator for
   authentication, but origins could then track the client's federator
   user ID or the client's IP address across accesses.

1.2.  Architecture

   At a high level, the PAT architecture seeks to solve the following
   problem: in the absence of a stable Client identifier, an Origin
   needs to verify the identity of a connecting Client and enforce
   access policies for the incoming Client.  To accomplish this, the PAT
   architecture employs four functional components:

Hendrickson, et al.       Expires 28 April 2022                 [Page 5]
Internet-Draft            Private Access Tokens             October 2021

   1.  Client: requests a PAT from an Issuer and presents it to a Origin
       for access to the Origin's service.

   2.  Mediator: authenticates a Client, using information such as its
       IP address, an account name, or a device identifier.  Anonymizes
       a Client to an Issuer and relays information between an
       anonymized Client and an Issuer.

   3.  Issuer: issues PATs to an anonymized Client on behalf of an
       Origin.  Anonymizes an Origin to a Mediator and enforces the
       Origin's policy.

   4.  Origin: directs a Client to an Issuer with a challenge and
       enables access to content or services to the Client upon
       verification of any PAT sent in response by the Client.

   In the PAT architecture, these four components interact as follows.

   An Origin designates a trusted Issuer to issue tokens for it.  The
   Origin then redirects any incoming Clients to the Issuer for policy
   enforcement, expecting the Client to return with a proof from the
   Issuer that the Origin's policy has been enforced for this Client.

   The Client employs a trusted Mediator through which it communicates
   with the Issuer for this proof.  The Mediator performs three
   important functions:

   *  authenticate and associate the Client with a stable identifier;

   *  maintain issuance state for the Client and relay it to the Issuer;
      and

   *  anonymize the Client and mediate communication between the Client
      and the Issuer.

   When a Mediator-anonymized Client requests a token from an Issuer,
   the Issuer enforces the Origin's policies based on the received
   Client issuance state and Origin policy.  Issuers know the Origin's
   policies and enforce them on behalf of the Origin.  An example policy
   is: "Limit 10 accesses per Client".  More examples and their use
   cases are discussed in Section 6.  The Issuer does not learn the
   Client's true identity.

Hendrickson, et al.       Expires 28 April 2022                 [Page 6]
Internet-Draft            Private Access Tokens             October 2021

   Finally, the Origin provides access to content or services to a
   Client upon verifying a PAT presented by the Client.  Verification of
   this token serves as proof that the Client meets the Origin's
   policies as enforced by the delegated Issuer with the help of a
   Mediator.  The Origin can then provide any services or content gated
   behind these policies to the Client.

   Figure 1 shows the components of the PAT architecture described in
   this document.  Protocol details follow in Section 4 and Section 5.

    Client        Mediator          Issuer          Origin

       <---------------------------------------- Challenge \
                                                           |
   +--------------------------------------------\          |
   | TokenRequest --->                          |          |
   |             (validate)                     |          |
   |             (attach state)                 |          |
   |                    TokenRequest --->       |          |    PAT
   |                                 (validate) |   PAT    | Challenge/
   |                                 (evaluate) | Issuance |  Response
   |                    <--- TokenResponse      |   Flow   |   Flow
   |             (evaluate)                     |          |
   |             (update state)                 |          |
   |   <--- TokenResponse                       |          |
   ---------------------------------------------/          |
                                                           |
        Response -------------------------------------- >  /

                   Figure 1: PAT Architectural Components

1.3.  Properties and Requirements

   In this architecture, the Mediator, Issuer, and Origin each have
   partial knowledge of the Client's identity and actions, and each
   entity only knows enough to serve its function (see Section 2 for
   more about the pieces of information):

   *  The Mediator knows the Client's identity and learns the Client's
      public key (CLIENT_KEY), the Issuer being targeted (ISSUER_NAME),
      the period of time for which the Issuer's policy is valid
      (ISSUER_POLICY_WINDOW), and the number of tokens issued to a given
      Client for the claimed Origin in the given policy window.  The
      Mediator does not know the identity of the Origin the Client is
      trying to access (ORIGIN_ID), but knows a Client-anonymized
      identifier for it (ANON_ORIGIN_ID).

Hendrickson, et al.       Expires 28 April 2022                 [Page 7]
Internet-Draft            Private Access Tokens             October 2021

   *  The Issuer knows the Origin's secret (ORIGIN_SECRET) and policy
      about client access, and learns the Origin's identity
      (ORIGIN_NAME) and the number of previous tokens issued to the
      Client (as communicated by the Mediator) during issuance.  The
      Issuer does not learn the Client's identity.

   *  The Origin knows the Issuer to which it will delegate an incoming
      Client (ISSUER_NAME), and can verify that any tokens presented by
      the Client were signed by the Issuer.  The Origin does not learn
      which Mediator was used by a Client for issuance.

   Since an Issuer enforces policies on behalf of Origins, a Client is
   required to reveal the Origin's identity to the delegated Issuer.  It
   is a requirement of this architecture that the Mediator not learn the
   Origin's identity so that, despite knowing the Client's identity, a
   Mediator cannot track and concentrate information about Client
   activity.

   An Issuer expects a Mediator to verify its Clients' identities
   correctly, but an Issuer cannot confirm a Mediator's efficacy or the
   Mediator-Client relationship directly without learning the Client's
   identity.  Similarly, an Origin does not know the Mediator's
   identity, but ultimately relies on the Mediator to correctly verify
   or authenticate a Client for the Origin's policies to be correctly
   enforced.  An Issuer therefore chooses to issue tokens to only known
   and reputable Mediators; the Issuer can employ its own methods to
   determine the reputation of a Mediator.

   A Mediator is expected to employ a stable Client identifier, such as
   an IP address, a device identifier, or an account at the Mediator,
   that can serve as a reasonable proxy for a user with some creation
   and maintenance cost on the user.

   For the Issuance protocol, a Client is expected to create and
   maintain stable and explicit secrets for time periods that are on the
   scale of Issuer policy windows.  Changing these secrets arbitrarily
   during a policy window can result in token issuance failure for the
   rest of the policy window; see Section 5.1.1 for more details.  A
   Client can use a service offered by its Mediator or a third-party to
   store these secrets, but it is a requirement of the PAT architecture
   that the Mediator not be able to learn these secrets.

   The privacy guarantees of the PAT architecture, specifically those
   around separating the identity of the Client from the names of the
   Origins that it accesses, are based on the expectation that there is
   not collusion between the entities that know about Client identity
   and those that know about Origin identity.  Clients choose and share
   information with Mediators, and Origins choose and share policy with

Hendrickson, et al.       Expires 28 April 2022                 [Page 8]
Internet-Draft            Private Access Tokens             October 2021

   Issuers; however, the Mediator is generally expected to not be
   colluding with Issuers or Origins.  If this occurs, it can become
   possible for a Mediator to learn or infer which Origins a Client is
   accessing, or for an Origin to learn or infer the Client identity.
   For further discussion, see Section 8.4.

1.4.  Client Identity

   The PAT architecture does not enforce strong constraints around the
   definition of a Client identity and allows it to be defined entirely
   by a Mediator.  If a user can create an arbitrary number of Client
   identities that are accepted by one or more Mediators, a malicious
   user can easily abuse the system to defeat the Issuer's ability to
   enforce per-Client policies.

   These multiple identities could be fake or true identities.

   A Mediator alone is responsible for detecting and weeding out fake
   Client identities in the PAT architecture.  An Issuer relies on a
   Mediator's reputation; as explained in Section 1.3, the correctness
   of the architecture hinges on Issuers issuing tokens to only known
   and reputable Mediators.

   Users have multiple true identities on the Internet however, and as a
   result, it seems possible for a user to abuse the system without
   having to create fake identities.  For instance, a user could use
   multiple Mediators, authenticating with each one using a different
   true identity.

   The PAT architecture offers no panacea against this potential abuse.
   We note however that the usages of PATs will cause the ecosystem to
   evolve and offer practical mitigations, such as:

   *  An Issuer can learn the properties of a Mediator - specifically,
      which stable Client identifier is authenticated by the Mediator -
      to determine whether the Mediator is acceptable for an Origin.

   *  An Origin can choose an Issuer based on the types of Mediators
      accepted by the Issuer, or the Origin can communicate its
      constraints to the designated Issuer.

   *  An Origin can direct a user to a specific Issuer based on client
      properties that are visible.  For instance, properties that are
      observable in the HTTP User Agent string.

   *  The number of true Mediator-authenticated identities for a user is
      expected to be small, and therefore likely to be small enough to
      not matter for certain use cases.  For instance, when PATs are

Hendrickson, et al.       Expires 28 April 2022                 [Page 9]
Internet-Draft            Private Access Tokens             October 2021

      used to prevent fraud by rate-limiting Clients (as described in
      Section 1.1.1), an Origin might be tolerant of the potential
      amplification caused by an attacking user's access to multiple
      true identities with Issuer-trusted Mediators.

1.5.  User Interaction

   When used in contexts like websites, origin servers that challenge
   clients for Private Access Tokens need to consider how to optimize
   their interaction model to ensure a good user experience.

   Private Access Tokens are designed to be used without explicit user
   involvement.  Since tokens are only valid for a single origin and in
   response to a specific challenge, there is no need for a user to
   manage a limited pool of tokens across origins.  The information that
   is available to an origin upon token redemption is limited to the
   fact that this is a client that passed a Mediator's checks and has
   not exceeded the per-origin limit defined by an Issuer.  Generally,
   if a user is willing to use Private Access Tokens with a particular
   origin (or all origins), there is no need for per-challenge user
   interaction.  Note that the Issuance flow may separately involve user
   interaction if the Mediator needs to authenticate the Client.

   Since tokens are issued using a separate connection through a
   Mediator to an Issuer, the process of issuance can add user-
   perceivable latency.  Origins SHOULD NOT block useful work on token
   authentication.  Instead, token authentication can be used in similar
   ways to CAPTCHA validation today, but without the need for user
   interaction.  If issuance is taking a long time, a website could show
   an indicator that it is waiting, or fall back to another method of
   user validation.

   If an origin is requesting an unexpected number of tokens, such as
   requesting token authentication more than once for a single website
   load, it can indicate that the server is not functioning correctly,
   or is trying to attack or overload the client or issuance servers.
   In such cases, the client SHOULD ignore redundant token challengers,
   or else alert the user.

2.  Notation and Terminology

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

Hendrickson, et al.       Expires 28 April 2022                [Page 10]
Internet-Draft            Private Access Tokens             October 2021

   Unless said otherwise, this document encodes protocol messages in TLS
   notation from [TLS13], Section 3.

   This draft includes pseudocode that uses the functions and
   conventions defined in [HPKE].

   Encoding an integer to a sequence of bytes in network byte order is
   described using the function "encode(n, v)", where "n" is the number
   of bytes and "v" is the integer value.  The function "len()" returns
   the length of a sequence of bytes.

   The following terms are defined to refer to the different pieces of
   information passed through the system:

   ISSUER_NAME:  The Issuer Name identifies which Issuer is able to
      provide tokens for a Client.  The Client sends the Issuer Name to
      the Mediator so the Mediator know where to forward requests.  Each
      Issuer is associated with a specific ISSUER_POLICY_WINDOW.

   ISSUER_POLICY_WINDOW:  The period over which an Issuer will track
      access policy, defined in terms of seconds and represented as a
      uint64.  The state that the Mediator keeps for a Client is
      specific to a policy window.  The effective policy window for a
      specific Client starts when the Client first sends a request
      associated with an Issuer.

   ORIGIN_TOKEN_KEY:  The public key used when generating and verifying
      Private Access Tokens.  Each Origin Token Key is unique to a
      single Origin.  The corresponding private key is held by the
      Issuer.

   ISSUER_KEY:  The public key used to encrypt values such as
      ORIGIN_NAME in requests from Clients to the Issuer, so that
      Mediators cannot learn the ORIGIN_NAME value.  Each ISSUER_KEY is
      used across all requests on the Issuer, for different Origins.

   ORIGIN_NAME:  The name of the Origin that requests and verifies
      Private Access Tokens.

   ANON_ORIGIN_ID:  An identifier that is generated by the Client and
      marked on requests to the Mediator, which represents a specific
      Origin anonymously.  The Client generates a stable ANON_ORIGIN_ID
      for each ORIGIN_NAME, to allow the Mediator to count token access
      without learning the ORIGIN_NAME.

   CLIENT_KEY:  A public key chosen by the Client and shared only with
      the Mediator.

Hendrickson, et al.       Expires 28 April 2022                [Page 11]
Internet-Draft            Private Access Tokens             October 2021

   CLIENT_SECRET:  The secret key used by the Client during token
      issuance, whose public key (CLIENT_KEY) is shared with the
      Mediator.

   ORIGIN_SECRET:  The secret key used by the Issuer during token
      issuance, whose public key is not shared with anyone.

   ANON_ISSUER_ORIGIN_ID:  An identifier that is generated by Issuer
      based on an ORIGIN_SECRET that is per-Client and per-Origin.  See
      Section 5.6 for details of derivation.

3.  Configuration

   Issuers MUST provide three parameters for configuration:

   1.  ISSUER_KEY: a KeyConfig as defined in [OHTTP] to use when
       encrypting the ORIGIN_NAME in issuance requests.  This parameter
       uses resource media type "application/ohttp-keys".

   2.  ISSUER_POLICY_WINDOW: a uint64 of seconds as defined in
       Section 2.

   3.  ISSUER_REQUEST_URI: a Private Access Token request URL for
       generating access tokens.  For example, an Issuer URL might be
       https://issuer.example.net/access-token-request.  This parameter
       uses resource media type "text/plain".

   These parameters can be obtained from an Issuer via a directory
   object, which is a JSON object whose field names and values are raw
   values and URLs for the parameters.

    +======================+==========================================+
    | Field Name           | Value                                    |
    +======================+==========================================+
    | issuer-key           | ISSUER_KEY resource URL as a JSON string |
    +----------------------+------------------------------------------+
    | issuer-policy-window | ISSUER_POLICY_WINDOW as a JSON number    |
    +----------------------+------------------------------------------+
    | issuer-request-uri   | ISSUER_REQUEST_URI resource URL as a     |
    |                      | JSON string                              |
    +----------------------+------------------------------------------+

                                  Table 1

   As an example, the Issuer's JSON directory could look like:

Hendrickson, et al.       Expires 28 April 2022                [Page 12]
Internet-Draft            Private Access Tokens             October 2021

 {
    "issuer-key": "https://issuer.example.net/key",
    "issuer-token-window": 86400,
    "issuer-request-uri": "https://issuer.example.net/access-token-request"
 }
 ~~~

Mediators MUST provide a single parameter for configuration, MEDIATOR_REQUEST_URI,
wich is Private Access Token request URL for proxying protocol messages to Issuers.
For example, a Mediator URL might be https://mediator.example.net/relay-access-token-request.
Similar to Issuers, Mediators make this parameter available by a directory object
with the following contents:

| Field Name           | Value                             |
|:---------------------|:----------------------------------|
| mediator-request-uri | MEDIATOR_REQUEST_URI resource URL |

As an example, the Mediator's JSON dictionary could look like:

   { "mediator-request-uri": "https://mediator.example.net/relay-access-
   token-request." } ~~~

   Issuer and Mediator directory resources have the media type
   "application/json" and are located at the well-known location /.well-
   known/private-access-tokens-directory.

4.  Token Challenge and Redemption Protocol

   This section describes the interactive protocol for the token
   challenge and redemption flow between a Client and an Origin.

   Token redemption is performed using HTTP Authentication ([RFC7235]),
   with the scheme "PrivateAccessToken".  Origins challenge Clients to
   present a unique, single-use token from a specific Issuer.  Once a
   Client has received a token from that Issuer, it presents the token
   to the Origin.

   Token redemption only requires Origins to verify token signatures
   computed using the Blind Signature protocol from [BLINDSIG].  Origins
   are not required to implement the complete Blind Signature protocol.
   (In contrast, token issuance requires Clients and Issuers to
   implement the Blind Signature protocol, as described in Section 5.)

Hendrickson, et al.       Expires 28 April 2022                [Page 13]
Internet-Draft            Private Access Tokens             October 2021

4.1.  Token Challenge

   Origins send a token challenge to Clients in an "WWW-Authenticate"
   header with the "PrivateAccessToken" scheme.  This challenge includes
   a TokenChallenge message, along with information about what keys to
   use when requesting a token from the Issuer.

   The TokenChallenge message has the following structure:

   struct {
       uint8_t version;
       opaque origin_name<1..2^16-1>;
       opaque issuer_name<1..2^16-1>;
       opaque redemption_nonce[32];
   } TokenChallenge;

   The structure fields are defined as follows:

   *  "version" is a 1-octet integer.  This document defines version 1.

   *  "origin_name" is a string containing the name of the Origin
      (ORIGIN_NAME).

   *  "issuer_name" is a string containing the name of the Issuer
      (ISSUER_NAME).

   *  "redemption_nonce" is a fresh 32-byte nonce generated for each
      redemption request.

   When used in an authentication challenge, the "PrivateAccessToken"
   scheme uses the following attributes:

   *  "challenge", which contains a base64url-encoded [RFC4648]
      TokenChallenge value.  This MUST be unique for every 401 HTTP
      response to prevent replay attacks.

   *  "token-key", which contains a base64url encoding of the
      SubjectPublicKeyInfo object for use with the RSA Blind Signature
      protocol (ORIGIN_TOKEN_KEY).

   *  "issuer-key", which contains a base64url encoding of a KeyConfig
      as defined in [OHTTP] to use when encrypting the ORIGIN_NAME in
      issuance requests (ISSUER_KEY).

   *  "max-age", an optional attribute that consists of the number of
      seconds for which the challenge will be accepted by the Origin.

   Origins MAY also include the standard "realm" attribute, if desired.

Hendrickson, et al.       Expires 28 April 2022                [Page 14]
Internet-Draft            Private Access Tokens             October 2021

   As an example, the WWW-Authenticate header could look like this:

WWW-Authenticate: PrivateAccessToken challenge=abc..., token-key=123...,
issuer-key=456...

   Upon receipt of this challenge, a Client uses the message and keys in
   the Issuance protocol (see Section 5).  If the TokenChallenge has a
   version field the Client does not recognize or support, it MUST NOT
   parse or respond to the challenge.  This document defines version 1,
   which indicates use of private tokens based on RSA Blind Signatures
   [BLINDSIG], and determines the rest of the structure contents.

   Note that it is possible for the WWW-Authenticate header to include
   multiple challenges, in order to allow the Client to fetch a batch of
   multiple tokens for future use.

   For example, the WWW-Authenticate header could look like this:

WWW-Authenticate: PrivateAccessToken challenge=abc..., token-key=123...,
issuer-key=456..., PrivateAccessToken challenge=def..., token-key=234...,
issuer-key=567...

4.2.  Token Redemption

   The output of the issuance protocol is a token that corresponds to
   the Origin's challenge (see Section 4.1).  A token is a structure
   that begins with a single byte that indicates a version, which MUST
   match the version in the TokenChallenge structure.

   struct {
       uint8_t version;
       uint8_t token_key_id[32];
       uint8_t message[32];
       uint8_t signature[Nk];
   } Token;

   The structure fields are defined as follows:

   *  "version" is a 1-octet integer.  This document defines version 1.

   *  "token_key_id" is a collision-resistant hash that identifies the
      ORIGIN_TOKEN_KEY used to produce the signature.  This is generated
      as SHA256(public_key), where public_key is a DER-encoded
      SubjectPublicKeyInfo object carrying the public key.

   *  "message" is a 32-octet message containing the hash of the
      original TokenChallenge, SHA256(TokenChallenge).  This message is
      signed by the signature,

Hendrickson, et al.       Expires 28 April 2022                [Page 15]
Internet-Draft            Private Access Tokens             October 2021

   *  "signature" is a Nk-octet RSA Blind Signature that covers the
      message.  For version 1, Nk is indicated by size of the Token
      structure and may be 256, 384, or 512.  These correspond to RSA
      2048, 3072, and 4096 bit keys.  Clients implementing version 1
      MUST support signature sizes with Nk of 512 and 256.

   When used for client authorization, the "PrivateAccessToken"
   authentication scheme defines one parameter, "token", which contains
   the base64url-encoded Token struct.  All unknown or unsupported
   parameters to "PrivateAccessToken" authentication credentials MUST be
   ignored.

   Clients present this Token structure to Origins in a new HTTP request
   using the Authorization header as follows:

   Authorization: PrivateAccessToken token=abc...

   Origins verify the token signature using the corresponding policy
   verification key from the Issuer, and validate that the message
   matches the hash of a TokenChallenge it previously issued and is
   still valid, SHA256(TokenChallenge), and that the version of the
   Token matches the version in the TokenChallenge.  The TokenChallenge
   MAY be bound to a specific HTTP session with Client, but Origins can
   also accept tokens for valid challenges in new sessions.

   If a Client's issuance request fails with a 401 error, as described
   in Section 5.4, the Client MUST react to the challenge as if it could
   not produce a valid Authorization response.

5.  Issuance Protocol

   This section describes the Issuance protocol for a Client to request
   and receive a token from an Issuer.  Token issuance involves a
   Client, Mediator, and Issuer, with the following steps:

   1.  The Client sends a token request to the Mediator, encrypted using
       an Issuer-specific key

   2.  The Mediator validates the request and proxies the request to the
       Issuer

   3.  The Issuer decrypts the request and sends a response back to the
       Mediator

   4.  The Mediator verifies the response and proxies the response to
       the Client

Hendrickson, et al.       Expires 28 April 2022                [Page 16]
Internet-Draft            Private Access Tokens             October 2021

   The Issuance protocol has a number of underlying cryptographic
   dependencies for operation:

   *  [HPKE], for encrypting information in transit between Client and
      Issuer across the Mediator.

   *  RSA Blind Signatures [BLINDSIG], for issuing and constructing
      Tokens as described in Section 4.2.

   *  Prime Order Groups (POGs), for computing stable mappings between
      (Client, Origin) pairs.  This document uses notation described in
      [VOPRF], Section 2.1, and, in particular, the functions
      RandomScalar(), Generator(), SerializeScalar(),
      SerializeElement(), and HashToScalar().

   *  Non-Interactive proof-of-knowledge (POK), as described in
      Section 5.8, for verifying correctness of Client requests.

   Clients and Issuers are required to implement all of these
   dependencies, whereas Mediators are required to implement POG and POK
   support.

5.1.  State Requirements

   The Issuance protocol requires each participating endpoint to
   maintain some necessary state, as described in this section.

5.1.1.  Client State

   A Client is required to have the following information, derived from
   a given TokenChallenge:

   *  Origin name (ORIGIN_NAME), a URI referring to the Origin
      [RFC6454].  This is the value of TokenChallenge.origin_name.

   *  Origin token public key (ORIGIN_TOKEN_KEY), a blind signature
      public key corresponding to the Origin identified by
      TokenChallenge.origin_name.

   *  Issuer public key (ISSUER_KEY), a public key used to encrypt
      requests corresponding to the Issuer identified by
      TokenChallenge.issuer_name.

   Clients maintain a stable CLIENT_ID that they use for all
   communication with a specific Mediator.  CLIENT_ID is a public key,
   where the corresponding private key CLIENT_SECRET is known only to
   the client.

Hendrickson, et al.       Expires 28 April 2022                [Page 17]
Internet-Draft            Private Access Tokens             October 2021

   If the client loses this (CLIENT_ID, CLIENT_SECRET), they may
   generate a new tuple.  The mediator will enforce if a client is
   allowed to use this new CLIENT_ID.  See #mediator-state for details
   on this enforcement.

   Clients also need to be able to generate an ANON_ORIGIN_ID value that
   corresponds to the ORIGIN_NAME, to send in requests to the Mediator.

   ANON_ORIGIN_ID MUST be a stable and unpredictable 32-byte value
   computed by the Client.  Clients MUST NOT change this value across
   token requests for the same ORIGIN_NAME.  Doing so will result in
   token issuance failure (specifically, when a Mediator rejects a
   request upon detecting two ANON_ORIGIN_ID values that map to the same
   Origin).

   One possible mechanism for implementing this identifier is for the
   Client to store a mapping between the ORIGIN_NAME and a randomly
   generated ANON_ORIGIN_ID for future requests.  Alternatively, the
   Client can compute a PRF keyed by a per-client secret (CLIENT_SECRET)
   over the ORIGIN_NAME, e.g., ANON_ORIGIN_ID =
   HKDF(secret=CLIENT_SECRET, salt="", info=ORIGIN_NAME).

5.1.2.  Mediator State

   A Mediator is required to maintain state for every authenticated
   Client.  The mechanism of identifying a Client is specific to each
   Mediator, and is not defined in this document.  As examples, the
   Mediator could use device-specific certificates or account
   authentication to identify a Client.

   Mediators must enforce that Clients don't change their CLIENT_ID
   frequently, to ensure Clients can't regularily evade the per-client
   policy as seen by the issuer.  Mediators MUST NOT allow Clients to
   change their CLIENT_ID more than once within a policy window, or in
   the subsequent policy window after a previous CLIENT_ID change.
   Alternative schemes where the mediator stores the encrypted
   (CLIENT_ID, CLIENT_SECRET) tuple on behalf of the client are possble
   but not described here.

   Mediators are expected to know the ISSUER_POLICY_WINDOW for any
   ISSUER_NAME to which they allow access.  This information can be
   retrieved using the URIs defined in Section 3.

   For each Client-Issuer pair, a Mediator maintains a policy window
   start and end time for each Issuer from which a Client requests a
   token.

Hendrickson, et al.       Expires 28 April 2022                [Page 18]
Internet-Draft            Private Access Tokens             October 2021

   For each tuple of (CLIENT_ID, ANON_ORIGIN_ID, policy window), the
   Mediator maintains the following state:

   *  A counter of successful tokens issued

   *  Whether or not a previous request was rejected by the Issuer

   *  The last received ANON_ISSUER_ORIGIN_ID value for this
      ANON_ORIGIN_ID, if any

5.1.3.  Issuer State

   Issuers maintain a stable ORIGIN_SECRET that they use in calculating
   values returned to the Mediator for each origin.  If this value
   changes, it will open up a possibility for Clients to request extra
   tokens for an Origin without being limited, within a policy window.

   Issuers are expected to have the private key that corresponds to
   ISSUER_KEY, which allows them to decrypt the ORIGIN_NAME values in
   requests.

   Issuers also need to know the set of valid ORIGIN_TOKEN_KEY public
   keys and corresponding private key, for each ORIGIN_NAME that is
   served by the Issuer.  Origins SHOULD update their view of the
   ORIGIN_TOKEN_KEY regularly to ensure that Client requests do not fail
   after ORIGIN_TOKEN_KEY rotation.

5.2.  Issuance HTTP Headers

   The Issuance protocol defines four new HTTP headers that are used in
   requests and responses between Clients, Mediators, and Issuers (see
   Section 10.2).

   The "Sec-Token-Origin" is an Item Structured Header [RFC8941].  Its
   value MUST be a Byte Sequence.  This header is sent both on Client-
   to-Mediator requests (Section 5.3) and on Issuer-to-Mediator
   responses (Section 5.5).  Its ABNF is:

       Sec-Token-Origin = sf-binary

   The "Sec-Token-Client" is an Item Structured Header [RFC8941].  Its
   value MUST be a Byte Sequence.  This header is sent on Client-to-
   Mediator requests (Section 5.3), and contains the bytes of
   CLIENT_KEY.  Its ABNF is:

       Sec-Token-Client = sf-binary

Hendrickson, et al.       Expires 28 April 2022                [Page 19]
Internet-Draft            Private Access Tokens             October 2021

   The "Sec-Token-Nonce" is an Item Structured Header [RFC8941].  Its
   value MUST be a Byte Sequence.  This header is sent on Client-to-
   Mediator requests (Section 5.3), and contains a per-request nonce
   value.  Its ABNF is:

       Sec-Token-Nonce = sf-binary

   The "Sec-Token-Count" is an Item Structured Header [RFC8941].  Its
   value MUST be an Integer.  This header is sent on Mediator-to-Issuer
   requests (Section 5.3), and contains the number of times a Client has
   previously received a token for an Origin.  Its ABNF is:

       Sec-Token-Count = sf-integer

5.3.  Client-to-Mediator Request

   The Client and Mediator MUST use a secure and Mediator-authenticated
   HTTPS connection.  They MAY use mutual authentication or mechanisms
   such as TLS certificate pinning, to mitigate the risk of channel
   compromise; see Section 7 for additional about this channel.

   Issuance begins by Clients hashing the TokenChallenge to produce a
   token input as message = SHA256(challenge), and then blinding message
   as follows:

   blinded_req, blind_inv = rsabssa_blind(ORIGIN_TOKEN_KEY, message)

   The Client MUST use a randomized variant of RSABSSA in producing this
   signature with a salt length of at least 32 bytes.

   The Client uses CLIENT_SECRET to generate proof of its request.

   blind = RandomScalar()
   blind_key = blind * CLIENT_SECRET
   blind_generator = blind * Generator()
   key_proof = SchnorrProof(CLIENT_SECRET, blind_key, blind_generator)

   The Client then transforms this proof into "mapping_nonce",
   "mapping_key", "mapping_generator", and "mapping_proof".

   mapping_nonce = SerializeScalar(blind)
   mapping_key = SerializeElement(blind_key)
   mapping_generator = SerializeElement(blind_generator)
   mapping_proof = SerializeProof(key_proof)

   The Client then constructs a Private Access Token request using
   mapping_key, mapping_generator, mapping_proof, blinded_req, and
   origin information.

Hendrickson, et al.       Expires 28 April 2022                [Page 20]
Internet-Draft            Private Access Tokens             October 2021

   struct {
      uint8_t version;
      uint8_t mapping_generator[Ne];
      uint8_t mapping_key[Ne];
      uint8_t mapping_proof[Np];
      uint8_t token_key_id;
      uint8_t blinded_req[Nk];
      uint8_t name_key_id[32];
      uint8_t encrypted_origin_name<1..2^16-1>;
   } AccessTokenRequest;

   The structure fields are defined as follows:

   *  "version" is a 1-octet integer, which matches the version in the
      TokenChallenge.  This document defines version 1.

   *  "mapping_generator", "mapping_key", and "mapping_proof" are
      computed as described above.

   *  "token_key_id" is the least significant byte of the
      ORIGIN_TOKEN_KEY key ID, which is generated as SHA256(public_key),
      where public_key is a DER-encoded SubjectPublicKeyInfo object
      carrying ORIGIN_TOKEN_KEY.

   *  "blinded_req" is the Nk-octet request defined above.

   *  "name_key_id" is a collision-resistant hash that identifies the
      ISSUER_KEY public key, generated as SHA256(KeyConfig).

   *  "encrypted_origin_name" is an encrypted structure that contains
      ORIGIN_NAME, calculated as described in Section 5.7.

   The Client then generates an HTTP POST request to send through the
   Mediator to the Issuer, with the AccessTokenRequest as the body.  The
   media type for this request is "message/access-token-request".  The
   Client includes the "Sec-Token-Origin" header, whose value is
   ANON_ORIGIN_ID; the "Sec-Token-Client" header, whose value is
   CLIENT_KEY; and the "Sec-Token-Nonce" header, whose value is
   mapping_nonce.  The Client sends this request to the Mediator's proxy
   URI.  An example request is shown below, where Nk = 512.

Hendrickson, et al.       Expires 28 April 2022                [Page 21]
Internet-Draft            Private Access Tokens             October 2021

   :method = POST
   :scheme = https
   :authority = issuer.net
   :path = /access-token-request
   accept = message/access-token-response
   cache-control = no-cache, no-store
   content-type = message/access-token-request
   content-length = 512
   sec-token-origin = ANON_ORIGIN_ID
   sec-token-client = CLIENT_KEY
   sec-token-nonce = mapping_nonce

   <Bytes containing the AccessTokenRequest>

   If the Mediator detects a version in the AccessTokenRequest that it
   does not recognize or support, it MUST reject the request with an
   HTTP 400 error.

   The Mediator also checks to validate that the name_key_id in the
   client's AccessTokenRequest matches a known ISSUER_KEY public key for
   the Issuer.  For example, the Mediator can fetch this key using the
   API defined in Section 3.  This check is done to help ensure that the
   Client has not been given a unique key that could allow the Issuer to
   fingerprint or target the Client.  If the key does not match, the
   Mediator rejects the request with an HTTP 400 error.  Note that
   Mediators need to be careful in cases of key rotation; see Section 8.

   The Mediator finally checks to ensure that the
   AccessTokenRequest.mapping_proof is valid for the given CLIENT_KEY;
   see Section 5.8 for verification details.  If the index is invalid,
   the Mediator rejects the request with an HTTP 400 error.

   If the Mediator accepts the request, it will look up the state stored
   for this Client.  It will look up the count of previously generate
   tokens for this Client using the same ANON_ORIGIN_ID.  See
   Section 5.1.2 for more details.

   If the Mediator has stored state that a previous request for this
   ANON_ORIGIN_ID was rejected by the Issuer in the current policy
   window, it SHOULD reject the request without forwarding it to the
   Issuer.

   If the Mediator detects this Client has changed their CLIENT_ID more
   frequently than allowed as described in #mediator-state, it SHOULD
   reject the request without forwarding it to the Issuer.

Hendrickson, et al.       Expires 28 April 2022                [Page 22]
Internet-Draft            Private Access Tokens             October 2021

5.4.  Mediator-to-Issuer Request

   The Mediator and the Issuer MUST use a secure and Issuer-
   authenticated HTTPS connection.  Also, Issuers MUST authenticate
   Mediators, either via mutual TLS or another form of application-layer
   authentication.  They MAY additionally use mechanisms such as TLS
   certificate pinning, to mitigate the risk of channel compromise; see
   Section 7 for additional about this channel.

   Before copying and forwarding the Client's AccessTokenRequest request
   to the Issuer, the Mediator adds a header that includes the count of
   previous tokens as "Sec-Token-Count".  The Mediator MAY also add
   additional context information, but MUST NOT add information that
   will uniquely identify a Client.

   :method = POST
   :scheme = https
   :authority = issuer.net
   :path = /access-token-request
   accept = message/access-token-response
   cache-control = no-cache, no-store
   content-type = message/access-token-request
   content-length = 512
   sec-token-count = 3

   <Bytes containing the AccessTokenRequest>

   Upon receipt of the forwarded request, the Issuer validates the
   following conditions:

   *  The "Sec-Token-Count" header is present

   *  The AccessTokenRequest contains a supported version

   *  For version 1, the AccessTokenRequest.name_key_id corresponds to
      the ID of the ISSUER_KEY held by the Issuer

   *  For version 1, the AccessTokenRequest.encrypted_origin_name can be
      decrypted using the Issuer's private key (the private key
      associated with ISSUER_KEY), and matches an ORIGIN_NAME that is
      served by the Issuer

   *  For version 1, the AccessTokenRequest.blinded_req is of the
      correct size

   *  For version 1, the AccessTokenRequest.token_key_id corresponds to
      an ID of an ORIGIN_TOKEN_KEY for the corresponding ORIGIN_NAME

Hendrickson, et al.       Expires 28 April 2022                [Page 23]
Internet-Draft            Private Access Tokens             October 2021

   If any of these conditions is not met, the Issuer MUST return an HTTP
   400 error to the Mediator, which will forward the error to the
   client.

   If the request is valid, the Issuer then can use the value from "Sec-
   Token-Count" to determine if the Client is allowed to receive a token
   for this Origin during the current policy window.  If the Issuer
   refuses to issue more tokens, it responds with an HTTP 429 (Too Many
   Requests) error to the Mediator, which will forward the error to the
   client.

   The Issuer determines the correct ORIGIN_TOKEN_KEY by using the
   decrypted ORIGIN_NAME value and AccessTokenRequest.token_key_id.  If
   there is no ORIGIN_TOKEN_KEY whose truncated key ID matches
   AccessTokenRequest.token_key_id, the Issuer MUST return an HTTP 401
   error to Mediator, which will forward the error to the client.  The
   Mediator learns that the client's view of the Origin key was invalid
   in the process.

5.5.  Issuer-to-Mediator Response

   If the Issuer is willing to give a token to the Client, the Issuer
   verifies the token request using "mapping_generator", "mapping_key",
   and "mapping_proof":

   valid = SchnorrVerify(mapping_generator, mapping_key, mapping_proof)

   If this fails, the Issuer rejects the request with a 400 error.
   Otherwise, the Issuer decrypts
   AccessTokenRequest.encrypted_origin_name to discover "origin".  If
   this fails, the Issuer rejects the request with a 400 error.  The
   Issuer then evaluates the mapping over the ORIGIN_SECRET pertaining
   to the origin for this issuer:

   mapping_input = DeserializeElement(AccessTokenRequest.mapping_key)
   index = ORIGIN_SECRET * mapping_input
   mapping_index = SerializeElement(index)

   If DeserializeElement fails, or if AccessTokenRequest.mapping_key is
   the identity element, the Issuer rejects the request with a 400
   error.

   The Issuer completes the issuance flow by computing a blinded
   response as follows:

   blind_sig = rsabssa_blind_sign(skP, AccessTokenRequest.blinded_req)

Hendrickson, et al.       Expires 28 April 2022                [Page 24]
Internet-Draft            Private Access Tokens             October 2021

   skP is the private key corresponding to ORIGIN_TOKEN_KEY, known only
   to the Issuer.

   The Issuer generates an HTTP response with status code 200 whose body
   consists of blind_sig, with the content type set as "message/access-
   token-response" and the mapping_tag set in the "Sec-Token-Origin"
   header.

   :status = 200
   content-type = message/access-token-response
   content-length = 512
   sec-token-origin = mapping_index

   <Bytes containing the blind_sig>

5.6.  Mediator-to-Client Response

   Upon receipt of a successful response from the Issuer, the Mediator
   extracts the "Sec-Token-Origin" header, and uses the value to
   determine ANON_ISSUER_ORIGIN_ID.

   index = DeserializeElement(mapping_index)
   nonce = DeserializeScalar(mapping_nonce)
   ANON_ISSUER_ORIGIN_ID = (nonce^(-1)) * index

   If the "Sec-Token-Origin" is missing, or if the same
   ANON_ISSUER_ORIGIN_ID was previously received in a response for a
   different ANON_ORIGIN_ID within the same policy window, the Mediator
   MUST drop the token and respond to the client with an HTTP 400
   status.  If there is not an error, the ANON_ISSUER_ORIGIN_ID is
   stored alongside the state for the ANON_ORIGIN_ID.

   For all other cases, the Mediator forwards all HTTP responses
   unmodified to the Client as the response to the original request for
   this issuance.

   When the Mediator detects successful token issuance, it MUST
   increment the counter in its state for the number of tokens issued to
   the Client for the ANON_ORIGIN_ID.

   Upon receipt, the Client handles the response and, if successful,
   processes the body as follows:

   sig = rsabssa_finalize(ORIGIN_TOKEN_KEY, nonce, blind_sig, blind_inv)

   If this succeeds, the Client then constructs a Private Access Token
   as described in Section 4.1 using the token input message and output
   sig.

Hendrickson, et al.       Expires 28 April 2022                [Page 25]
Internet-Draft            Private Access Tokens             October 2021

5.7.  Encrypting Origin Names

   Given a KeyConfig (ISSUER_KEY), Clients produce encrypted_origin_name
   and authenticate all other contents of the AccessTokenRequest using
   the following values:

   *  the key identifier from the configuration, keyID, with the
      corresponding KEM identified by kemID, the public key from the
      configuration, pkI, and;

   *  a selected combination of KDF, identified by kdfID, and AEAD,
      identified by aeadID.

   Beyond the key configuration inputs, Clients also require the
   AccessTokenRequest inputs.  Together, these are used to encapsulate
   ORIGIN_NAME (origin_name) and produce ENCRYPTED_ORIGIN_NAME
   (encrypted_origin) as follows:

   1.  Compute an [HPKE] context using pkI, yielding context and
       encapsulation key enc.

   2.  Construct associated data, aad, by concatenating the values of
       keyID, kemID, kdfID, aeadID, and all other values of the
       AccessTokenRequest structure.

   3.  Encrypt (seal) request with aad as associated data using context,
       yielding ciphertext ct.

   4.  Concatenate the values of aad, enc, and ct, yielding an
       Encapsulated Request enc_request.

   Note that enc is of fixed-length, so there is no ambiguity in parsing
   this structure.

   In pseudocode, this procedure is as follows:

Hendrickson, et al.       Expires 28 April 2022                [Page 26]
Internet-Draft            Private Access Tokens             October 2021

   enc, context = SetupBaseS(pkI, "AccessTokenRequest")
   aad = concat(encode(1, keyID),
                encode(2, kemID),
                encode(2, kdfID),
                encode(2, aeadID),
                encode(1, version),
                encode(Ne, mapping_generator),
                encode(Ne, mapping_key),
                encode(Np, mapping_proof),
                encode(1, token_key_id),
                encode(Nk, blinded_req),
                encode(32, name_key_id))
   ct = context.Seal(aad, origin_name)
   encrypted_origin_name = concat(enc, ct)

   Issuers reverse this procedure to recover ORIGIN_NAME by computing
   the AAD as described above and decrypting encrypted_origin_name with
   their private key skI, the private key corresponding to pkI.  In
   pseudocode, this procedure is as follows:

   enc, ct = parse(encrypted_origin_name)
   aad = concat(encode(1, keyID),
                encode(2, kemID),
                encode(2, kdfID),
                encode(2, aeadID),
                encode(1, version),
                encode(Ne, mapping_generator),
                encode(Ne, mapping_key),
                encode(Np, mapping_proof),
                encode(1, token_key_id),
                encode(Nk, blinded_req),
                encode(32, name_key_id))
   enc, context = SetupBaseR(enc, skI, "AccessTokenRequest")
   origin_name, error = context.Open(aad, ct)

5.8.  Non-Interactive Schnorr Proof of Knowledge

   Each Issuance request requires evaluation and verification of a
   Schnorr proof-of-knowledge.  Given input secret "secret" and two
   elements, "base" and "target", generation of this proof (u, c, z),
   denoted SchnorrProof(secret, base, target), works as follows:

Hendrickson, et al.       Expires 28 April 2022                [Page 27]
Internet-Draft            Private Access Tokens             October 2021

   r = RandomScalar()
   u = r * base
   c = HashToScalar(SerializeElement(base) ||
                    SerializeElement(target) ||
                    SerializeElement(mask),
                    dst = "PrivateAccessTokensProof")
   z = r + (c * secret)

   The proof is encoded by serializing (u, c, z) as follows:

   struct {
      uint8_t u[Ne];
      uint8_t c[Ns];
      uint8_t z[Ns];
   } Proof;

   The size of this structure is Np = Ne + 2*Ns bytes.

   Verification of a proof (u, c, z), denoted SchnorrVerify(base,
   target, proof), works as follows:

   c = HashToScalar(SerializeElement(base) ||
                    SerializeElement(target) ||
                    SerializeElement(mask),
                    dst = "PrivateAccessTokensProof")
   expected_left = base * z
   expected_right = u + (target * c)

   The proof is considered valid if expected_left is the same as
   expected_right.

6.  Instantiating Uses Cases

   This section describes various instantiations of this protocol to
   address use cases described in Section 1.1.

6.1.  Rate-limited Access

   To instantiate this case, the site acts as an Origin and registers a
   "bounded token" policy with the Issuer.  In this policy, the Issuer
   enforces a fixed number of tokens that it will allow a Client to
   request for a single ORIGIN_NAME.

   Origins request tokens from Clients and, upon successful redemption,
   the Origin knows the Client was able to request a token for the given
   ORIGIN_NAME within its budget.  Failure to present a token can be
   interpreted as a signal that the client's token budget was exceeded.

Hendrickson, et al.       Expires 28 April 2022                [Page 28]
Internet-Draft            Private Access Tokens             October 2021

   Clients can redeem a token from a specific challenge up to the max-
   age in the challenge.  Servers can choose to issue many challenges in
   a single HTTP 401 response, providing the client with many challenge
   nonces which can be used to redeem tokens over a longer period of
   time.

6.2.  Client Geo-Location

   To instantiate this use case, the Issuer has an issuing key pair per
   geographic region, i.e., each region has a unique policy key.  When
   verifying the key for the Client request, the Mediator obtains the
   per-region key from the Issuer based on the Client's perceived
   location.  During issuance, the Mediator checks that this key matches
   that of the Client's request.  If it matches, the Mediator forwards
   the request to complete issuance.  The number of key pairs is then
   the cross product of the number of Origins that require per-region
   keys and the number of regions.

   During redemption, Clients present their geographic location to
   Origins in a "Sec-CH-Geohash" header.  Origins use this to obtain the
   appropriate policy verification key.  Origins request tokens from
   Clients and, upon successful redemption, the Origin knows the Client
   obtained a token for the given ORIGIN_NAME in the specified region.

6.3.  Private Client Authentication

   To instantiate this case, the site acts as an Origin and registers an
   "unlimited token" policy with the Issuer.  In this policy, the Issuer
   does not enforce any limit on the number of tokens a given user will
   obtain.

   Origins request tokens from Clients and, upon successful redemption,
   the Origin knows the Client was able to request a token for the given
   ORIGIN_NAME tuple.  As a result, the Origin knows this is an
   authentic client.

7.  Security Considerations

   This section discusses security considerations for the protocol.

   [OPEN ISSUE: discuss trust model]

Hendrickson, et al.       Expires 28 April 2022                [Page 29]
Internet-Draft            Private Access Tokens             October 2021

7.1.  Client Identity

   The HTTPS connection between Client and Mediator is minimally
   Mediator-authenticated.  Mediators can also require Client
   authentication if they wish to restrict Private Access Token proxying
   to trusted or otherwise authenticated Clients.  Absent some form of
   Client authentication, Mediators can use other per-Client information
   for the client identifier mapping, such as IP addresses.

7.2.  Denial of Service

   Requesting and verifying a Private Access Token is more expensive
   than checking an implicit signal, such as an IP address, especially
   since malicious clients can generate garbage Private Access Tokens
   and for Origins to work.  However, similar DoS vectors already exist
   for Origins, e.g., at the underlying TLS layer.

7.3.  Channel Security

   An attacker that can act as an intermediate between Mediator and
   Issuer communication can influence or disrupt the ability for the
   Issuer to correctly rate-limit token issuance.  All communication
   channels use server-authenticated HTTPS.  Some connections, e.g.,
   between a Mediator and an Issuer, require mutual authentication
   between both endpoints.  Where appropriate, endpoints MAY use further
   enhancements such as TLS certificate pinning to mitigate the risk of
   channel compromise.

   An attacker that can intermediate the channel between Client and
   Origin can observe a TokenChallenge, and can view a Token being
   presented for authentication to an Origin.  Scoping the
   TokenChallenge nonce to the Client HTTP session prevents Tokens being
   collected in one session and then presented to the Origin in another.
   Note that an Origin cannot distinguish between a connection to a
   single Client and a connection to an attacker intermediating multiple
   Clients.  Thus, it is possible for an attacker to collect and later
   present Tokens from multiple clients over the same Origin session.

8.  Privacy Considerations

8.1.  Client Token State and Origin Tracking

   Origins SHOULD only generate token challenges based on client action,
   such as when a user loads a website.  Clients SHOULD ignore token
   challenges if an Origin tries to force the client to present tokens
   multiple times without any new client-initiated action.  Failure to
   do so can allow malicious origins to track clients across contexts.
   Specifically, an origin can abuse per-user token limits for tracking

Hendrickson, et al.       Expires 28 April 2022                [Page 30]
Internet-Draft            Private Access Tokens             October 2021

   by assigning each new client a random token count and observing
   whether or not the client can successfully redeem that many tokens in
   a given context.  If any token redemption fails, then the origin
   learns information about how many tokens that client had previously
   been issued.

   By rejecting repeated or duplicative challenges within a single
   context, the origin only learns a single bit of information: whether
   or not the client had any token quota left in the given policy
   window.

8.2.  Origin Verification

   Private Access Tokens are defined in terms of a Client authenticating
   to an Origin, where the "origin" is used as defined in [RFC6454].  In
   order to limit cross-origin correlation, Clients MUST verify that the
   origin_name presented in the TokenChallenge structure (Section 4.1)
   matches the origin that is providing the HTTP authentication
   challenge, where the matching logic is defined for same-origin
   policies in [RFC6454].  Clients MAY further limit which
   authentication challenges they are willing to respond to, for example
   by only accepting challenges when the origin is a web site to which
   the user navigated.

8.3.  Client Identification with Unique Keys

   Client activity could be linked if an Origin and Issuer collude to
   have unique keys targeted at specific Clients or sets of Clients.

   To mitigate the risk of a targeted ISSUER_KEY, the Mediator can
   observe and validate the name_key_id presented by the Client to the
   Issuer.  As described in Section 5, Mediators MUST validate that the
   name_key_id in the Client's AccessTokenRequest matches a known public
   key for the Issuer.  The Mediator needs to support key rotation, but
   ought to disallow very rapid key changes, which could indicate that
   an Origin is colluding with an Issuer to try to rotate the key for
   each new Client in order to link the client activity.

   To mitigate the risk of a targeted ORIGIN_TOKEN_KEY, the protocol
   expects that an Issuer has only a single valid public key for signing
   tokens at a time.  The Client does not present the name_key_id of the
   token public key to the Issuer, but instead expects the Issuer to
   infer the correct key based on the information the Issuer knows,
   specifically the origin_name itself.

Hendrickson, et al.       Expires 28 April 2022                [Page 31]
Internet-Draft            Private Access Tokens             October 2021

8.4.  Collusion Among Different Entities

   Collusion among the different entities in the PAT architecture can
   result in violation of the Client's privacy.

   Issuers and Mediators should be run by mutually distinct
   organizations to limit information sharing.  A single entity running
   an issuer and mediator for a single redemption can view the origins
   being accessed by a given client.  Running the issuer and mediator in
   this 'single issuer/mediator' fashion reduces the privacy promises to
   those of the [I-D.ietf-privacypass-protocol]; see Appendix A for more
   discussion.  This may be desirable for a redemption flow that is
   limited to specific issuers and mediators, but should be avoided
   where hiding origins from the mediator is desirable.

   If a Mediator and Origin are able to collude, they can correlate a
   client's identity and origin access patterns through timestamp
   correlation.  The timing of a request to an Origin and subsequent
   token issuance to a Mediator can reveal the Client identity (as known
   to the Mediator) to the Origin, especially if repeated over multiple
   accesses.

9.  Deployment Considerations

9.1.  Origin Key Rollout

   Issuers SHOULD generate a new (ORIGIN_TOKEN_KEY, ORIGIN_SECRET)
   regularly, and SHOULD maintain old and new secrets to allow for
   graceful updates.  The RECOMMENDED rotation interval is two times the
   length of the policy window for that information.  During generation,
   issuers must ensure the token_key_id (the 8-bit prefix of
   SHA256(ORIGIN_TOKEN_KEY)) is different from all other token_key_id
   values for that origin currently in rotation.  One way to ensure this
   uniqueness is via rejection sampling, where a new key is generated
   until its token_key_id is unique among all currently in rotation for
   the origin.

10.  IANA Considerations

10.1.  Authentication Scheme

   This document registers the "PrivateAccessToken" authentication
   scheme in the "Hypertext Transfer Protocol (HTTP) Authentication
   Scheme Registry" established by [RFC7235].

   Authentication Scheme Name: PrivateAccessToken

   Pointer to specification text: Section 4.1 of this document

Hendrickson, et al.       Expires 28 April 2022                [Page 32]
Internet-Draft            Private Access Tokens             October 2021

10.2.  HTTP Headers

   This document registers four new headers for use on the token
   issuance path in the "Permanent Message Header Field Names"
   <https://www.iana.org/assignments/message-headers>.

       +-------------------+----------+--------+---------------+
       | Header Field Name | Protocol | Status |   Reference   |
       +-------------------+----------+--------+---------------+
       | Sec-Token-Origin  |   http   |  std   | This document |
       +-------------------+----------+--------+---------------+
       | Sec-Token-Client  |   http   |  std   | This document |
       +-------------------+----------+--------+---------------+
       | Sec-Token-Nonce   |   http   |  std   | This document |
       +-------------------+----------+--------+---------------+
       | Sec-Token-Count   |   http   |  std   | This document |
       +-------------------+----------+--------+---------------+

                      Figure 2: Registered HTTP Header

10.3.  Media Types

   This specification defines the following protocol messages, along
   with their corresponding media types:

   *  AccessTokenRequest Section 5: "message/access-token-request"

   *  AccessTokenResponse Section 5: "message/access-token-response"

   The definition for each media type is in the following subsections.

10.3.1.  "message/access-token-request" media type

   Type name:  message

   Subtype name:  access-token-request

   Required parameters:  N/A

   Optional parameters:  None

   Encoding considerations:  only "8bit" or "binary" is permitted

   Security considerations:  see Section 5

   Interoperability considerations:  N/A

   Published specification:  this specification

Hendrickson, et al.       Expires 28 April 2022                [Page 33]
Internet-Draft            Private Access Tokens             October 2021

   Applications that use this media type:  N/A

   Fragment identifier considerations:  N/A

   Additional information:  Magic number(s):  N/A

                            Deprecated alias names for this type:  N/A

                            File extension(s):  N/A

                            Macintosh file type code(s):  N/A

   Person and email address to contact for further information:  see Aut
      hors' Addresses section

   Intended usage:  COMMON

   Restrictions on usage:  N/A

   Author:  see Authors' Addresses section

   Change controller:  IESG

10.3.2.  "message/access-token-response" media type

   Type name:  message

   Subtype name:  access-token-response

   Required parameters:  N/A

   Optional parameters:  None

   Encoding considerations:  only "8bit" or "binary" is permitted

   Security considerations:  see Section 5

   Interoperability considerations:  N/A

   Published specification:  this specification

   Applications that use this media type:  N/A

   Fragment identifier considerations:  N/A

   Additional information:  Magic number(s):  N/A

                            Deprecated alias names for this type:  N/A

Hendrickson, et al.       Expires 28 April 2022                [Page 34]
Internet-Draft            Private Access Tokens             October 2021

                            File extension(s):  N/A

                            Macintosh file type code(s):  N/A

   Person and email address to contact for further information:  see Aut
      hors' Addresses section

   Intended usage:  COMMON

   Restrictions on usage:  N/A

   Author:  see Authors' Addresses section

   Change controller:  IESG

11.  References

11.1.  Normative References

   [BLINDSIG] Denis, F., Jacobs, F., and C. A. Wood, "RSA Blind
              Signatures", Work in Progress, Internet-Draft, draft-irtf-
              cfrg-rsa-blind-signatures-02, 2 August 2021,
              <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
              rsa-blind-signatures-02>.

   [HPKE]     Barnes, R. L., Bhargavan, K., Lipp, B., and C. A. Wood,
              "Hybrid Public Key Encryption", Work in Progress,
              Internet-Draft, draft-irtf-cfrg-hpke-12, 2 September 2021,
              <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
              hpke-12>.

   [OHTTP]    Thomson, M. and C. A. Wood, "Oblivious HTTP", Work in
              Progress, Internet-Draft, draft-thomson-http-oblivious-02,
              24 August 2021, <https://datatracker.ietf.org/doc/html/
              draft-thomson-http-oblivious-02>.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC4648]  Josefsson, S., "The Base16, Base32, and Base64 Data
              Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
              <https://www.rfc-editor.org/rfc/rfc4648>.

   [RFC6454]  Barth, A., "The Web Origin Concept", RFC 6454,
              DOI 10.17487/RFC6454, December 2011,
              <https://www.rfc-editor.org/rfc/rfc6454>.

Hendrickson, et al.       Expires 28 April 2022                [Page 35]
Internet-Draft            Private Access Tokens             October 2021

   [RFC7235]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
              Protocol (HTTP/1.1): Authentication", RFC 7235,
              DOI 10.17487/RFC7235, June 2014,
              <https://www.rfc-editor.org/rfc/rfc7235>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.

   [RFC8941]  Nottingham, M. and P-H. Kamp, "Structured Field Values for
              HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021,
              <https://www.rfc-editor.org/rfc/rfc8941>.

   [TLS13]    Rescorla, E., "The Transport Layer Security (TLS) Protocol
              Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
              <https://www.rfc-editor.org/rfc/rfc8446>.

   [VOPRF]    Davidson, A., Faz-Hernandez, A., Sullivan, N., and C. A.
              Wood, "Oblivious Pseudorandom Functions (OPRFs) using
              Prime-Order Groups", Work in Progress, Internet-Draft,
              draft-irtf-cfrg-voprf-07, 6 July 2021,
              <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
              voprf-07>.

11.2.  Informative References

   [I-D.ietf-privacypass-protocol]
              Celi, S., Davidson, A., and A. Faz-Hernandez, "Privacy
              Pass Protocol Specification", Work in Progress, Internet-
              Draft, draft-ietf-privacypass-protocol-01, 22 February
              2021, <https://datatracker.ietf.org/doc/html/draft-ietf-
              privacypass-protocol-01>.

Appendix A.  Related Work: Privacy Pass

   Private Access Tokens has many similarities to the existing Privacy
   Pass protocol ([I-D.ietf-privacypass-protocol]).  Both protocols
   allow clients to redeem signed tokens while not allowing linking
   between token issuance and token redemption.

   There are several important differences between the protocols,
   however:

   *  Private Access Tokens uses per-origin tokens that support rate-
      limiting policies.  Each token can only be used with a specific
      origin in accordance with a policy defined for that origin.  This
      allows origins to implement metered paywalls or mechanisms that
      that limit the actions a single client can perform.  Per-origin

Hendrickson, et al.       Expires 28 April 2022                [Page 36]
Internet-Draft            Private Access Tokens             October 2021

      tokens also ensure that one origin cannot consume all of a
      client's tokens, so there is less need for clients to manage when
      they are willing to present tokens to origins.

   *  Private Access Tokens employ an online challenge (Section 4.1)
      during token redemption.  This ensures that tokens cannot be
      harvested and stored for use later.  This also removes the need
      for preventing double spending or employing token expiry
      techniques, such as frequent signer rotation or expiry-encoded
      public metadata.

   *  Private Access Tokens use a publically verifiable signature
      [BLINDSIG] to optimize token verification at the origin by
      avoiding a round trip to the issuer/mediator.

Authors' Addresses

   Scott Hendrickson
   Google LLC

   Email: scott@shendrickson.com

   Jana Iyengar
   Fastly

   Email: jri@fastly.com

   Tommy Pauly
   Apple Inc.
   One Apple Park Way
   Cupertino, California 95014,
   United States of America

   Email: tpauly@apple.com

   Steven Valdez
   Google LLC

   Email: svaldez@chromium.org

   Christopher A. Wood
   Cloudflare

   Email: caw@heapingbits.net

Hendrickson, et al.       Expires 28 April 2022                [Page 37]