<?xml version='1.0' encoding='UTF-8'?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" ipr="trust200902" submissionType="IETF" category="info" consensus="false" docName="draft-li-oauth-policy-based-anonymous-tokens-00">
  <front>
    <title abbrev="OAuth Policy-Based Anonymous Tokens">OAuth 2.0 Policy-Based Anonymous Access Tokens</title>
    <seriesInfo name="Internet-Draft" value="draft-li-oauth-policy-based-anonymous-tokens-00"/>
    <author fullname="David Kretzler" initials="D. Kretzler">
      <organization abbrev="Huawei">Huawei Heisenberg Research Center</organization>
      <address>
        <postal>
          <country>Germany</country>
        </postal>
        <email>david.kretzler@huawei.com</email>
      </address>
    </author>
    <author fullname="Yong Li" initials="Y. Li">
      <organization abbrev="Huawei">Huawei Heisenberg Research Center</organization>
      <address>
        <postal>
          <country>Germany</country>
        </postal>
        <email>yong.li1@huawei.com</email>
      </address>
    </author>
    <author fullname="Jian Wang" initials="J. Wang">
      <organization abbrev="Huawei">Huawei Technologies Co., Ltd.</organization>
      <address>
        <postal>
          <street>Huawei Industrial Base, Bantian, Longgang District</street>
          <city>Shenzhen</city>
          <region>Guangdong</region>
          <code>518129</code>
          <country>China</country>
        </postal>
        <email>wangjian365@huawei.com</email>
      </address>
    </author>
    <author fullname="Antoine Fressancourt" initials="A. Fressancourt">
      <organization abbrev="Huawei">Huawei Technologies France S.A.S.U.</organization>
      <address>
        <postal>
          <street>18, Quai du Point du Jour</street>
          <city>Boulogne-Billancourt</city>
          <code>92100</code>
          <country>France</country>
        </postal>
        <email>antoine.fressancourt@huawei.com</email>
      </address>
    </author>
    <date year="2026" month="August" day="26"/>
    <area>Security</area>
    <keyword>OAuth</keyword>
    <keyword>policy-based authorization</keyword>
    <keyword>anonymous tokens</keyword>
    <keyword>unlinkability</keyword>
    <keyword>agent authorization</keyword>
    <abstract>
      <t>This document specifies an OAuth 2.0 access-token type that allows a client, after one authorization-server issuance, to derive a policy-bounded set of unlinkable, single-use access tokens locally. Each derived token is bound to one canonical tag, an intended resource server, approved authorization details, a policy epoch, and a validity interval. Resource servers validate the token offline and enforce both policy membership and replay prevention.</t>
      <t>The protocol defines authorization request semantics, token-endpoint issuance, canonical policy and metadata objects, token derivation and HTTP presentation, resource-server validation, capability discovery, error handling, and IANA registrations. Version 1 requires public verification and the counter-window policy profile. It supports an optional private metadata bit, while private-verification ciphersuites remain optional.</t>
      <t>Concrete cryptographic algorithms are supplied by separately registered PBAT ciphersuites. The initial mandatory-to-implement ciphersuite is the publicly-verifiable equivalence-class-signature construction over BLS12-381 specified by the companion PBAT ciphersuite document. This specification does not replace OAuth grants, resource-owner consent, client authentication, or audience restriction.</t>
      <t>— middle</t>
    </abstract>
  </front>
  <middle>
    <section anchor="introduction">
      <name>Introduction</name>
      <t>OAuth 2.0 <xref target="RFC6749"/> enables a client to obtain limited access to a protected resource. The authorization server (AS) makes an authorization decision and issues an access token. The client presents the access token to a resource server (RS), commonly using the bearer-token mechanism defined in <xref target="RFC6750"/>.</t>
      <t>This model is widely deployed, but two common design choices create an undesirable trade-off in some environments:</t>
      <ul>
        <li>
          <t>The client obtains an independently redeemable token for each action or short group of actions. This provides fine-grained control. Batched issuance can reduce the number of AS round trips, but the issuance communication and issuer work remain linear in the number of tokens. A policy or public-context change requires another issuance interaction.</t>
        </li>
        <li>
          <t>The client obtains a reusable token, commonly called an anonymous credential in cryptographic protocols, covering many actions. This reduces AS interaction, but increases the authority and lifetime of a single credential and can make action-level quotas difficult to enforce without an additional online authorization service.</t>
        </li>
      </ul>
      <t>The trade-off is especially visible for automated agents. An agent can be authorized to perform a bounded task containing many calls, potentially across administrative domains. The principal may want the agent to perform up to a specified number of actions during a policy epoch without giving the agent an unrestricted bearer token or requiring the AS to approve every individual call. Related agent-authorization requirements are discussed in <xref target="AGENT-AUTHZ"/>.</t>
      <t>Policy-based anonymous tokens (PBATs), introduced in <xref target="PBAT-ORIGINAL"/> and extended in <xref target="PBAT"/>, provide a useful cryptographic building block for this problem. A token issuer issues one pre-token to an eligible client. The client then locally derives one token for each tag allowed by a public policy. For a fixed pre-token and tag, token derivation is deterministic, which allows the verifier to reject reuse while preventing the client from creating more independent tokens than the policy admits. Issuance and redemption are unlinkable even when the issuer and verifier collude, subject to the limitations described in this document.</t>
      <t>This document specifies the version 1 OAuth protocol profile for that primitive. It makes the following contributions:</t>
      <ol>
        <li>
          <t>It defines the OAuth roles and authorization semantics for policy-based anonymous access tokens.</t>
        </li>
        <li>
          <t>It defines a stable ciphersuite interface and registry so that the OAuth protocol does not depend on one cryptographic construction.</t>
        </li>
        <li>
          <t>It defines issuance, local derivation, presentation, and validation phases.</t>
        </li>
        <li>
          <t>It defines requirements for policies, tags, public metadata, replay detection, privacy, and key management.</t>
        </li>
        <li>
          <t>It defines the counter-window policy profile, the <tt>PBAT</tt> HTTP authentication scheme, conformance requirements, and required IANA registrations.</t>
        </li>
      </ol>
      <t>Discussion of this document takes place on the OAuth Working Group mailing list (mailto:oauth@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/oauth/.</t>
      <t>The term anonymous in this document has a narrow meaning: a successfully redeemed token cannot be linked to its issuance transcript, except through information deliberately placed in the policy, public metadata, or external network and application signals. It does not mean that the client is anonymous to the AS during the OAuth authorization process, nor that the RS is unable to observe the request it serves.</t>
    </section>
    <section anchor="conventions">
      <name>Conventions and Requirements Language</name>
      <t>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 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>This document uses the OAuth terms authorization server, client, resource owner, resource server, access token, and grant as defined by <xref target="RFC6749"/>.</t>
      <dl>
        <dt>Policy-Based Authorization Credential (PBAC):</dt>
        <dd>
          <t>A credential issued by the AS after an OAuth authorization decision. A PBAC is not presented directly to an RS. It enables the client to derive policy-based anonymous access tokens.</t>
        </dd>
        <dt>Policy-Based Anonymous Access Token (PBAT):</dt>
        <dd>
          <t>A token locally derived from a PBAC for one policy-admitted tag. A PBAT is presented to an RS. Within a policy epoch, the same PBAC and tag produce the same logical token.</t>
        </dd>
        <dt>Issuance Request:</dt>
        <dd>
          <t>Ciphersuite-specific data generated by the client and sent to the AS during PBAC issuance. It commonly contains a blinded or public representation of a client-generated secret and a proof of possession of that secret.</t>
        </dd>
        <dt>Issuance Response:</dt>
        <dd>
          <t>Ciphersuite-specific data generated by the AS. The client finalizes this response to obtain a PBAC.</t>
        </dd>
        <dt>Policy:</dt>
        <dd>
          <t>An authorization rule that defines the finite or otherwise bounded set of tags for which a client can derive acceptable PBATs, together with the authorization semantics applying to those tags.</t>
        </dd>
        <dt>Policy Epoch:</dt>
        <dd>
          <t>A period during which a policy, its identifier, and its tag interpretation remain stable. A new epoch results in a distinct tag namespace.</t>
        </dd>
        <dt>Policy Evaluation Context:</dt>
        <dd>
          <t>Public, independently verifiable inputs used by a policy profile when it evaluates a tag. Examples include the current time, a policy epoch derived from time, or an authenticated location assertion. The context is not a client assertion and is evaluated independently by the RS.</t>
        </dd>
        <dt>Tag:</dt>
        <dd>
          <t>A canonical byte string identifying one permitted derivation opportunity under a policy. A tag can encode a counter, time window, action class, transaction identifier, or a profile-defined combination of these values.</t>
        </dd>
        <dt>Public Metadata:</dt>
        <dd>
          <t>Canonically encoded information visible to the client, AS, and RS and cryptographically bound to a PBAC and all PBATs derived from it. Public metadata carries security-relevant information that is not intended to be hidden.</t>
        </dd>
        <dt>Private Metadata Bit:</dt>
        <dd>
          <t>An optional one-bit value selected by the AS, hidden from the client at issuance, and recoverable only by an authorized verifier. The bit is not a general-purpose claim channel.</t>
        </dd>
        <dt>Ciphersuite:</dt>
        <dd>
          <t>A registered specification of the cryptographic algorithms, groups, hash functions, encodings, and proof systems implementing the abstract PBAT operations in this document.</t>
        </dd>
        <dt>Spent-Token State:</dt>
        <dd>
          <t>State maintained by an RS, or by a service trusted by a set of RSs, to detect repeated presentation of the same PBAT.</t>
        </dd>
      </dl>
    </section>
    <section anchor="problem-statement">
      <name>Problem Statement</name>
      <t>OAuth provides several mechanisms for narrowing authority. Scopes, authorization details <xref target="RFC9396"/>, resource indicators <xref target="RFC8707"/>, token exchange <xref target="RFC8693"/>, sender-constrained tokens such as DPoP <xref target="RFC9449"/>, and short token lifetimes can all reduce the authority or exposure of an access token. None of these mechanisms, by itself, allows a client to obtain one policy-bound credential and then locally derive a bounded set of issuance-redemption-unlinkable access tokens.</t>
      <t>The problem addressed by this document has five elements:</t>
      <ul>
        <li>
          <t><strong>Bounded local derivation:</strong> An AS authorizes a bounded set of future actions without issuing one token per action.</t>
        </li>
        <li>
          <t><strong>Least authority:</strong> Each presented token represents one tag and does not expose a reusable credential covering the entire task.</t>
        </li>
        <li>
          <t><strong>Issuance-redemption unlinkability:</strong> The AS and RS cannot cryptographically correlate a presented PBAT with a particular issuance transcript, even if they share protocol transcripts. Nor can they cryptographically correlate it with another PBAT derived from the same PBAC, except through information deliberately exposed in the tag, policy, public metadata, or the enclosing application request.</t>
        </li>
        <li>
          <t><strong>Policy enforcement:</strong> An RS can determine whether the tag and public metadata are valid under the authorization policy and can reject reuse.</t>
        </li>
        <li>
          <t><strong>OAuth compatibility:</strong> Resource-owner consent, client authentication, authorization details, audience restriction, and OAuth security best practices remain applicable.</t>
        </li>
      </ul>
    </section>
    <section anchor="use-cases">
      <name>Use Cases</name>
      <section anchor="bounded-agent-task-execution">
        <name>Bounded Agent Task Execution</name>
        <t>A user authorizes an agent to perform up to 20 read operations against a data service during a 30-minute task. The AS issues one PBAC bound to the RS, authorization details, maximum-use policy, and expiry time. The agent derives one PBAT for each admitted counter value and presents a different PBAT for each operation. Compromise of one presented PBAT does not reveal the PBAC and does not enable additional derivations.</t>
        <t>The issuer assigns any task identifier outside the PBAT’s public metadata and policy unless that identifier is shared by a sufficiently large population. Embedding a unique task identifier, or other client-specific value, in a PBAT-bound policy or metadata partitions the anonymity set and can link the PBATs derived from that PBAC.</t>
        <t>The AS learns that it authorized the task and its policy, but it does not learn from the PBAT protocol which permitted counter value was used at which time. The RS necessarily observes the operation and tag it processes, and a colluding RS can disclose this information to the AS.</t>
      </section>
      <section anchor="privacy-preserving-rate-limited-api-access">
        <name>Privacy-Preserving, Rate-Limited API Access</name>
        <t>A service authorizes an eligible client to make a fixed number of anonymous API calls during a daily epoch. Eligibility can be based on subscription, device posture, proof of personhood, payment, or another mechanism outside the scope of this document. The client obtains one PBAC and derives a PBAT for each counter admitted by the daily policy. The RS rejects a repeated PBAT and therefore enforces the limit without learning the client’s OAuth identity from the PBAT.</t>
      </section>
      <section anchor="cross-domain-resource-access">
        <name>Cross-Domain Resource Access</name>
        <t>An AS in one administrative domain authorizes a client to access an RS in another domain. A publicly verifiable PBAT ciphersuite allows the RS to validate derived tokens with an AS public key. The public metadata binds the credential to the intended audience and authorization details. The RS does not need an online introspection call for every request.</t>
      </section>
      <section anchor="hidden-binary-issuer-decision">
        <name>Hidden Binary Issuer Decision</name>
        <t>In a deployment with an explicitly defined risk model, an AS issues a PBAC containing a private metadata bit. The bit can represent one of two issuer decisions while preventing the client from learning the decision from the issuance transcript alone. An authorized verifier can recover the bit during redemption and apply a locally defined action.</t>
        <t>This feature is optional. It is not suitable when the verifier’s observable response immediately discloses the bit, when a transparent authorization decision is required, or when the AS needs to convey more than a binary decision.</t>
      </section>
    </section>
    <section anchor="design-goals">
      <name>Design Goals and Non-Goals</name>
      <section anchor="goals">
        <name>Goals</name>
        <t>The protocol has the following goals:</t>
        <ul>
          <li>
            <t>Preserve the OAuth authorization decision and audience restriction.</t>
          </li>
          <li>
            <t>Permit one AS issuance interaction to authorize a bounded set of local derivations.</t>
          </li>
          <li>
            <t>Prevent derivation of more independent tokens than admitted by the policy.</t>
          </li>
          <li>
            <t>Bind each PBAT to immutable public metadata.</t>
          </li>
          <li>
            <t>Make an issuance transcript and PBAT redemption transcript cryptographically unlinkable, and make separate PBAT redemption transcripts derived from the same PBAC cryptographically unlinkable, subject to deliberately exposed policy, metadata, tag, and application-request information.</t>
          </li>
          <li>
            <t>Support public verification for cross-domain deployments.</t>
          </li>
          <li>
            <t>Permit private verification where AS and RS key-sharing is acceptable.</t>
          </li>
          <li>
            <t>Provide ciphersuite agility and allow independent cryptographic review.</t>
          </li>
          <li>
            <t>Preserve compatibility with OAuth security guidance in <xref target="RFC9700"/>.</t>
          </li>
        </ul>
      </section>
      <section anchor="non-goals">
        <name>Non-Goals</name>
        <t>This document does not:</t>
        <ul>
          <li>
            <t>Authenticate a human or establish proof of personhood.</t>
          </li>
          <li>
            <t>Replace OAuth grants, resource-owner consent, or client authentication.</t>
          </li>
          <li>
            <t>Hide the requested resource, method, timing, network address, or application behavior from the RS.</t>
          </li>
          <li>
            <t>Provide general anonymous credentials or selective disclosure.</t>
          </li>
          <li>
            <t>Provide unrestricted offline delegation or allow a holder to widen the authorization granted by the AS.</t>
          </li>
          <li>
            <t>Eliminate all server-side state. Replay-resistant deployments maintain spent-token state.</t>
          </li>
          <li>
            <t>Restate the algorithms of each concrete cryptographic ciphersuite in this document. Ciphersuites are separate Standards Track specifications and are registered under the rules in this document.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="architecture">
      <name>OAuth Architecture</name>
      <t>The OAuth role mapping is as follows:</t>
      <table>
        <thead>
          <tr>
            <th>PBAT function</th>
            <th>OAuth role</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Issuer</td>
            <td>Authorization Server</td>
          </tr>
          <tr>
            <td>Client</td>
            <td>OAuth Client, including an automated agent</td>
          </tr>
          <tr>
            <td>Verifier</td>
            <td>Resource Server</td>
          </tr>
          <tr>
            <td>Eligibility decision</td>
            <td>OAuth authorization decision</td>
          </tr>
          <tr>
            <td>Pre-token</td>
            <td>Policy-Based Authorization Credential</td>
          </tr>
          <tr>
            <td>Locally derived token</td>
            <td>Policy-Based Anonymous Access Token</td>
          </tr>
        </tbody>
      </table>
      <t>The resource owner, when present, authorizes the client through an OAuth grant. The AS authenticates the client when required by the selected grant and makes an authorization decision. PBAT changes the form and use of the resulting access credential; it does not change how the grant is obtained.</t>
      <t>The high-level protocol flow, after completion of the selected OAuth grant, is:</t>
      <figure>
        <artwork> Client                    Authorization Server                 RS
   |                                |                           |
   |-- obtain policy and metadata -&gt;|                           |
   |&lt;-- policy and metadata --------|                           |
   |                                |                           |
   |-- token request + issuance ---&gt;|                           |
   |&lt;-- issuance response ----------|                           |
   |                                |                           |
   |-- Finalize issuance            |                           |
   |-- Derive(tag_1)                |                           |
   |--------------------- PBAT(tag_1) --------------------------&gt;|
   |&lt;-------------------- protected resource -------------------|
   |                                |                           |
   |-- Derive(tag_2)                |                           |
   |--------------------- PBAT(tag_2) --------------------------&gt;|
   |&lt;-------------------- protected resource -------------------|</artwork>
      </figure>
      <t>{: artwork-align=center artwork-name=OAuth PBAT flow}</t>
      <t>The AS can know the client and resource owner during issuance. The privacy property applies between the issuance transcript and later PBAT presentations. Deployments that require the AS not to learn the client identity need an additional anonymous or privacy-preserving eligibility mechanism, which is outside the scope of this document.</t>
    </section>
    <section anchor="suite-interface">
      <name>Abstract PBAT Ciphersuite Interface</name>
      <t>A conforming PBAT ciphersuite defines the following operations. The exact inputs and outputs are ciphersuite-specific byte strings, but their security semantics are common. Ciphersuite identifiers are case-sensitive ASCII strings registered in the OAuth PBAT Ciphersuites registry. An implementation MUST NOT advertise or select an unregistered identifier, except for identifiers beginning with <tt>x-</tt> in a closed test deployment.</t>
      <dl>
        <dt>
          <tt>Setup(security_parameter) -&gt; public_parameters</tt>
        </dt>
        <dd>
          <t>Establishes public parameters and domain-separation values.</t>
        </dd>
        <dt>
          <tt>IssuerKeyGen(public_parameters, mode) -&gt; (issuer_private_key, issuer_public_key)</tt>
        </dt>
        <dd>
          <t>Generates key material for public or private verification. A public-mode ciphersuite MUST permit validation using only the issuer public key. A private-mode ciphersuite uses the issuer private key as its verifier key in version 1. An RS that receives this key is therefore trusted as an issuer for the purposes of that ciphersuite.</t>
        </dd>
        <dt>
          <tt>Request(public_parameters, public_metadata, issuer_public_key) -&gt; (issuance_request, client_state)</tt>
        </dt>
        <dd>
          <t>Creates a fresh client secret and an issuance request without revealing the secret. The public metadata is bound to the resulting client state.</t>
        </dd>
      </dl>
      <t><tt>Issue(public_parameters, issuance_request, public_metadata, private_bit, issuer_private_key) -&gt; issuance_response</tt> : Creates an issuance response bound to the public metadata. If the public metadata enables a private metadata bit, <tt>private_bit</tt> is either zero or one; otherwise it is <tt>none</tt>. A malicious issuer MUST NOT be able to embed an unrestricted hidden identifier in place of the bit without detection by the client.</t>
      <dl>
        <dt>
          <tt>Finalize(public_parameters, issuance_response, client_state) -&gt; PBAC</tt>
        </dt>
        <dd>
          <t>Verifies the issuance response and returns a PBAC or an error. Finalization MUST detect an invalid issuer proof, a public-metadata mismatch, and malformed ciphersuite data.</t>
        </dd>
        <dt>
          <tt>Derive(public_parameters, PBAC, tag) -&gt; (token, witness)</tt>
        </dt>
        <dd>
          <t>Derives the token and proof material associated with <tt>tag</tt>. For a fixed PBAC and canonical tag, the logical token MUST be deterministic. The externally visible witness SHOULD be randomized so that it cannot be linked to the issuance transcript.</t>
        </dd>
      </dl>
      <t><tt>Verify(public_parameters, policy, token, tag, public_metadata, witness, issuer_public_key) -&gt; valid | invalid</tt> : Validates a publicly verifiable PBAT.</t>
      <t><tt>VerifyPrivate(public_parameters, policy, token, tag, public_metadata, witness, verifier_key) -&gt; valid | invalid</tt> : Validates a private-verification PBAT.</t>
      <t><tt>ReadBit(public_parameters, policy, token, tag, public_metadata, witness, verifier_key) -&gt; 0 | 1 | invalid</tt> : When the ciphersuite supports private metadata, validates the relevant proof and returns the private metadata bit. A ciphersuite MAY share computation between this operation and either verification operation, but the logical results remain distinct.</t>
      <t>A ciphersuite specification MUST define:</t>
      <ul>
        <li>
          <t>all groups, fields, hash functions, and proof systems;</t>
        </li>
        <li>
          <t>canonical encoding and decoding of every ciphersuite value;</t>
        </li>
        <li>
          <t>hash-to-field and hash-to-group functions, as applicable;</t>
        </li>
        <li>
          <t>domain-separation tags for all protocol contexts;</t>
        </li>
        <li>
          <t>validation of public keys, group elements, and proofs;</t>
        </li>
        <li>
          <t>public- and private-verification capabilities;</t>
        </li>
        <li>
          <t>test vectors, including invalid and boundary cases;</t>
        </li>
        <li>
          <t>the security assumptions and claimed security properties; and</t>
        </li>
        <li>
          <t>limits on policy, metadata, and tag sizes.</t>
        </li>
      </ul>
      <t>Version 1 implementations MUST implement <tt>PBAT-EQS-BLS12381-SHA256</tt>, the public-verification equivalence-class-signature ciphersuite over BLS12-381 selected in <xref target="standards-path"/> and specified by the companion ciphersuite document. An implementation MUST NOT substitute a locally defined suite under that identifier.</t>
      <t>The algebraic-MAC construction in <xref target="PBAT"/> is the designated basis for a subsequent optional private-verification ciphersuite. The zkSNARK construction is not part of version 1 because its proving cost and setup requirements do not justify a mandatory interoperable profile.</t>
    </section>
    <section anchor="authorization-request">
      <name>Authorization Request</name>
      <t>A client requests PBAT authorization using the <tt>authorization_details</tt> parameter defined by <xref target="RFC9396"/>. The authorization-detail type is <tt>policy_based_anonymous_token</tt>. For PBAT issuance, the <tt>authorization_details</tt> array MUST contain exactly one object and that object MUST have this type.</t>
      <t>The authorization detail contains the following members:</t>
      <dl>
        <dt>
          <tt>type</tt>
        </dt>
        <dd>
          <t>REQUIRED. The value MUST be <tt>policy_based_anonymous_token</tt>.</t>
        </dd>
        <dt>
          <tt>locations</tt>
        </dt>
        <dd>
          <t>REQUIRED. An array containing one or more RS identifiers as defined by <xref target="RFC9396"/>. Each identifier is also an audience restriction.</t>
        </dd>
        <dt>
          <tt>actions</tt>
        </dt>
        <dd>
          <t>OPTIONAL. An array of action identifiers understood by the AS and RS.</t>
        </dd>
        <dt>
          <tt>policy_id</tt>
        </dt>
        <dd>
          <t>REQUIRED. A stable identifier for the requested policy and policy epoch.</t>
        </dd>
        <dt>
          <tt>policy_profile</tt>
        </dt>
        <dd>
          <t>REQUIRED. An identifier for the specification that defines canonical tags and policy membership.</t>
        </dd>
        <dt>
          <tt>epoch_id</tt>
        </dt>
        <dd>
          <t>REQUIRED. A string identifying the requested policy epoch.</t>
        </dd>
        <dt>
          <tt>not_before</tt>
        </dt>
        <dd>
          <t>REQUIRED. A non-negative integer NumericDate for the beginning of the requested policy validity interval.</t>
        </dd>
        <dt>
          <tt>expires_at</tt>
        </dt>
        <dd>
          <t>REQUIRED. A non-negative integer NumericDate later than <tt>not_before</tt> for the end of the requested policy validity interval.</t>
        </dd>
        <dt>
          <tt>verification_mode</tt>
        </dt>
        <dd>
          <t>REQUIRED. The value <tt>public</tt> or <tt>private</tt>. Version 1 clients and servers MUST support <tt>public</tt>.</t>
        </dd>
        <dt>
          <tt>private_metadata</tt>
        </dt>
        <dd>
          <t>REQUIRED boolean. <tt>true</tt> requests the private metadata bit; <tt>false</tt> disables it.</t>
        </dd>
        <dt>
          <tt>maximum_uses</tt>
        </dt>
        <dd>
          <t>REQUIRED for <tt>counter-window-v1</tt>. An integer from 1 through 4294967295 limiting the number of independent tags admitted during the policy epoch.</t>
        </dd>
      </dl>
      <t>Unknown members are invalid for this authorization-detail type. Array values MUST NOT be empty or contain duplicates. String comparison follows <xref target="RFC8259"/> without additional Unicode normalization.</t>
      <t>An example authorization detail is:</t>
      <figure>
        <artwork type="json">{
  "type": "policy_based_anonymous_token",
  "locations": ["https://api.example.com"],
  "actions": ["read"],
  "policy_id": "urn:example:policy:daily-read:2026-07-20",
  "policy_profile": "counter-window-v1",
  "epoch_id": "2026-07-20T00:00:00Z/P1D",
  "not_before": 1784505600,
  "expires_at": 1784592000,
  "verification_mode": "public",
  "private_metadata": false,
  "maximum_uses": 10
}</artwork>
      </figure>
      <t>{: artwork-name=PBAT authorization detail}</t>
      <t>The <tt>policy_based_anonymous_token</tt> type is non-enriching: the AS MUST either authorize the exact requested members and values or reject the request with <tt>invalid_authorization_details</tt>. It MUST NOT add, remove, or change a member after authorization. The client repeats the exact <tt>authorization_details</tt> array in the token request as permitted by <xref target="RFC9396"/>. <tt>authorization_details_hash</tt> is the base64url-encoded SHA-256 digest of the UTF-8 JCS serialization of that complete array. The AS MUST NOT issue a policy that grants broader authority or a longer validity interval than the resource owner or grant permits.</t>
      <t>The ciphersuite issuance request is not part of the authorization request. It is created after the AS has authorized the exact authorization details and is sent in the token request as <tt>pbat_issuance_request</tt> (<xref target="issuance"/>). This parameter carries the <tt>issuance_request</tt> output of <tt>Request</tt> and is bound to the authorized policy through the identical public-metadata bytes supplied to both operations.</t>
    </section>
    <section anchor="issuance">
      <name>Issuance at the Token Endpoint</name>
      <t>PBAC issuance is carried on the OAuth token request associated with the selected grant. The request MUST contain the exact <tt>authorization_details</tt> array authorized by the grant. This document defines three additional token-request parameters:</t>
      <dl>
        <dt>
          <tt>pbat_issuance_request</tt>
        </dt>
        <dd>
          <t>REQUIRED for a PBAT token request. A base64url-encoded, ciphersuite-specific <tt>issuance_request</tt> output generated by <tt>Request</tt>. The client MUST retain the corresponding <tt>client_state</tt> locally; it MUST NOT send that state to the AS or RS.</t>
        </dd>
        <dt>
          <tt>pbat_ciphersuite</tt>
        </dt>
        <dd>
          <t>REQUIRED. The identifier of a ciphersuite supported by both the client and AS.</t>
        </dd>
        <dt>
          <tt>pbat_public_metadata</tt>
        </dt>
        <dd>
          <t>REQUIRED. The base64url encoding of the exact public-metadata bytes used to create the issuance request.</t>
        </dd>
      </dl>
      <t>Before invoking <tt>Request</tt>, the client uses the exact authorization detail it will send in the token request, constructs the policy object in <xref target="policy-model"/>, selects a mutually supported ciphersuite and verification mode, and obtains a matching AS key from <tt>pbat_keys_uri</tt>. The selected key MUST remain valid through the policy’s <tt>expires_at</tt> time. The client then constructs the exact public-metadata object, invokes <tt>Request</tt>, and sends the resulting issuance request. The AS and client MUST run their ciphersuite operations over identical metadata bytes.</t>
      <t>The AS MUST compare the <tt>pbat_public_metadata</tt> request parameter with the authorized policy, audience, key identifier, and validity interval. It MUST reject a mismatch. The token response MUST echo the identical byte string.</t>
      <t>After successful authorization, the token response contains:</t>
      <dl>
        <dt>
          <tt>authorization_details</tt>
        </dt>
        <dd>
          <t>REQUIRED by <xref target="RFC9396"/>. The value MUST exactly equal the array in the token request.</t>
        </dd>
        <dt>
          <tt>access_token</tt>
        </dt>
        <dd>
          <t>REQUIRED. The base64url-encoded <tt>issuance_response</tt> output of <tt>Issue(public_parameters, issuance_request, public_metadata, private_bit,   issuer_private_key)</tt>. The client MUST process this value with <tt>Finalize</tt> and its retained <tt>client_state</tt> before storing or using the resulting PBAC. The unfinalized value MUST NOT be sent to an RS.</t>
        </dd>
        <dt>
          <tt>token_type</tt>
        </dt>
        <dd>
          <t>REQUIRED. The case-insensitive value <tt>PBAT</tt>.</t>
        </dd>
        <dt>
          <tt>expires_in</tt>
        </dt>
        <dd>
          <t>RECOMMENDED. The lifetime of the PBAC and its derived PBATs in seconds.</t>
        </dd>
        <dt>
          <tt>pbat_ciphersuite</tt>
        </dt>
        <dd>
          <t>REQUIRED. The selected ciphersuite identifier.</t>
        </dd>
        <dt>
          <tt>pbat_policy</tt>
        </dt>
        <dd>
          <t>REQUIRED. The base64url encoding of the exact UTF-8, JCS-serialized policy object defined in <xref target="policy-model"/>.</t>
        </dd>
        <dt>
          <tt>pbat_public_metadata</tt>
        </dt>
        <dd>
          <t>REQUIRED. The base64url encoding of the exact public-metadata bytes bound by the ciphersuite.</t>
        </dd>
      </dl>
      <t>For example:</t>
      <figure>
        <artwork type="json">{
  "access_token": "base64url(issuance-response)",
  "token_type": "PBAT",
  "expires_in": 1800,
  "authorization_details": [{
    "type": "policy_based_anonymous_token",
    "locations": ["https://api.example.com"],
    "actions": ["read"],
    "policy_id": "urn:example:policy:daily-read:2026-07-20",
    "policy_profile": "counter-window-v1",
    "epoch_id": "2026-07-20T00:00:00Z/P1D",
    "not_before": 1784505600,
    "expires_at": 1784592000,
    "verification_mode": "public",
    "private_metadata": false,
    "maximum_uses": 10
  }],
  "pbat_ciphersuite": "PBAT-EQS-BLS12381-SHA256",
  "pbat_policy": "base64url(policy-bytes)",
  "pbat_public_metadata": "base64url(metadata-bytes)"
}</artwork>
      </figure>
      <t>{: artwork-name=PBAT token response}</t>
      <t>Malformed issuance data, a metadata mismatch, or a policy mismatch produces the token-endpoint <tt>invalid_request</tt> error. A syntactically valid but unsupported ciphersuite produces <tt>unsupported_pbat_ciphersuite</tt>. The AS MUST NOT return an issuance response after either error.</t>
      <t>An AS SHOULD NOT issue a refresh token with a PBAC unless the deployment has defined the privacy consequences. Refresh requests are linkable to the client and can allow the AS to correlate policy epochs. Short-lived PBACs and explicit reauthorization are RECOMMENDED for privacy-sensitive deployments.</t>
    </section>
    <section anchor="policy-model">
      <name>Policy, Tag, and Metadata Model</name>
      <section anchor="policy-requirements">
        <name>Policy Requirements</name>
        <t>A policy profile defines a predicate <tt>Admitted(policy, tag, evaluation_context)</tt> and a canonical tag encoding. It MUST ensure that the set of independently usable tags in a policy epoch is bounded. A profile MUST NOT rely on a client assertion that a counter is within range unless the RS can validate that assertion from the tag, policy, and evaluation context.</t>
        <t>The evaluation context enables policy profiles to use independently available, public information such as current time, a current epoch derived from time, or an authenticated location. A profile that uses such information MUST define its canonical representation, source of truth, clock-skew or freshness rules, and the exact evaluation algorithm. The client MAY form a tag using the same public inputs, but the RS MUST derive or authenticate those inputs independently. In <tt>counter-window-v1</tt>, <tt>epoch_id</tt> is a fixed value bound into the policy and tag; a new time-based epoch requires a new policy and PBAC.</t>
        <t>Every version 1 policy object is a JSON object <xref target="RFC8259"/> containing exactly the following members:</t>
        <dl>
          <dt>
            <tt>policy_id</tt>
          </dt>
          <dd>
            <t>REQUIRED string. An identifier unique within the issuer namespace.</t>
          </dd>
          <dt>
            <tt>issuer</tt>
          </dt>
          <dd>
            <t>REQUIRED string. The AS issuer identifier.</t>
          </dd>
          <dt>
            <tt>audience</tt>
          </dt>
          <dd>
            <t>REQUIRED non-empty array of strings. Each value is an RS identifier.</t>
          </dd>
          <dt>
            <tt>policy_profile</tt>
          </dt>
          <dd>
            <t>REQUIRED string containing a registered policy-profile identifier.</t>
          </dd>
          <dt>
            <tt>epoch_id</tt>
          </dt>
          <dd>
            <t>REQUIRED string identifying the policy epoch.</t>
          </dd>
          <dt>
            <tt>not_before</tt>
          </dt>
          <dd>
            <t>REQUIRED non-negative integer containing a NumericDate in seconds.</t>
          </dd>
          <dt>
            <tt>expires_at</tt>
          </dt>
          <dd>
            <t>REQUIRED non-negative integer containing a NumericDate in seconds and greater than <tt>not_before</tt>.</t>
          </dd>
          <dt>
            <tt>authorization_details</tt>
          </dt>
          <dd>
            <t>REQUIRED array exactly equal to the approved array in the token request and response.</t>
          </dd>
          <dt>
            <tt>authorization_details_hash</tt>
          </dt>
          <dd>
            <t>REQUIRED base64url string equal to SHA-256 over the UTF-8 JCS serialization of the approved <tt>authorization_details</tt> array.</t>
          </dd>
          <dt>
            <tt>parameters</tt>
          </dt>
          <dd>
            <t>REQUIRED object whose members are defined by <tt>policy_profile</tt>.</t>
          </dd>
        </dl>
        <t>The policy is constructed deterministically from the one approved authorization detail. <tt>policy_id</tt>, <tt>policy_profile</tt>, <tt>epoch_id</tt>, <tt>not_before</tt>, and <tt>expires_at</tt> are copied without transformation; <tt>issuer</tt> is the AS issuer identifier; <tt>audience</tt> copies <tt>locations</tt> in its existing array order; <tt>authorization_details</tt> is the complete one-element array; <tt>authorization_details_hash</tt> is computed as specified above; and <tt>parameters.maximum_uses</tt> copies <tt>maximum_uses</tt> for <tt>counter-window-v1</tt>.</t>
        <t>For the authorization detail above, the decoded policy object is:</t>
        <figure>
          <artwork type="json">{
  "policy_id": "urn:example:policy:daily-read:2026-07-20",
  "issuer": "https://as.example.com",
  "audience": ["https://api.example.com"],
  "policy_profile": "counter-window-v1",
  "epoch_id": "2026-07-20T00:00:00Z/P1D",
  "not_before": 1784505600,
  "expires_at": 1784592000,
  "authorization_details": [{
    "type": "policy_based_anonymous_token",
    "locations": ["https://api.example.com"],
    "actions": ["read"],
    "policy_id": "urn:example:policy:daily-read:2026-07-20",
    "policy_profile": "counter-window-v1",
    "epoch_id": "2026-07-20T00:00:00Z/P1D",
    "not_before": 1784505600,
    "expires_at": 1784592000,
    "verification_mode": "public",
    "private_metadata": false,
    "maximum_uses": 10
  }],
  "authorization_details_hash": "&lt;base64url-hash&gt;",
  "parameters": {"maximum_uses": 10}
}</artwork>
        </figure>
        <t>{: artwork-name=PBAT policy object}</t>
        <t>Unknown top-level members MUST be rejected in version 1. The policy is serialized using JCS <xref target="RFC8785"/> and UTF-8. <tt>policy_hash</tt> is the base64url encoding of SHA-256 <xref target="RFC6234"/> over those exact bytes. The ciphersuite binds <tt>policy_hash</tt> through public metadata; a separate signature over the policy object is therefore not required. An RS MUST reject a PBAT if the received policy bytes do not produce the bound <tt>policy_hash</tt>, or if recomputing <tt>authorization_details_hash</tt> from the embedded <tt>authorization_details</tt> array does not produce the stored and bound value.</t>
      </section>
      <section anchor="counter-window-policy-profile">
        <name>Counter-Window Policy Profile</name>
        <t>All version 1 implementations MUST implement the <tt>counter-window-v1</tt> policy profile. For this profile, <tt>parameters</tt> contains exactly one member, <tt>maximum_uses</tt>, whose value is an integer in the range 1 through 4294967295. The profile admits one tag for every integer counter from zero through <tt>maximum_uses - 1</tt>.</t>
        <t>The canonical tag is the UTF-8 JCS serialization of this JSON object:</t>
        <figure>
          <artwork type="json">{
  "counter": 0,
  "epoch_id": "2026-07-20T00:00:00Z/P1D",
  "policy_id": "urn:example:policy:daily-read:2026-07-20"
}</artwork>
        </figure>
        <t>{: artwork-name=Counter-window tag}</t>
        <t>The object contains exactly <tt>counter</tt>, <tt>epoch_id</tt>, and <tt>policy_id</tt>; unknown members are invalid. <tt>counter</tt> MUST be within the admitted interval and the two string members MUST exactly match the policy. The counter is not a secret. A client MUST NOT reuse a counter with the same PBAC and policy epoch, and an RS MUST reject reuse of the resulting logical token.</t>
        <t>Other profiles can bind tags to transactions or action classes. Each such profile MUST be registered, define a finite tag space, specify canonical policy parameters and tags, and state its privacy consequences.</t>
      </section>
      <section anchor="public-metadata">
        <name>Public Metadata</name>
        <t>Public metadata prevents substitution of security-relevant context. Every version 1 public-metadata object contains exactly these members:</t>
        <ul>
          <li>
            <t><tt>iss</tt>: the AS issuer identifier string;</t>
          </li>
          <li>
            <t><tt>aud</tt>: a non-empty array of intended RS identifier strings;</t>
          </li>
          <li>
            <t><tt>policy_id</tt>: the exact policy identifier string;</t>
          </li>
          <li>
            <t><tt>policy_hash</tt>: the base64url-encoded SHA-256 digest of the policy bytes;</t>
          </li>
          <li>
            <t><tt>authorization_details_hash</tt>: the value from the policy object;</t>
          </li>
          <li>
            <t><tt>nbf</tt>: the earliest acceptable redemption time as an integer NumericDate;</t>
          </li>
          <li>
            <t><tt>exp</tt>: the latest acceptable redemption time as an integer NumericDate;</t>
          </li>
          <li>
            <t><tt>key_id</tt>: the AS verification-key identifier string;</t>
          </li>
          <li>
            <t><tt>ciphersuite</tt>: the selected registered ciphersuite identifier;</t>
          </li>
          <li>
            <t><tt>verification_mode</tt>: either <tt>public</tt> or <tt>private</tt>; and</t>
          </li>
          <li>
            <t><tt>private_metadata</tt>: a boolean indicating whether <tt>ReadBit</tt> is required.</t>
          </li>
        </ul>
        <t>For example:</t>
        <figure>
          <artwork type="json">{
  "iss": "https://as.example.com",
  "aud": ["https://api.example.com"],
  "policy_id": "urn:example:policy:daily-read:2026-07-20",
  "policy_hash": "base64url(SHA-256(policy-bytes))",
  "authorization_details_hash": "&lt;base64url-hash&gt;",
  "nbf": 1784505600,
  "exp": 1784592000,
  "key_id": "2026-07-key-1",
  "ciphersuite": "PBAT-EQS-BLS12381-SHA256",
  "verification_mode": "public",
  "private_metadata": false
}</artwork>
        </figure>
        <t>{: artwork-name=PBAT public metadata}</t>
        <t>Unknown members MUST be rejected in version 1. The object is serialized using JCS and UTF-8. The resulting bytes are passed unchanged to the PBAT ciphersuite. The <tt>iss</tt>, <tt>aud</tt>, <tt>policy_id</tt>, <tt>authorization_details_hash</tt>, <tt>nbf</tt>, and <tt>exp</tt> values MUST exactly match the corresponding policy values. String comparison, URI normalization, and audience matching occur before canonicalization according to the specifications that define those fields.</t>
        <t>If <tt>private_metadata</tt> is true, the selected ciphersuite registry entry MUST indicate private-bit support, the AS supplies either zero or one to <tt>Issue</tt>, and the RS invokes <tt>ReadBit</tt>. If it is false, the AS MUST use the ciphersuite’s no-private-metadata issuance path and the RS MUST NOT invoke <tt>ReadBit</tt>.</t>
        <t>Public metadata reduces the effective anonymity set because tokens with different metadata can be distinguished. An AS SHOULD use shared policy and metadata values for sufficiently large client populations and MUST NOT place client-specific identifiers, unique timestamps, or other unnecessary fingerprinting values in public metadata.</t>
      </section>
      <section anchor="private-metadata-bit">
        <name>Private Metadata Bit</name>
        <t>The private metadata bit is OPTIONAL. A ciphersuite supporting it MUST prove to the client that the hidden value is one of exactly two public alternatives. It MUST prevent the AS from embedding a larger covert identifier in the same field.</t>
        <t>Version 1 fixes the semantics: one means that normal RS authorization can continue, and zero means that the RS MUST deny the protected-resource request after otherwise validating the PBAT. The bit is intended only for a binary issuer eligibility decision whose disclosure during issuance would weaken an abuse defense. It MUST NOT encode identity, risk score, action class, or any multi-valued claim. A deployment subject to transparency, explainability, or adverse-action requirements MUST disable the feature unless its use and resulting denial behavior satisfy those requirements.</t>
      </section>
    </section>
    <section anchor="presentation">
      <name>Token Derivation and Presentation</name>
      <t>Before accessing a protected resource, the client:</t>
      <ol>
        <li>
          <t>obtains the exact policy and verifies its integrity;</t>
        </li>
        <li>
          <t>selects a canonical tag admitted by that policy;</t>
        </li>
        <li>
          <t>invokes <tt>Derive</tt> with the PBAC and tag;</t>
        </li>
        <li>
          <t>constructs the version 1 PBAT presentation envelope; and</t>
        </li>
        <li>
          <t>sends the envelope using the <tt>PBAT</tt> HTTP authentication scheme.</t>
        </li>
      </ol>
      <t>The version 1 presentation envelope is a JSON object containing exactly the following members:</t>
      <figure>
        <artwork type="json">{
  "version": 1,
  "ciphersuite": "PBAT-EQS-BLS12381-SHA256",
  "issuer": "https://as.example.com",
  "key_id": "2026-07-key-1",
  "policy": "base64url(policy-bytes)",
  "tag": "base64url(canonical-tag)",
  "public_metadata": "base64url(metadata-bytes)",
  "token": "base64url(token-bytes)",
  "witness": "base64url(witness-bytes)"
}</artwork>
      </figure>
      <t>{: artwork-name=PBAT presentation envelope}</t>
      <t><tt>version</tt> is the integer 1. <tt>ciphersuite</tt>, <tt>issuer</tt>, and <tt>key_id</tt> are strings that exactly match the bound public metadata. <tt>policy</tt>, <tt>tag</tt>, <tt>public_metadata</tt>, <tt>token</tt>, and <tt>witness</tt> are base64url strings containing the exact bytes defined by this document and the selected ciphersuite. Unknown members, duplicate names, non-integer versions, and non-canonical base64url values MUST be rejected.</t>
      <t>The envelope is serialized using JCS and UTF-8. The PBAT presentation value is the unpadded base64url encoding of those bytes. This serialization is deterministic and is the only version 1 presentation encoding.</t>
      <t>The serialized presentation is base64url encoded and sent using the HTTP authentication framework in <xref target="RFC9110"/> as:</t>
      <figure>
        <artwork type="http">Authorization: PBAT &lt;presentation&gt;</artwork>
      </figure>
      <t>{: artwork-name=PBAT authorization header}</t>
      <t>The client and RS MUST use TLS for all requests carrying a PBAT. A client MUST NOT transmit a PBAT in a URI query parameter, form body, cookie, or any header field other than <tt>Authorization</tt>.</t>
      <t>The PBAC, client secret, and issuance transcript MUST NOT be included in the presentation.</t>
      <t>Unless a field specification states otherwise, base64url values in this document use the URL-safe alphabet and omit padding as specified by <xref target="RFC7515"/>.</t>
      <section anchor="pbat-challenge">
        <name>PBAT Authentication Challenge</name>
        <t>An RS that requires a PBAT and receives no usable credentials responds with HTTP status 401 and a <tt>WWW-Authenticate</tt> challenge:</t>
        <figure>
          <artwork type="http">WWW-Authenticate: PBAT realm="example"</artwork>
        </figure>
        <t>{: artwork-name=PBAT challenge}</t>
        <t>The <tt>PBAT</tt> challenge uses the <tt>auth-param</tt> syntax of <xref target="RFC9110"/>. The <tt>realm</tt> parameter is OPTIONAL. The <tt>error</tt>, <tt>error_description</tt>, and <tt>error_uri</tt> parameters have the meanings in <xref target="RFC6750"/>. A challenge MUST NOT contain a parameter more than once. Clients MUST ignore unknown challenge parameters.</t>
        <t>For an invalid, expired, malformed, or replayed PBAT, the RS responds with HTTP status 401 and <tt>error="invalid_token"</tt>. When a valid PBAT does not grant the requested operation, the RS responds with HTTP status 403 and <tt>error="insufficient_scope"</tt>. Error descriptions MUST NOT reveal proof validation details, spent-token state, or the value of a private metadata bit.</t>
      </section>
    </section>
    <section anchor="validation">
      <name>Resource Server Validation</name>
      <t>An RS receiving a PBAT performs the following steps in order:</t>
      <ol>
        <li>
          <t>Parse the presentation using strict, ciphersuite-aware decoding. Reject unknown fields, duplicate fields, invalid base64url, non-canonical encodings, and oversized values.</t>
        </li>
        <li>
          <t>Verify that the <tt>issuer</tt> is trusted and obtain the exact issuer key identified by <tt>key_id</tt>.</t>
        </li>
        <li>
          <t>Verify that the RS is an intended audience and that the current time is within the metadata validity interval.</t>
        </li>
        <li>
          <t>Decode the <tt>policy</tt> member, recompute <tt>policy_hash</tt>, and verify that the policy identifiers, audience, validity interval, and authorization-details hash match the public metadata.</t>
        </li>
        <li>
          <t>Verify that the public metadata matches the envelope and policy and that the approved authorization details permit the requested operation.</t>
        </li>
        <li>
          <t>Construct the policy-profile-defined evaluation context and evaluate <tt>Admitted(policy, tag, evaluation_context)</tt>. If the tag is not admitted, reject the request.</t>
        </li>
        <li>
          <t>Invoke <tt>Verify</tt> for a public ciphersuite or <tt>VerifyPrivate</tt> for a private ciphersuite. Reject an invalid result.</t>
        </li>
        <li>
          <t>If private metadata is enabled, invoke <tt>ReadBit</tt>, retain the returned bit, and reject <tt>invalid</tt>.</t>
        </li>
        <li>
          <t>Atomically check and record spent-token state. If the token has already been accepted in the same issuer, key, policy, and ciphersuite context, reject the request.</t>
        </li>
        <li>
          <t>If the retained private bit is zero, deny the request. Otherwise, authorize only the operation represented by the approved authorization details and local RS policy.</t>
        </li>
      </ol>
      <t>The spent-token check and record operation MUST be atomic. A distributed RS deployment MUST use a consistent replay-detection mechanism or route all presentations in the same replay domain to a common service. Eventual consistency alone can permit simultaneous double spending.</t>
      <t>Error responses use the PBAT challenge rules in <xref target="pbat-challenge"/> and MUST NOT reveal whether failure resulted from the private metadata bit.</t>
    </section>
    <section anchor="verification-modes">
      <name>Verification Modes</name>
      <section anchor="public-verification">
        <name>Public Verification</name>
        <t>In public-verification mode, the RS validates a PBAT using an AS public key. This mode supports AS and RS separation and is RECOMMENDED for cross-domain OAuth deployments. A compromise of an RS verification key does not by itself permit token issuance if the key is public-only.</t>
        <t>Public verification does not mean that all PBAT fields are public, nor does it guarantee that the RS can recover an optional private metadata bit. A ciphersuite specification MUST state whether and how private-bit recovery is available. When private metadata is enabled, the AS provisions any recovery key to the authorized RS through a confidential, authenticated mechanism outside this protocol. A recovery key MUST NOT appear in <tt>pbat_keys_uri</tt> and SHOULD be scoped so that its compromise does not enable token issuance.</t>
      </section>
      <section anchor="private-verification">
        <name>Private Verification</name>
        <t>In version 1 private-verification mode, an RS uses the AS issuance private key as its verification key. This mode can provide better performance, but it creates a stronger trust relationship:</t>
        <ul>
          <li>
            <t>every verifier holding the key can forge or issue acceptable tokens;</t>
          </li>
          <li>
            <t>key distribution increases the compromise surface;</t>
          </li>
          <li>
            <t>isolation between RSs becomes more difficult; and</t>
          </li>
          <li>
            <t>cross-domain deployment requires explicit key-management agreements.</t>
          </li>
        </ul>
        <t>Private verification is therefore NOT RECOMMENDED across independent administrative domains unless the ciphersuite provides verifier-specific keys with appropriate non-forgeability and isolation properties.</t>
      </section>
    </section>
    <section anchor="discovery">
      <name>Discovery and Capability Negotiation</name>
      <t>An AS supporting this protocol advertises the following metadata in its authorization-server metadata document <xref target="RFC8414"/>:</t>
      <dl>
        <dt>
          <tt>pbat_versions_supported</tt>
        </dt>
        <dd>
          <t>REQUIRED array of integers. This specification defines version 1.</t>
        </dd>
        <dt>
          <tt>pbat_ciphersuites_supported</tt>
        </dt>
        <dd>
          <t>Array of supported ciphersuite identifiers.</t>
        </dd>
        <dt>
          <tt>pbat_policy_profiles_supported</tt>
        </dt>
        <dd>
          <t>Array of supported policy-profile identifiers.</t>
        </dd>
        <dt>
          <tt>pbat_verification_modes_supported</tt>
        </dt>
        <dd>
          <t>Array containing <tt>public</tt>, <tt>private</tt>, or both.</t>
        </dd>
        <dt>
          <tt>pbat_keys_uri</tt>
        </dt>
        <dd>
          <t>REQUIRED HTTPS URL of the AS PBAT ciphersuite-key document. Public-mode entries contain verification keys; private-mode entries contain the public issuance material required by the client.</t>
        </dd>
      </dl>
      <t>The three array members after <tt>pbat_versions_supported</tt> are REQUIRED when <tt>pbat_versions_supported</tt> contains 1. An RS advertises the same four metadata members using protected-resource metadata <xref target="RFC9728"/>. It also includes <tt>policy_based_anonymous_token</tt> in <tt>authorization_details_types_supported</tt>.</t>
      <t>For example:</t>
      <figure>
        <artwork type="json">{
  "pbat_versions_supported": [1],
  "pbat_ciphersuites_supported": ["PBAT-EQS-BLS12381-SHA256"],
  "pbat_policy_profiles_supported": ["counter-window-v1"],
  "pbat_verification_modes_supported": ["public"],
  "pbat_keys_uri": "https://as.example.com/.well-known/pbat-keys"
}</artwork>
      </figure>
      <t>{: artwork-name=PBAT capability metadata}</t>
      <t>The key document is a JSON object with a <tt>keys</tt> array. Each entry contains <tt>kid</tt>, <tt>ciphersuite</tt>, <tt>public_key</tt>, <tt>not_before</tt>, <tt>expires_at</tt>, and <tt>status</tt>. <tt>public_key</tt> is an unpadded base64url value whose decoded bytes are defined by the ciphersuite. <tt>status</tt> is either <tt>active</tt> or <tt>revoked</tt>. An AS MUST NOT publish two entries with the same <tt>ciphersuite</tt> and <tt>kid</tt>, and MUST NOT reuse that pair for different key material. Clients and RSs MUST validate the decoded public key using the ciphersuite rules and MUST reject a key outside its advertised validity interval or with status <tt>revoked</tt>. A revoked entry MUST remain published until every policy bound to it has expired.</t>
      <figure>
        <artwork type="json">{
  "keys": [{
    "kid": "2026-07-key-1",
    "ciphersuite": "PBAT-EQS-BLS12381-SHA256",
    "public_key": "base64url(ciphersuite-public-key)",
    "not_before": 1784505600,
    "expires_at": 1787184000,
    "status": "active"
  }]
}</artwork>
      </figure>
      <t>{: artwork-name=PBAT verification-key document}</t>
      <t>The client MUST select a version, ciphersuite, policy profile, and verification mode supported by both the AS and RS. The AS MUST reject an unsupported combination with <tt>unsupported_pbat_ciphersuite</tt> when the ciphersuite is the incompatible element, or <tt>invalid_request</tt> otherwise. It MUST NOT silently substitute a different version, profile, mode, or ciphersuite.</t>
      <t>Discovery metadata is not sufficient to establish trust in a ciphersuite or issuer key. Trust establishment is deployment-specific.</t>
    </section>
    <section anchor="conformance">
      <name>Version 1 Conformance</name>
      <t>An implementation claiming version 1 conformance implements at least one of the AS, client, or RS roles and satisfies all requirements for that role. In addition:</t>
      <ul>
        <li>
          <t>every conforming AS supports the authorization-detail type, token-endpoint parameters, public verification, <tt>counter-window-v1</tt>, the mandatory <tt>PBAT-EQS-BLS12381-SHA256</tt> ciphersuite, and AS discovery metadata;</t>
        </li>
        <li>
          <t>every conforming client supports policy and metadata canonicalization, issuance finalization, counter-window derivation, the mandatory ciphersuite, and the <tt>PBAT</tt> HTTP authentication scheme; and</t>
        </li>
        <li>
          <t>every conforming RS supports protected-resource discovery metadata, strict presentation parsing, public verification with the mandatory ciphersuite, counter-window policy validation, the <tt>PBAT</tt> challenge, and atomic replay detection.</t>
        </li>
      </ul>
      <t>Private verification and the private metadata bit are optional features. An implementation supporting either feature MUST advertise it and implement all corresponding ciphersuite, key-management, error, security, and privacy requirements. Implementing only the abstract ciphersuite interface without a registered ciphersuite does not constitute protocol conformance.</t>
    </section>
    <section anchor="related-work">
      <name>Relationship to Existing Work</name>
      <section anchor="oauth-access-tokens">
        <name>OAuth Access Tokens</name>
        <t>Bearer tokens <xref target="RFC6750"/> are directly reusable until expiry or revocation. A PBAC is not directly presented, and each PBAT is bound to one admitted tag. The PBAT protocol therefore changes token use rather than replacing OAuth’s grant and authorization model. The same separation is applicable to the OAuth 2.1 framework under development <xref target="OAUTH21"/>.</t>
      </section>
      <section anchor="rich-authorization-requests">
        <name>Rich Authorization Requests</name>
        <t>Rich Authorization Requests <xref target="RFC9396"/> express fine-grained authorization requirements. This document uses authorization details to state the authority that is bound into public metadata. RAR does not define anonymous or locally derived access tokens, so the mechanisms are complementary.</t>
      </section>
      <section anchor="resource-indicators">
        <name>Resource Indicators</name>
        <t>Resource indicators <xref target="RFC8707"/> help the AS issue audience-restricted access tokens. PBAT public metadata preserves this restriction for all locally derived tokens.</t>
      </section>
      <section anchor="token-exchange">
        <name>Token Exchange</name>
        <t>OAuth Token Exchange <xref target="RFC8693"/> allows a client to exchange one token for another at an AS. It remains an online issuance operation and is useful for cross-domain and delegation scenarios. PBAT instead permits bounded local derivation after one issuance. A deployment can use token exchange to obtain a PBAC, but the exchange and derivation operations are distinct.</t>
      </section>
      <section anchor="dpop">
        <name>DPoP</name>
        <t>DPoP <xref target="RFC9449"/> sender-constrains an access token to a client key and reduces the utility of a stolen token. It does not provide issuance-redemption unlinkability or bounded local derivation. Applying DPoP directly to PBATs can introduce a stable public key that defeats unlinkability. Any combined profile MUST analyze this correlation risk and SHOULD use per-policy or per-presentation keys where compatible with the ciphersuite.</t>
      </section>
      <section anchor="transaction-tokens">
        <name>Transaction Tokens</name>
        <t>Transaction Tokens <xref target="TXNTOK"/> propagate identity and authorization context among workloads processing a transaction in a trusted domain. PBATs minimize identity disclosure and unlink issuance from redemption. The mechanisms address different trust and privacy goals. A PBAT MUST NOT be treated as a Transaction Token without an explicit profile.</t>
      </section>
      <section anchor="privacy-pass">
        <name>Privacy Pass</name>
        <t>Privacy Pass <xref target="RFC9576"/> defines an architecture for privacy-preserving authorization, an HTTP authentication scheme <xref target="RFC9577"/>, and issuance protocols <xref target="RFC9578"/>. Privacy Pass commonly issues independently redeemable tokens, including batched issuance. PBATs authorize a policy-defined family of deterministic, tag-specific derivations from one credential.</t>
        <t>The standards boundary is fixed as follows. This document owns the OAuth authorization semantics, PBAC issuance binding, PBAT presentation envelope, <tt>PBAT</tt> authentication scheme, policy profiles, and OAuth discovery. Separate PBAT ciphersuite documents own the cryptographic algorithms and receive review from the Privacy Pass and CFRG communities. The <tt>PrivateToken</tt> authentication scheme is not reused because its token challenge and redemption syntax does not carry the policy, tag, and OAuth metadata required here. A ciphersuite document can reuse Privacy Pass primitives when their security properties and wire formats match the PBAT interface.</t>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <section anchor="oauth-security-requirements">
        <name>OAuth Security Requirements</name>
        <t>All deployments MUST follow the OAuth security requirements and current best practices in <xref target="RFC9700"/> and the requirements of the selected grant. In particular, authorization responses need injection and mix-up defenses, redirect URIs require exact matching, public clients use PKCE where applicable, and tokens are audience restricted.</t>
        <t>PBAT does not compensate for a compromised authorization endpoint, malicious redirect URI, weak client authentication, or incorrect resource-owner consent.</t>
      </section>
      <section anchor="theft-of-a-pbac">
        <name>Theft of a PBAC</name>
        <t>A PBAC contains or protects client state capable of deriving multiple PBATs. Its theft can therefore be more serious than theft of one derived PBAT. Clients MUST protect PBACs and derivation secrets at rest and in use. Where available, non-exportable key storage SHOULD be used. Implementations SHOULD erase intermediate issuance state after successful finalization.</t>
      </section>
      <section anchor="replay-and-double-spending">
        <name>Replay and Double Spending</name>
        <t>PBAT derivation makes the logical token deterministic for a tag, but does not by itself prevent repeated presentation. RS replay detection is REQUIRED. Replay keys MUST include sufficient context to prevent cross-issuer, cross-policy, and cross-ciphersuite confusion. Distributed race conditions need to be treated as security failures, not merely accounting errors.</t>
      </section>
      <section anchor="policy-bypass-and-downgrade">
        <name>Policy Bypass and Downgrade</name>
        <t>The policy identifier, epoch, audience, authorization details, ciphersuite, and validity interval MUST be cryptographically bound through public metadata or the ciphersuite transcript. The client and RS MUST reject substitution of a less restrictive policy or weaker ciphersuite.</t>
      </section>
      <section anchor="key-rotation-and-revocation">
        <name>Key Rotation and Revocation</name>
        <t>Version 1 deliberately uses epoch expiry for individual authorization revocation and key status for emergency bulk revocation. The AS MUST bound each policy lifetime according to deployment risk. Setting a key entry’s status to <tt>revoked</tt> invalidates every PBAT under that key; an RS MUST refresh the key document often enough to meet the deployment’s emergency-revocation objective.</t>
        <t>Immediate per-client revocation after issuance is not supported because a revocation handle would enable linkage or require an online call at redemption. Token revocation <xref target="RFC7009"/> can cause a client to delete a PBAC, but cannot identify already derived PBATs to an RS. Online introspection <xref target="RFC7662"/> is therefore outside the version 1 validation path; using it for each presentation defeats the stated unlinkability goal. A deployment that requires immediate per-client revocation MUST use a different access-token profile.</t>
        <t>Privacy-preserving revocation based on cryptographic accumulators is a promising future extension, but is outside version 1 until its protocol, security properties, and interoperability requirements have been specified and independently reviewed.</t>
      </section>
      <section anchor="malicious-issuer">
        <name>Malicious Issuer</name>
        <t>A malicious AS can try to place unique values in policies, metadata, keys, or proof randomness to create a subliminal identifier. Ciphersuite security alone cannot prevent unique public metadata. Clients SHOULD verify that metadata conforms to a shared profile and SHOULD reject unnecessary unique values. A private-bit ciphersuite MUST prove that the hidden choice is one of two allowed values.</t>
      </section>
      <section anchor="malicious-client">
        <name>Malicious Client</name>
        <t>A ciphersuite MUST prevent a client from forging a PBAC, deriving acceptable tokens for tags not admitted by the policy, or generating more independent tokens than allowed. The RS MUST independently validate policy membership; it MUST NOT rely on client-provided authorization claims without cryptographic or policy validation.</t>
      </section>
      <section anchor="cryptographic-agility">
        <name>Cryptographic Agility</name>
        <t>An implementation MUST NOT deploy an unregistered or locally invented ciphersuite without a complete specification and independent review. Group elements, public keys, and proofs MUST be validated before use. Hash functions serving different roles MUST use domain separation. Decoding failures MUST terminate validation without exposing secret-dependent detail.</t>
      </section>
    </section>
    <section anchor="privacy">
      <name>Privacy Considerations</name>
      <section anchor="scope-of-unlinkability">
        <name>Scope of Unlinkability</name>
        <t>PBAT unlinkability concerns cryptographic issuance and presentation transcripts. The AS can know the client during OAuth authorization. The RS sees the source network, timing, requested resource, application behavior, and tag. Cookies, TLS client certificates, stable DPoP keys, application identifiers, and traffic analysis can independently link requests.</t>
        <t>Applications claiming anonymity need to address these higher-layer and network-layer signals.</t>
      </section>
      <section anchor="anonymity-set-partitioning">
        <name>Anonymity Set Partitioning</name>
        <t>Public metadata and policies partition the anonymity set. A unique audience, policy identifier, expiry time, authorization-details hash, or key identifier can make a client distinguishable even if the PBAT construction is secure. ASs SHOULD issue common metadata to groups of clients and SHOULD use coarse expiry values and shared policy epochs.</t>
      </section>
      <section anchor="tag-linkability">
        <name>Tag Linkability</name>
        <t>A tag is visible to the RS and a logical PBAT is deterministic for that tag. Repeated presentations are intentionally linkable so they can be rejected. Tags MUST NOT contain user identifiers or unnecessary application data. Policy profiles SHOULD minimize semantic information in tags while retaining verifiable boundedness.</t>
      </section>
      <section anchor="as-rs-collusion">
        <name>AS-RS Collusion</name>
        <t>A secure ciphersuite aims to prevent an AS and RS from matching a valid PBAT to one issuance transcript. Colluding parties can still correlate unique metadata, authorization timing, IP addresses, policy choices, and application behavior. Privacy claims MUST distinguish cryptographic unlinkability from end-to-end anonymity.</t>
      </section>
      <section anchor="logging-and-telemetry">
        <name>Logging and Telemetry</name>
        <t>AS and RS logs can undo privacy protections. Implementations SHOULD avoid logging complete PBATs, witnesses, issuance requests, or client-specific policy values. Operational metrics SHOULD be aggregated. Retention periods and access controls SHOULD reflect the privacy sensitivity of the data.</t>
      </section>
    </section>
    <section anchor="operations">
      <name>Operational Considerations</name>
      <section anchor="spent-token-storage">
        <name>Spent-Token Storage</name>
        <t>The RS can store a collision-resistant digest of the validated logical token and its issuer, key, policy, and ciphersuite context rather than the full presentation. Storage duration needs to cover the maximum redemption period plus an allowance for clock skew. The digest construction and storage model must not permit offline guessing of low-entropy tokens.</t>
      </section>
      <section anchor="clock-and-epoch-handling">
        <name>Clock and Epoch Handling</name>
        <t>AS and RS clocks need an agreed tolerance. A policy profile MUST define epoch boundaries and behavior near a boundary. A client MUST NOT derive a token for an expired epoch, and the RS MUST reject it even when the PBAC itself has not yet been deleted locally.</t>
      </section>
      <section anchor="failure-handling">
        <name>Failure Handling</name>
        <t>Clients need to treat issuance-finalization failure as a failed token request. They MUST NOT retry with the same client state unless the ciphersuite permits safe retry. AS and RS errors SHOULD be coarse enough not to create an oracle for private metadata or proof internals.</t>
      </section>
      <section anchor="audit">
        <name>Audit</name>
        <t>PBAT intentionally limits correlation between issuance and resource access. Deployments requiring individual attribution for every action need a different token profile or a separate, explicitly consented audit mechanism. Audit requirements MUST be evaluated before selecting PBAT.</t>
      </section>
    </section>
    <section anchor="standards-path">
      <name>Standards-Track Structure and Publication Path</name>
      <t>This document is the version 1 OAuth protocol specification and is intended for publication as a Proposed Standard. It defines all OAuth-visible and HTTP-visible behavior. It is not an Informational framework and does not defer the token representation, verification mode, initial policy profile, or protocol ownership to a future document.</t>
      <t>The cryptographic construction advances as a separate IETF Standards Track companion specification. The initial companion specifies the <tt>PBAT-EQS-BLS12381-SHA256</tt> ciphersuite, based on the publicly verifiable equivalence-class-signature construction in <xref target="PBAT"/>. It defines all group operations, hash functions, zero-knowledge proofs, encodings, validation rules, domain-separation strings, test vectors, and security limits required by <xref target="suite-interface"/>. The companion receives dedicated CFRG review before the two documents complete working-group last call.</t>
      <t>The OAuth document and initial ciphersuite document are publication dependencies and advance together. The intended sequence is:</t>
      <ol>
        <li>
          <t>submit this document and the EQS ciphersuite companion as individual Internet-Drafts;</t>
        </li>
        <li>
          <t>seek OAuth Working Group adoption of this document and Security Area coordination for the ciphersuite companion;</t>
        </li>
        <li>
          <t>complete interoperable implementations and test vectors for issuance, derivation, presentation, and replay rejection;</t>
        </li>
        <li>
          <t>run CFRG cryptographic review of the EQS construction and OAuth review of the authorization and HTTP bindings;</t>
        </li>
        <li>
          <t>conduct coordinated working-group last calls; and</t>
        </li>
        <li>
          <t>request IETF Last Call and IESG publication of both documents as Proposed Standards.</t>
        </li>
      </ol>
      <t>The algebraic-MAC construction in <xref target="PBAT"/> advances only as a later optional private-verification ciphersuite. It does not delay version 1 publication. The zkSNARK construction is excluded from the version 1 standards set. New ciphersuites and policy profiles are added through the registries established by <xref target="iana"/> without changing the OAuth wire protocol.</t>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <section anchor="oauth-access-token-type">
        <name>OAuth Access Token Type</name>
        <t>IANA is requested to register the following value in the OAuth Access Token Types registry:</t>
        <dl>
          <dt>Name:</dt>
          <dd>
            <t>
              <tt>PBAT</tt>
            </t>
          </dd>
          <dt>Additional Token Endpoint Response Parameters:</dt>
          <dd>
            <t><tt>pbat_ciphersuite</tt>, <tt>pbat_policy</tt>, <tt>pbat_public_metadata</tt></t>
          </dd>
          <dt>HTTP Authentication Scheme(s):</dt>
          <dd>
            <t>
              <tt>PBAT</tt>
            </t>
          </dd>
          <dt>Change Controller:</dt>
          <dd>
            <t>IETF</t>
          </dd>
          <dt>Reference:</dt>
          <dd>
            <t>This document</t>
          </dd>
        </dl>
      </section>
      <section anchor="http-authentication-scheme">
        <name>HTTP Authentication Scheme</name>
        <t>IANA is requested to register the following value in the HTTP Authentication Schemes registry:</t>
        <dl>
          <dt>Authentication Scheme Name:</dt>
          <dd>
            <t>
              <tt>PBAT</tt>
            </t>
          </dd>
          <dt>Reference:</dt>
          <dd>
            <t><xref target="presentation"/> and <xref target="pbat-challenge"/> of this document</t>
          </dd>
          <dt>Notes:</dt>
          <dd>
            <t>Carries a policy-based anonymous access-token presentation as a <tt>token68</tt> value.</t>
          </dd>
        </dl>
      </section>
      <section anchor="oauth-parameters">
        <name>OAuth Parameters</name>
        <t>IANA is requested to add the following values to the OAuth Parameters registry. The Change Controller for every entry is IETF and the reference is this document.</t>
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Parameter Usage Location</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>pbat_issuance_request</tt>
              </td>
              <td>token request</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_ciphersuite</tt>
              </td>
              <td>token request, token response</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_public_metadata</tt>
              </td>
              <td>token request, token response</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_policy</tt>
              </td>
              <td>token response</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="oauth-extensions-error">
        <name>OAuth Extensions Error</name>
        <t>IANA is requested to add the following value to the OAuth Extensions Error registry:</t>
        <dl>
          <dt>Name:</dt>
          <dd>
            <t>
              <tt>unsupported_pbat_ciphersuite</tt>
            </t>
          </dd>
          <dt>Usage Location:</dt>
          <dd>
            <t>token endpoint</t>
          </dd>
          <dt>Protocol Extension:</dt>
          <dd>
            <t>OAuth 2.0 Policy-Based Anonymous Access Tokens</t>
          </dd>
          <dt>Change Controller:</dt>
          <dd>
            <t>IETF</t>
          </dd>
          <dt>Reference:</dt>
          <dd>
            <t><xref target="issuance"/> of this document</t>
          </dd>
        </dl>
      </section>
      <section anchor="authorization-server-metadata">
        <name>Authorization Server Metadata</name>
        <t>IANA is requested to add the following values to the OAuth Authorization Server Metadata registry. The Change Controller for every entry is IETF and the reference is <xref target="discovery"/> of this document.</t>
        <table>
          <thead>
            <tr>
              <th>Metadata Name</th>
              <th>Metadata Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>pbat_versions_supported</tt>
              </td>
              <td>JSON array of supported PBAT protocol version integers</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_ciphersuites_supported</tt>
              </td>
              <td>JSON array of supported PBAT ciphersuite identifiers</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_policy_profiles_supported</tt>
              </td>
              <td>JSON array of supported PBAT policy-profile identifiers</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_verification_modes_supported</tt>
              </td>
              <td>JSON array of supported PBAT verification modes</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_keys_uri</tt>
              </td>
              <td>HTTPS URL of the authorization server’s PBAT ciphersuite-key document</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="protected-resource-metadata">
        <name>Protected Resource Metadata</name>
        <t>IANA is requested to add the following values to the OAuth Protected Resource Metadata registry. The Change Controller for every entry is IETF and the reference is <xref target="discovery"/> of this document.</t>
        <table>
          <thead>
            <tr>
              <th>Metadata Name</th>
              <th>Metadata Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>pbat_versions_supported</tt>
              </td>
              <td>JSON array of PBAT protocol version integers accepted by the protected resource</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_ciphersuites_supported</tt>
              </td>
              <td>JSON array of PBAT ciphersuite identifiers accepted by the protected resource</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_policy_profiles_supported</tt>
              </td>
              <td>JSON array of PBAT policy-profile identifiers accepted by the protected resource</td>
            </tr>
            <tr>
              <td>
                <tt>pbat_verification_modes_supported</tt>
              </td>
              <td>JSON array of PBAT verification modes accepted by the protected resource</td>
            </tr>
          </tbody>
        </table>
        <t>The <tt>policy_based_anonymous_token</tt> authorization-detail type is not placed in a new IANA registry. Consistent with <xref target="RFC9396"/>, AS and RS implementations advertise that type through the existing <tt>authorization_details_types_supported</tt> metadata member.</t>
      </section>
      <section anchor="oauth-pbat-ciphersuites-registry">
        <name>OAuth PBAT Ciphersuites Registry</name>
        <t>IANA is requested to create the OAuth PBAT Ciphersuites registry under the OAuth Parameters registry group. Registry entries contain:</t>
        <ul>
          <li>
            <t>ciphersuite identifier;</t>
          </li>
          <li>
            <t>verification mode (<tt>public</tt> or <tt>private</tt>);</t>
          </li>
          <li>
            <t>private metadata bit support (<tt>yes</tt> or <tt>no</tt>); and</t>
          </li>
          <li>
            <t>specification reference.</t>
          </li>
        </ul>
        <t>Ciphersuite identifiers are case-sensitive strings of 1 to 64 characters and match the regular expression <tt>[A-Za-z0-9][A-Za-z0-9._-]{0,63}</tt>. Identifiers beginning with <tt>x-</tt> are reserved for private testing and MUST NOT be registered. The registration policy is IETF Review <xref target="RFC8126"/>. A specification requesting registration MUST satisfy every requirement in <xref target="suite-interface"/>, include test vectors, and document unlinkability, unforgeability, metadata binding, replay-key construction, and implementation limits.</t>
        <t>The initial entry is:</t>
        <table>
          <thead>
            <tr>
              <th>Identifier</th>
              <th>Mode</th>
              <th>Private Bit</th>
              <th>Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>PBAT-EQS-BLS12381-SHA256</tt>
              </td>
              <td>public</td>
              <td>yes</td>
              <td>Companion PBAT EQS ciphersuite specification described in <xref target="standards-path"/></td>
            </tr>
          </tbody>
        </table>
        <t>The OAuth protocol document and the companion ciphersuite document are to be published together. IANA is requested to use the RFC number assigned to the companion document as the final reference for this entry.</t>
      </section>
      <section anchor="oauth-pbat-policy-profiles-registry">
        <name>OAuth PBAT Policy Profiles Registry</name>
        <t>IANA is requested to create the OAuth PBAT Policy Profiles registry under the OAuth Parameters registry group. Registry entries contain a profile identifier, a short description, and a specification reference. Identifiers follow the syntax and private-use rule defined for ciphersuite identifiers. The registration policy is Specification Required <xref target="RFC8126"/>. Designated experts are requested to verify that a profile defines a finite tag space, canonical policy and tag encodings, authorization semantics, and privacy considerations.</t>
        <t>The initial entry is:</t>
        <table>
          <thead>
            <tr>
              <th>Identifier</th>
              <th>Description</th>
              <th>Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>counter-window-v1</tt>
              </td>
              <td>Integer counter window within a bounded policy epoch</td>
              <td><xref target="policy-model"/> of this document</td>
            </tr>
          </tbody>
        </table>
        <t>— back</t>
      </section>
    </section>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>{:numbered=false}</t>
      <t>The authors thank Codrin Ogreanu for his work with David Kretzler and Yong Li on the underlying policy-based anonymous-token framework and constructions. The authors also thank the authors and contributors of the Privacy Pass and OAuth specifications whose work provides the foundation for this proposal.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front>
          <title>RFC2119</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="2119"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>RFC8174</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8174"/>
      </reference>
      <reference anchor="RFC6749" target="https://www.rfc-editor.org/info/rfc6749">
        <front>
          <title>RFC6749</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="6749"/>
      </reference>
      <reference anchor="RFC6750" target="https://www.rfc-editor.org/info/rfc6750">
        <front>
          <title>RFC6750</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="6750"/>
      </reference>
      <reference anchor="RFC7515" target="https://www.rfc-editor.org/info/rfc7515">
        <front>
          <title>RFC7515</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="7515"/>
      </reference>
      <reference anchor="RFC6234" target="https://www.rfc-editor.org/info/rfc6234">
        <front>
          <title>RFC6234</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="6234"/>
      </reference>
      <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/rfc8126">
        <front>
          <title>RFC8126</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8126"/>
      </reference>
      <reference anchor="RFC8259" target="https://www.rfc-editor.org/info/rfc8259">
        <front>
          <title>RFC8259</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8259"/>
      </reference>
      <reference anchor="RFC8414" target="https://www.rfc-editor.org/info/rfc8414">
        <front>
          <title>RFC8414</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8414"/>
      </reference>
      <reference anchor="RFC8707" target="https://www.rfc-editor.org/info/rfc8707">
        <front>
          <title>RFC8707</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8707"/>
      </reference>
      <reference anchor="RFC8785" target="https://www.rfc-editor.org/info/rfc8785">
        <front>
          <title>RFC8785</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8785"/>
      </reference>
      <reference anchor="RFC9396" target="https://www.rfc-editor.org/info/rfc9396">
        <front>
          <title>RFC9396</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9396"/>
      </reference>
      <reference anchor="RFC9700" target="https://www.rfc-editor.org/info/rfc9700">
        <front>
          <title>RFC9700</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9700"/>
      </reference>
      <reference anchor="RFC9728" target="https://www.rfc-editor.org/info/rfc9728">
        <front>
          <title>RFC9728</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9728"/>
      </reference>
      <reference anchor="RFC9110" target="https://www.rfc-editor.org/info/rfc9110">
        <front>
          <title>RFC9110</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9110"/>
      </reference>
      <reference anchor="RFC7009" target="https://www.rfc-editor.org/info/rfc7009">
        <front>
          <title>RFC7009</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="7009"/>
      </reference>
      <reference anchor="RFC7662" target="https://www.rfc-editor.org/info/rfc7662">
        <front>
          <title>RFC7662</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="7662"/>
      </reference>
      <reference anchor="RFC8693" target="https://www.rfc-editor.org/info/rfc8693">
        <front>
          <title>RFC8693</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="8693"/>
      </reference>
      <reference anchor="RFC9449" target="https://www.rfc-editor.org/info/rfc9449">
        <front>
          <title>RFC9449</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9449"/>
      </reference>
      <reference anchor="RFC9576" target="https://www.rfc-editor.org/info/rfc9576">
        <front>
          <title>RFC9576</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9576"/>
      </reference>
      <reference anchor="RFC9577" target="https://www.rfc-editor.org/info/rfc9577">
        <front>
          <title>RFC9577</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9577"/>
      </reference>
      <reference anchor="RFC9578" target="https://www.rfc-editor.org/info/rfc9578">
        <front>
          <title>RFC9578</title>
          <author>
            <organization>IETF</organization>
          </author>
          <date/>
        </front>
        <seriesInfo name="RFC" value="9578"/>
      </reference>
      <reference anchor="OAUTH21" target="https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/">
        <front>
          <title>The OAuth 2.1 Authorization Framework</title>
          <author initials="D." surname="Hardt" fullname="Dick Hardt"/>
          <author initials="A." surname="Parecki" fullname="Aaron Parecki"/>
          <author initials="T." surname="Lodderstedt" fullname="Torsten Lodderstedt"/>
          <date year="2026"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-oauth-v2-1"/>
      </reference>
      <reference anchor="TXNTOK" target="https://datatracker.ietf.org/doc/draft-ietf-oauth-transaction-tokens/">
        <front>
          <title>Transaction Tokens</title>
          <author initials="A." surname="Tulshibagwale" fullname="Atul Tulshibagwale"/>
          <author initials="G." surname="Fletcher" fullname="George Fletcher"/>
          <author initials="P." surname="Kasselman" fullname="Pieter Kasselman"/>
          <date year="2026"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-oauth-transaction-tokens"/>
      </reference>
      <reference anchor="AGENT-AUTHZ" target="https://datatracker.ietf.org/doc/draft-chen-oauth-agent-authz-use-cases/">
        <front>
          <title>Agent Authorization Use Cases and Gap Analysis</title>
          <author initials="J." surname="Chen" fullname="Jia Chen"/>
          <author initials="J." surname="Yao" fullname="Jiankang Yao"/>
          <author initials="M." surname="Chen" fullname="Meiling Chen"/>
          <author initials="Y." surname="Jiang" fullname="Yuning Jiang"/>
          <date year="2026"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-chen-oauth-agent-authz-use-cases"/>
      </reference>
      <reference anchor="PBAT" target="https://eprint.iacr.org/2025/2263">
        <front>
          <title>Completing Policy-based Anonymous Tokens: Private Bits, Public Metadata and more...</title>
          <author initials="D." surname="Kretzler" fullname="David Kretzler"/>
          <author initials="Y." surname="Li" fullname="Yong Li"/>
          <author initials="C." surname="Ogreanu" fullname="Codrin Ogreanu"/>
          <date year="2025"/>
        </front>
      </reference>
      <reference anchor="PBAT-ORIGINAL" target="https://eprint.iacr.org/2025/659">
        <front>
          <title>Scalable and Fine-Tuned Privacy Pass from Group Verifiable Random Functions</title>
          <author initials="D." surname="Faut" fullname="Dennis Faut"/>
          <author initials="J." surname="Hesse" fullname="Julia Hesse"/>
          <author initials="L." surname="Kohl" fullname="Lisa Kohl"/>
          <author initials="A." surname="Rupp" fullname="Andy Rupp"/>
          <date year="2025"/>
        </front>
      </reference>
    </references>
  </back>
</rfc>
