<?xml version="1.0" encoding="utf-8"?><?xml-model href="rfc7991bis.rnc"?><?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>

<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>

<rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="exp" docName="draft-frank-purchase-exchange-format-00" ipr="trust200902" obsoletes="" updates="" submissionType="IETF" xml:lang="en" version="3">

<!-- comments by the author: email is present in IANA Considerations (remove before publishing), front->author (published at bottom under Author's Address) -->

<front>
 <title abbrev="PEF">Purchase Exchange Format (PEF)</title>
 <seriesInfo name="Internet-Draft" value="draft-frank-purchase-exchange-format-00"/>
 <author fullname="Maximilian Josef Frank" initials="M. J." role="editor" surname="Frank"><address>
   <postal><country>Germany</country></postal>
   <email>contact@script4all.com</email>
  </address></author>
 <date year="2022"/>
 <area>General</area>
 <workgroup>Internet Engineering Task Force</workgroup>
 <keyword>media purchase</keyword><keyword>purchase</keyword><keyword>exchange</keyword><keyword>transfer</keyword>
 <abstract><t>This document defines the purchase exchange format (PEF), which consists of signed purchase records, to enable sharing, verification, and transfer of information about license ownership.  This enables sharing of abonnements, rentals, and one-time-purchases across platforms as well as deleting or switching accounts of (media) service providers without loosing or double-purchasing products.  It can also be applied to non-media products.</t></abstract>
</front>

<middle>
 <section><name>Introduction</name>
  <t>The purchase exchange format (PEF) defines the format of signed purchase records, to enable sharing, verification, and transfer of information about license ownership.  This enables to</t>
  <ul>
  <li>simplify and automate digital inheritance or (family) sharing across platforms,</li>
  <li>delete or switch accounts of (media) service providers without loosing purchases (also for data portability or correlation with EU Digital Markets Act),</li>
  <li>save (TV) recordings without storing the actual content,</li>
  <li>offer account-less services through modification, up- and download of purchase exchange formats,</li>
  <li>differentiate between levels e.g. an upgrade is needed for watching a purchased movie in cinema.</li>
  </ul>
  
  <t>When purchasing media like videos, apps, or similar on different platforms, there may be overlapping purchases e.g. free content which is paid at a different streaming service, or subscriptions of different services with overlapping contents or rentals.  By this you would pay multiple times for the same product.  A signed list of purchases being exchanged between the service providers could avoid double-purchase of the same media items, by e.g. lowering the price of a subscription by the amount the media item would cost.  Furthermore it may be a problem to change operating system platforms, if you would have to pay for apps in the new app store again, whereas you already have purchased the same products in the old one.  A signed list of purchases being acknowledged by service providers could tackle this issue, whilst supporting fair competition.</t>

  <section><name>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 <xref target="BCP14"/> when, and only when, they appear in all capitals, as shown here.</t></section>
 </section>

 <section><name>Terminology</name>
  <t>Naming conventions throughout this document of attributes include use for offline or non-media purchases.</t>
  <dl newline="true">
  <dt>Product object</dt><dd>JSON object containing product data</dd>
  <dt>Record</dt><dd>JSON object containing purchase information and a list of product objects</dd>
  <dt>Signed Record</dt><dd>JSON Web Signature (JWS) <xref target="RFC7515"/> containing a record as payload</dd>
  </dl>
 </section>

 <section anchor="Record"><name>Record</name>
  <t>Each record <bcp14>MUST</bcp14> be a JSON object <xref target="RFC8259"/> for later conversion to a JWS payload (see <xref target="Signed.Record"/>).</t>
  <t>The following properties/claims of a record are <bcp14>REQUIRED</bcp14>:</t>
  <dl newline="true">
  <dt>iss</dt><dd>issuer, as defined in <xref target="RFC7519" section="4.1.1"/></dd>
  <dt>iat</dt><dd>timestamp of issuing for bookkeeping and maybe some legal requirements, as defined in <xref target="RFC7519" section="4.1.6"/></dd>
  </dl>
  <t>The following properties of a record are <bcp14>OPTIONAL</bcp14>:</t>
  <dl newline="true">
  <dt>jti</dt><dd>id e.g. to identify the transaction in the seller's bookkeeping, as defined in <xref target="RFC7519" section="4.1.7"/>.  For maintaining uniqueness across records in a simple way it is <bcp14>RECOMMENDED</bcp14> to use URL-style e.g. "seller.example/category/012345".</dd>
  </dl>

  <section><name>Timely Restrictions</name>
   <t>Timely restrictions are useful for rentals or subscriptions of products.  The following properties of a purchase object are <bcp14>OPTIONAL</bcp14>:</t>
   <dl newline="true">
   <dt>nbf</dt><dd>timestamp from when the products are licensed for use, as defined in <xref target="RFC7519" section="4.1.5"/></dd>
   <dt>exp</dt><dd>timestamp when the products' license will expire, as defined in <xref target="RFC7519" section="4.1.4"/></dd>
   <dt>exi</dt><dd>seconds after which the record expires after first use / issuing, e.g. for time-flexible subscriptions or vouchers, as defined in <xref target="RFC9200" section="5.10.3"/></dd>
   </dl>
  </section>

  <section anchor="License.Holder"><name>License Holder</name>
   <t>JWSs can be easily copied.  Thus it is <bcp14>RECOMMENDED</bcp14> to include the license holder into the record.  This is not mandatory to allow for anonymous use of this format.  The following properties of a record are <bcp14>OPTIONAL</bcp14> and to be implemented as defined in <xref target="OpenID.Connect.Core" section="5.1" relative="#StandardClaims"/>:</t>
   <ul>
   <li>name</li>
   <li>given_name</li>
   <li>middle_name</li>
   <li>family_name</li>
   <li>birthdate</li>
   <li>locale</li>
   <li>address</li>
   </ul>
   <t>It is <bcp14>NOT RECOMMENDED</bcp14> to use the address property/claim, as it may be difficult to re-acknowledge/re-issue a signed record after change of address.</t>
   <t>To enable features like family sharing across different service providers, only the property/claim "family_name" <bcp14>MAY</bcp14> be present.</t>
  </section>
 </section>

 <section anchor="Product.Objects"><name>Product Objects</name>
  <t>The <bcp14>REQUIRED</bcp14> property/claim "products" <bcp14>MUST</bcp14> have a JSON array (as defined in <xref target="RFC8259" section="5"/>) as value, containing product objects.  Product objects are JSON objects (see <xref target="RFC8259" section="4"/>) with specific properties as defined in this section.</t>

  <section><name>Identifier "id"</name>
   <t>Each product object <bcp14>MUST</bcp14> have the property "id".  This is a string containing a unique url-style product identifier.  For example "database.example/category/id" may be a valid id.  Each id contains a prefix defining the product type concatenated with the actual value.  Below you can find a list of <bcp14>RECOMMENDED</bcp14> identifiers for each type:</t>

   <dl newline="true">
   <dt>movie</dt><dd>Prefix: https://imdb.com/title/<br/>Identifier: <xref target="IMDb"/> ID<br/>Example: https://imdb.com/title/tt1254207</dd>
   <dt>music</dt><dd>Prefix: isrc://<br/>Identifier: uppercase <xref target="ISRC"/><br/>Example: isrc://AA6Q7-20-00047<br/><br/>or<br/><br/>Prefix: https://isni.org/isni/<br/>Identifier: uppercase <xref target="ISNI"/><br/>Example: https://isni.org/isni/000000012146438X</dd>
   <dt>book</dt><dd>Prefix: isbn://<br/>Identifier: alphanumeric-only <xref target="ISBN"/><br/>Example: isbn://123456789X</dd>
   <dt>app</dt><dd>Prefix: app://<br/>Identifier: application identifier<br/>Example: app://org.example.app</dd>
   </dl>

   <t>With this extendable identifier scheme you can …</t>

   <ul>
   <li>set up your own namespace e.g. if you invent and provide new products you can just use your website as prefix, and </li>
   <li>enable content creators to have product data stored with them and have others just referring to them, which reduces redundancy over the internet.  Example would be a film studio creating movies while storing and updating title, licenses, etc. directly and automatically.</li>
   </ul>
  </section>

  <section><name>Additional Information</name>
   <t>It is <bcp14>RECOMMENDED</bcp14>, but for the sake of brevity not mandatory, to include helpful information as object properties.  This might be necessary if the id prefix is not common, for still being able to identify a product e.g. a movie.  If used, the following properties <bcp14>MUST</bcp14> be used with consistent naming:</t>

   <dl newline="true">
   <dt>title</dt><dd>product title e.g. movie title, song name</dd>
   <dt>year</dt><dd>year of creation</dd>
   <dt>creator</dt><dd>creator of product e.g. the film studio, song author</dd>
   </dl>

   <t>Other properties with the same meaning as one of the keys above <bcp14>MUST NOT</bcp14> use different key names.  This means for example "song-name" is prohibited, because "title" is to be used instead.</t>
  </section>
 </section>

 <section anchor="Signed.Record"><name>Signed Record</name>
  <t>Above record doesn't provide data integrity.  Thus the security of records depend on JSON Web Signatures (JWS) <xref target="RFC7515"/> as their carrier.  A signed record is a JWS with its payload being a representation of the record according to Step 2 of <xref target="RFC7519" section="7.1"/>.  Do not confuse the payload with the actual value of the "payload" property of a JWS.  The more strict specification of a JSON Web Token <xref target="RFC7519"/> is not used to allow for JSON representations of signed records.  It is <bcp14>REQUIRED</bcp14> to use JWSs with asymmetric encryption keys, otherwise signatures couldn't be verified by others without giving up confidentiality of the signature key.  Unsecured JWSs as defined in <xref target="RFC7515" section="2"/> <bcp14>MUST NOT</bcp14> be used.</t>
  <t>To identify the JWSs as signed purchase records, it is <bcp14>RECOMMENDED</bcp14> to set the "typ"-claim to the Content-Type "TBD1" in its compact form as defined in <xref target="RFC7515" section="4.1.9"/>.</t>
 </section>

 <section><name>File Format and Synchronisation</name>
  <t>JWSs and thus signed records are signed by only one entity, because a product is bought from only one seller (single person or group as a whole).  To allow the exchange of multiple purchases bought from each a different seller, the file containing the purchases <bcp14>MUST</bcp14> be in JSON Lines format <xref target="JSON.Lines"/>, and use appropriate file name suffixes (i.e. .jsonl or derivatives through e.g. compression like .json.gz).  There <bcp14>MUST</bcp14> be zero or one signed records on each line.</t>
  <t>Synchronisation <bcp14>MAY</bcp14> be supported by product vendors or services through WebDAV file synchronisation <xref target="RFC4918"/>.  If this method is used, editors <bcp14>MUST</bcp14> take action against synchronisation issues e.g. synchronous writing of two different vendors.  If necessary, the strategy for avoiding collisions <bcp14>MUST</bcp14> be the "merge" method i.e. keeping entries on doubt.</t>
  <t>It is highly <bcp14>RECOMMENDED</bcp14> to restrict file access to read-and-append-only without rewriting the file.  Entries <bcp14>SHALL</bcp14> be terminated by other means than deletion e.g. by expiration timestamps, to allow:</t>

  <ul>
  <li>keeping a history of purchases,</li>
  <li>enable (immutable) streaming of the purchase exchange format line by line (see <xref target="JSON.Lines"/>) with empty lines as connection keep-alive,</li>
  <li>avoid file writing collisions by appending signed records without knowing the file content.</li>
  </ul>
 </section>

 <section anchor="IANA"><name>IANA Considerations</name>
  <section><name>Media Type Registration</name>
   <t>IANA is asked to assign the media type "application/pef" in the "Media Types" registry in the manner described in <xref target="RFC6838"/>, which can be used to identify a JWS as a signed record in purchase exchange format.  The subtype name replaces the placeholder TBD1 as used in <xref target="Signed.Record"/>.</t>
   <ul>
   <li>Type name: application</li>
   <li>Subtype name: pef</li>
   <li>Required parameters: N/A</li>
   <li>Optional parameters: N/A</li>
   <li>Encoding considerations: 8bit; as JWS <xref target="RFC7515"/></li>
   <li>Security considerations: this document <xref target="Security"/></li>
   <li>Interoperability considerations: N/A</li>
   <li>Published specification: this document</li>
   <li>Applications that use this media type: N/A</li>
   <li>Fragment identifier considerations: N/A</li>
   <li><t>Additional information:</t>
    <ul empty="true" spacing="compact">
    <li>Deprecated alias names for this type: N/A</li>
    <li>Magic number(s): N/A</li>
    <li>File extension(s): .jsonl, .ndjson</li>
    <li>Macintosh file type codes: TEXT</li>
    </ul>
   </li>
   <li>Person &amp; email address to contact for further information: Maximilian Josef Frank, contact@script4all.com (REMOVE EMAIL BEFORE PUBLISHING)</li>
   <li>Intended usage: COMMON</li>
   <li>Restrictions on usage: N/A</li>
   <li>Author: Maximilian Josef Frank</li>
   <li>Change controller: Maximilian Josef Frank</li>
   <li>Provisional registration: no</li>
   </ul>
  </section>

  <section><name>Comment on "JSON Web Token Claims" Registry</name>
   <t>As the underlying format of signed records are JWSs instead of JWTs, there is no formal need to register the property/claim "products", containing a list of products for which to prove license-ownership (see <xref target="Product.Objects"/>).</t>
  </section>
 </section>
    
 <section anchor="Security"><name>Security Considerations</name>
  <t>All the security considerations of JSON Web Signatures <xref target="RFC7515"/>, also apply to this specification.</t>

  <section><name>Authorization</name>
   <t>As signed records can be signed by anyone with custom keys, you <bcp14>MUST</bcp14> check its signature for authorization to issue purchases.  For this a root storage of authorized certificates <bcp14>MAY</bcp14> be used in combination with a certificate chain and the "x5c"-claim of JWS as defined in <xref target="RFC7515" section="4.1.6"/>.  These certificates may be used to sign the public keys of the actual product sellers, whose signed keys are used to sign the actual purchase record.</t></section>

  <section><name>License Holder</name>
   <t>If the license holder (see <xref target="License.Holder"/>) is encoded into the record, there may be issues with perfect authentication solely by the license holder information.  Subjects with exactly same names and birthdates could use each other's licenses, if they also possess the signed record.  As both possession of the signed record and knowledge of name and birthdate is required to abuse this circumstance, the risk is deemed to be low.</t>
   <t>Vendors <bcp14>MAY</bcp14> encode additional personal information into a record to strengthen authenticity, while maintaining portability and account-less use of the purchase exchange format.</t></section>
 </section>

 <section anchor="Privacy"><name>Privacy Considerations</name>
  <t>This section uses terms from <xref target="RFC6973"/>.</t>
  <t>It may be possible to create a fingerprint from the list of purchases and their properties (date, seller, etc.).  This could be used to track/identify the user (individual) across services, but also over time on the same service - even though the user uses the service provider's service without an account.  To mitigate this issue, …</t>
  <ul>
  <li>the file containing all signed records <bcp14>MAY</bcp14> be split into multiple files, so that only the relevant signed records are uploaded to the service provider, and</li>
  <li>signed records <bcp14>MAY</bcp14> be re-issued to modify the issuing date in regular intervals to reduce persistent attributes.</li>
  </ul>
 </section>
</middle>

<back>
 <references><name>References</name>
  <references><name>Normative References</name>
   <referencegroup anchor="BCP14" target="https://www.rfc-editor.org/info/bcp14">
    <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.2119.xml"/>
    <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8174.xml"/>
   </referencegroup>
   <reference anchor="IMDb" target="https://imdb.com"><front>
    <title>The Internet Movie Database</title>
    <author><organization>IMDb.com, Inc.</organization></author>
    </front></reference>
   <reference anchor="ISBN" target="https://isbn-international.org"><front>
    <title>International Standard Book Number</title>
    <author><organization>International ISBN Agency</organization></author>
    </front></reference>
   <reference anchor="ISNI" target="https://isni.org"><front>
    <title>International Standard Name Identifier</title>
    <author><organization>ISNI International Agency (ISNI-IA) Ltd.</organization></author>
    </front></reference>
   <reference anchor="ISRC" target="https://isrc.ifpi.org"><front>
    <title>International Standard Recording Code</title>
    <author><organization>International ISRC Agency</organization></author>
    </front></reference>
   <reference anchor="JSON.Lines" target="https://jsonlines.org"><front>
    <title>JSON Lines</title>
    <author fullname="Ian Ward" initials="I." surname="Ward"><organization/></author>
    </front></reference>
   <reference anchor="OpenID.Connect.Core" target="https://openid.net/specs/openid-connect-core-1_0.html"><front>
    <title>OpenID Connect Core v1</title>
    <author><organization>The OpenID Foundation</organization></author>
    <date year="2014"/>
    </front></reference>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.4918.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6838.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.6973.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8259.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.7515.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.7519.xml"/>
   <xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.9200.xml"/>
  </references>
  <references><name>Informative References</name>
  </references>
 </references>
    
 <section><name>Example</name>
  <t>The following example represents a record for the purchase of the movie "Big Buck Bunny" at a fictional service provider called "Media Europe GmbH" on the 1st January 2022 at 00:00:00. The license to watch this movie is shared among the "Doe" family. The purchase is a rental from the time of purchase until the same day at 23:59:59 (inclusive). Please note that per definition the value of "exp" is the next second after the last valid second.</t>
  <figure><name>Example record</name><sourcecode type="json" markers="false"><![CDATA[
{
 "iss":"Media Europe GmbH",
 "iat":1640995200,
 "exp":1641081600, 
 "family_name":"Doe",
 "media":[
  {
   "id":"https://imdb.com/title/tt1254207"
  }
 ]
}
   ]]></sourcecode></figure>
  </section>
 </back>
</rfc>