<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" ipr="trust200902" docName="draft-ietf-jose-json-proof-token-04" submissionType="IETF" category="std" xml:lang="en" indexInclude="true" consensus="true">

<front>
<title abbrev="json-proof-token">JSON Proof Token</title><seriesInfo value="draft-ietf-jose-json-proof-token-04" stream="IETF" status="standard" name="Internet-Draft"/>
<author initials="J." surname="Miller" fullname="Jeremie Miller"><organization>Ping Identity</organization><address><postal><street/>
</postal><email>jmiller@pingidentity.com</email>
</address></author><author initials="M." surname="Jones" fullname="Michael B. Jones"><organization>Self-Issued Consulting</organization><address><postal><street/>
</postal><email>michael_b_jones@hotmail.com</email>
<uri>https://self-issued.info/</uri>
</address></author><author initials="D." surname="Waite" fullname="David Waite"><organization>Ping Identity</organization><address><postal><street/>
</postal><email>dwaite+jwp@pingidentity.com</email>
</address></author><date/>
<area>Internet</area>
<workgroup>jose</workgroup>
<keyword>jose</keyword>
<keyword>zkp</keyword>
<keyword>jwp</keyword>
<keyword>jws</keyword>
<keyword>jpt</keyword>

<abstract>
<t>JSON Proof Token (JPT) is a compact, URL-safe, privacy-preserving representation of claims to be transferred between three parties.  The claims in a JPT are encoded as base64url-encoded JSON objects that are used as the payloads of a JSON Web Proof (JWP) structure, enabling them to be digitally signed and selectively disclosed.  JPTs also support reusability and unlinkability when using Zero-Knowledge Proofs (ZKPs).</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>JSON Proof Token (JPT) is a compact claims representation format intended to be used in the same ways as a JSON Web Token (JWT), but with additional support for selective disclosure and unlinkability.  JPTs encode claim values to be transmitted as payloads of a JSON Web Proof (JWP) <xref target="I-D.ietf-jose-json-web-proof"/>.  JPTs are always represented using the JWP Compact Serialization.  The corresponding claim names are not transmitted in the payloads and are stored in a separate structure that can be externalized and shared across multiple JPTs.</t>
<blockquote><t>Editor's Note: This draft is still early and incomplete. There will be significant changes to the algorithms as currently defined here.  Please do not use any of these definitions or examples for anything except personal experimentation and learning.  Contributions and feedback are welcomed at <eref target="https://github.com/json-web-proofs/json-web-proofs">https://github.com/json-web-proofs/json-web-proofs</eref>.</t>
</blockquote></section>

<section anchor="conventions-and-definitions"><name>Conventions and Definitions</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="background"><name>Background</name>
<t>JWP defines a container binding together a protected header, one or more payloads, and a cryptographic proof.  It does not define how claims are organized into payloads and what formats they are in.  JPTs are intended to be as close to a JWT as possible, while also supporting the selective disclosure and unlinkability of JWPs.</t>
</section>

<section anchor="design-considerations"><name>Design Considerations</name>
<t>The rationale behind the design for JSON Proof Tokens is important when considering how it is structured.  These sections detail the underlying reasoning informing the JPT design.</t>

<section anchor="unlinkability"><name>Unlinkability</name>
<t>Supporting unlinkability is perhaps the most challenging design constraint for JPTs.  Even the smallest oversight can introduce a subtle vector for relying parties to collude and correlate one or more subjects across their usage.</t>
<t>The principal tools to prevent this are data minimization and uniformity.  The data included in a JPT SHOULD be minimized to remove potential correlation points. The data SHOULD contain only values that are able to be selectively disclosed with consent or transformed by the proof algorithm when presented.</t>
<t>Any other data that is repeated across multiple JPTs is externalized so that it is uniform across every issuance.  This includes preventing the usage of optional headers, dynamic mapping of claims to payloads, changes to how many payloads are included, and the ordering of the payloads.</t>
</section>

<section anchor="selective-disclosure"><name>Selective Disclosure</name>
<t>While JWPs provide the underling structure for easily supporting selective disclosure, JPTs must go a step further to ensure that holders can effectively provide choice and consent on exactly what is being disclosed.  Software using JWPs MUST know the mappings from payloads to claims. All disclosed payloads MUST be mapped to claims and made accessible to the application.  Holders SHOULD understand the semantics of all potentially disclosed claims to the extent needed to decide whether to disclose them. JPTs SHOULD NOT contain claims that are intended only for a specific verifier.</t>
</section>

<section anchor="familiarity"><name>Familiarity</name>
<t>JPTs are intended to be as close to a JWT as possible in order to provide the simplest transition for any JWT-based system to add support for JPTs.</t>
<t>Although there are some stark differences in the lifecycle of a JPT, from the application's perspective, the interface to a JPT can be made fairly similar: a JSON object containing a mix of required and optional claims with well-understood values.</t>
<t>The most significant divergence required by JPTs is that of supporting values that may be disclosed or may instead only be a proof about the value.  Applications are required to interact with the JPT on a payload-by-payload basis instead of just verifying a JWT and then being able to interact with the JSON body directly.</t>
</section>

<section anchor="proofs"><name>Proofs</name>
<t>To generate a variety of efficient ZKPs of knowledge, range, membership, or other predicates, it is essential that each individual payload is only a single claim value.  This greatly simplifies the task of linking a derived proof of a given claim to the specific payload that was also signed by the issuer.  While JPTs support claims that have complex object or array compound values, they also allow for simple claim values such as JSON strings, numbers, and booleans that can be used directly in generating predicate proofs.</t>
</section>
</section>

<section anchor="claim-names"><name>Claim Names</name>
<t>It is RECOMMENDED that the claim names used with JPTs come from those in the IANA JSON Web Token Claims Registry <xref target="IANA.JWT.Claims"/> established by <xref target="RFC7519"/>, when those fit the application's needs.</t>
</section>

<section anchor="claims"><name>Claims</name>
<t>A JSON Proof Token assigns each playload a claim name. Payloads MUST each have a negotiated and understood claim name within the application context. The simplest solution to establish payload claim names is as an ordered array that aligns with the included payloads.  This claims array can be conveniently included in the Issuer Protected Header using the <tt>claims</tt> key.</t>
<t>All payloads are claim values and MUST be the base64url encoding of the UTF-8 representation of a JSON value.
That said, predicate proofs derived from payload values are not represented as claims;
they are contained in the presentation proof using algorithm-specific representations.</t>
<t>The following is an example JWP Issuer Protected Header that includes a claims property:</t>

<sourcecode type="json"><![CDATA[{
  "kid": "HjfcpyjuZQ-O8Ye2hQnNbT9RbbnrobptdnExR0DUjU8",
  "alg": "BBS",
  "claims": [
    "iat",
    "exp",
    "family_name",
    "given_name",
    "email",
    "address",
    "age_over_21"
  ]
}
]]>
</sourcecode>
<t>In this example, the "iat" and "exp" would be JSON-formatted numbers, "family_name", "given_name" and "email" would be JSON strings (in quotes), "address" would be a JSON object and "age_over_21" would be expected to be either <tt>true</tt> or <tt>false</tt>.</t>
<t>When the claims array is transferred as a property in the Issuer Protected Header, any variations of that array between JWP will be visible to the verifier, and can leak information about the subject or provide an additional vector for linkability.  Given the privacy design considerations around linkability, it is RECOMMENDED that the claims are defined external to an individual JPT and either referenced or known by the application context.</t>
<t>To facilitate this external definition of the claim names, an additional <tt>cid</tt> key is defined with a required digest value calculated as defined here.  This <tt>cid</tt> can be used similar to a <tt>kid</tt> in order to ensure that is it possible to externally resolve and then verify that the correct list of claim names is being used when processing the payloads containing the claim values.</t>
<t>If there is an associated JWK containing the signing key information, the <tt>claims</tt> key is also registered there as a convenient location for the claim names.</t>
<t>The following is an example JWP Protected Header that includes a <tt>cid</tt>:</t>

<sourcecode type="json"><![CDATA[{
  "kid": "HjfcpyjuZQ-O8Ye2hQnNbT9RbbnrobptdnExR0DUjU8",
  "alg": "BBS",
  "cid": "guA8PAI14Gkn4273f1rR606yMbRMFg4y"
}
]]>
</sourcecode>
</section>

<section anchor="payloads"><name>Payloads</name>
<blockquote><t>Editor's Note: This section is incomplete. Use it only as an indicator of the intended direction.</t>
</blockquote><t>Application resolves each claim as required when processing the JPT.  Resolution can result in one of three things:
1. A disclosed JSON value
2. A custom proof method
3. A <tt>null</tt> value</t>

<section anchor="disclosed"><name>Disclosed</name>
<t>Always an octet string of valid JSON text.</t>
</section>

<section anchor="proof-methods"><name>Proof Methods</name>

<ul spacing="compact">
<li>proof methods can be returned instead of a disclosed payload</li>
<li>these are generated by the algorithm from information in the JWP's proof value</li>
<li>a proof method may be custom based on the capabilities of the algorithm</li>
<li><t>define common proof method types available?</t>

<ul spacing="compact">
<li>range</li>
<li>membership</li>
<li>time</li>
<li>knowledge</li>
<li>linking</li>
</ul></li>
</ul>
</section>
</section>

<section anchor="example-jpt"><name>Example JPT</name>
<t>See the <xref target="I-D.ietf-jose-json-web-proof"/> appendix.</t>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>

<ul spacing="compact">
<li>Protected Header Minimization</li>
</ul>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>This document has no IANA actions.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-jose-json-web-proof.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
</references>
<references><name>Informative References</name>
<reference anchor="IANA.JWT.Claims" target="https://www.iana.org/assignments/jwt">
  <front>
    <title>JSON Web Token Claims</title>
    <author>
      <organization>IANA</organization>
    </author>
    <date/>
  </front>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
</references>
</references>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>This work was incubated in the DIF <eref target="https://identity.foundation/working-groups/crypto.html">Applied Cryptography Working Group</eref>.</t>
<t>We would like to thank
Brent Zundel
for his valuable contributions to this specification.</t>
</section>

<section anchor="document-history"><name>Document History</name>
<t>[[ To be removed from the final specification ]]</t>
<t>-04</t>

<ul spacing="compact">
<li>Refactoring figures and examples to be built from a common set across all three documents</li>
</ul>
<t>-03</t>

<ul spacing="compact">
<li>Improvements resulting from a full proofreading.</li>
<li>Added examples of JSON object and JSON boolean claims.</li>
</ul>
<t>-02</t>

<ul spacing="compact">
<li>Update example to use the current BBS algorithm</li>
</ul>
<t>-01</t>

<ul spacing="compact">
<li>Correct cross-references within group.</li>
</ul>
<t>-00</t>

<ul spacing="compact">
<li>Created initial working group draft based on draft-jmiller-jose-json-proof-token-01</li>
</ul>
</section>

</back>

</rfc>
