<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-lemmons-cose-composite-claims-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" consensus="true">

<front>
<title abbrev="Composite Token Claims">Composite Token Claims</title><seriesInfo value="draft-lemmons-cose-composite-claims-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="C." surname="Lemmons" fullname="Chris Lemmons"><organization>Comcast</organization><address><postal><street></street>
</postal><email>chris_lemmons@comcast.com</email>
</address></author><date/>
<area>Security</area>
<workgroup>COSE WG</workgroup>

<abstract>
<t>Composition claims are CBOR Web Token claims that define logical relationships
between sets of claims and provide for private claim values via encryption.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>Composition claims are claims defined for CBOR Web Tokens (CWTs) <xref target="RFC7519"></xref>.
These claims include logical operators &quot;or&quot;, &quot;nor&quot;, and &quot;and&quot; as well as a
wrapper that encrypts the values, but not the keys, of some claims.</t>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;,
&quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this
document are to be interpreted as described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when,
and only when, they appear in all capitals, as shown here.</t>
<t>This document reuses terminology from CWT <xref target="RFC7519"></xref> and COSE <xref target="RFC9052"></xref>.</t>
<t>This term is defined by this specification:</t>

<dl spacing="compact">
<dt>Composition Claim</dt>
<dd>A composition claim is a CWT claim that contains, as part of its value, one
or more CWT claim sets.</dd>
</dl>
</section>

<section anchor="claims"><name>Claims</name>
<t>Composition claims contain one or more claim sets.</t>
<t>In CWTs without composition claims, there is exactly one set of claims, so the
acceptability of the claim set decides the acceptability of the CWT. However,
this document defines multiple sets of claim sets, so it instead refers to
accepting or rejecting claim sets. If the primary claim set is unacceptable,
the CWT is unacceptable and <bcp14>MUST</bcp14> be rejected.</t>
<t>Some applications use tokens to convey information. For example, a token might
simply have a subject claim that identifies the bearer and the relying party
simply uses that as information, not necessarily as a means by which to provide
or deny access or make some other kind of decision. In this context, the token
simply describes all situations in which the token would accurately describe
that situation. That is to say, the token describes the set of contexts in
which it would be acceptable.</t>
<t>Composition claims can be nested to an arbitrary level of depth.
Implementations <bcp14>MAY</bcp14> limit the depth of composition nesting by rejecting
CWTs with too many levels but <bcp14>MUST</bcp14> support at least four levels of nesting.</t>

<section anchor="logical-claims"><name>Logical Claims</name>
<t>These claims identify one or more sets of claims in a logical relation. The
type of these claims is array and the elements of the array are maps that are
themselves sets of claims.</t>
<t>For the following CDDL, <tt>Claims-Set</tt> is a map of claims as defined in
<xref target="RFC8392"></xref>. It is described informatively in [draft-ietf-rats-eat] Appendix D.</t>

<section anchor="or-or-claim"><name>or (Or) Claim</name>
<t>The &quot;or&quot; (Or) claim identifies one or more sets of claims of which at least one
is acceptable. If every set of claims in an &quot;or&quot; claim would, when considered with
all the other relevant claims, result in the claim set being rejected, the
claim set containing the &quot;or&quot; claim <bcp14>MUST</bcp14> be rejected.</t>
<t>Use of this claim is <bcp14>OPTIONAL</bcp14>. The Claim Key [add key number] is used to
identify this claim.</t>
<t>The &quot;or&quot; (OR) claim is described by the following CDDL:</t>

<sourcecode type="cddl">$$Claims-Set-Claims //= ( or-claim-label =&gt; or-claim-value )
or-claim-label = TBD
or-claim-value = [ + Claims-Set ]
</sourcecode>
</section>

<section anchor="nor-not-or-claim"><name>nor (Not Or) Claim</name>
<t>The &quot;nor&quot; (Nor) claim identifies one or more sets of claims of which none are
acceptable. If any set of claims in a &quot;nor&quot; claim would, when considered with all
other relevant claims, result in the claim set being accepted, the claim set
containing the &quot;nor&quot; <bcp14>MUST</bcp14> be rejected.</t>
<t>This is the logical negation of the &quot;or&quot; claim.</t>
<t>Use of this claim is <bcp14>OPTIONAL</bcp14>. The Claim Key [add key number] is used to
identify this claim.</t>
<t>The &quot;nor&quot; (NOR) claim is described by the following CDDL:</t>

<sourcecode type="cddl">$$Claims-Set-Claims //= ( nor-claim-label =&gt; nor-claim-value )
nor-claim-label = TBD
nor-claim-value = [ + Claims-Set ]
</sourcecode>
</section>

<section anchor="and-and-claim"><name>and (And) Claim</name>
<t>The &quot;and&quot; (And) claim identifies one or more sets of claims of which all are
acceptable. If any claim in an &quot;and&quot; claim would, when considered with all other
relevant claims, result in the claim set being rejected, the claim set
containing the &quot;and&quot; claim <bcp14>MUST</bcp14> be rejected.</t>
<t>The &quot;and&quot; claim is often unnecessary because a given claim set is only accepted
when all its claims are acceptable. However, CBOR maps cannot have duplicate
keys, so claims cannot be repeated more than once. The &quot;and&quot; claim is useful
for claims that may be claimed multiple times, including the &quot;or&quot; and &quot;nor&quot;
claims.</t>
<t>Use of this claim is <bcp14>OPTIONAL</bcp14>. The Claim Key [add key number] is used to
identify this claim.</t>
<t>The &quot;and&quot; (AND) claim is described by the following CDDL:</t>

<sourcecode type="cddl">$$Claims-Set-Claims //= ( and-claim-label =&gt; and-claim-value )
and-claim-label = TBD
and-claim-value = [ + Claims-Set ]
</sourcecode>
</section>

<section anchor="examples"><name>Examples</name>
<t>These logical claims can be used to describe more complex relationships between
claims. For example, the following claim set describes a token with multiple
subject claims. This token describes a situation where either of the two
subjects must be true, but the issuer is not disclosing which one must be true
or even whether the two subjects are genuinely different.</t>

<artwork>{
  /or/ TBD: [
    { /sub/ 2: &quot;george@example.net&quot; },
    { /sub/ 2: &quot;harriet@example.net&quot; }
  ]
}
</artwork>
<t>A relying party that receives this token does not know if the bearer is George
or Harriet, but it knows that the bearer is one of them.</t>
<t>The &quot;nor&quot; claim is useful both as a logical negation, even when only one claim
is present. For example, consider the following claim set:</t>

<artwork>{
  /nor/ TBD: [
    { /aud/ 3: &quot;https://example.com&quot; }
  ]
}
</artwork>
<t>This token is intended for any audience except &quot;example.com&quot;.</t>
<t>Complex relationshops can also be described using the claims in combination.
The &quot;geohash&quot; claim <xref target="CTA5009A"></xref> describes a geographical region. For example:</t>

<artwork>{
  { /aud/ 3: &quot;https://example.com&quot; },
  { /geohash/ 282: &quot;9q8yy&quot; },
  { /nor/ TBD: [
      { /geohash/ 282: [&quot;9q8yy9&quot;, &quot;9q8yyd&quot;] }
    ]
  }
}
</artwork>
<t>This token describes an audience of &quot;<eref target="https://example.com&quot;">https://example.com"</eref> and a region
described by the geohash of &quot;9q8yy&quot; that does not include the region described
by &quot;9q8yy9&quot; or &quot;9q8yyd&quot;.</t>
<t>And if a very complex relationship is required, the &quot;and&quot; claim can be used to
combine multiple claims. For example, consider the following claim set:</t>

<artwork>{
  /and/ TBD: [
    {
      /or/ TBD: [
        { /sub/ 2: &quot;george@example.net&quot; },
        { /sub/ 2: &quot;harriet@example.net&quot; }
      ]
    },
    {
      /or/ TBD: [
        { /aud/ 3: &quot;https://example.com&quot; },
        { /aud/ 3: &quot;https://example.net&quot; }
      ]
    }
  ]
}
</artwork>
<t>This admittedly contrived example describes a token that is valid for either
George or Harriet and is intended for either <eref target="https://example.com">https://example.com</eref> or
<eref target="https://example.net">https://example.net</eref>. It is a bit contrived because the &quot;aud&quot; claim already
describes a list of acceptable audiences. The use of the &quot;and&quot; claim is
required in order to effectively repeat the &quot;or&quot; claim, because a single claim
set cannot contain the same claim twice.</t>
</section>
</section>

<section anchor="enveloped-claims"><name>Enveloped Claims</name>
<t>Enveloped claims identify a set of claims that should be considered as part of a
set of claims, but that require decryption before they can be processed. This
is sometimes useful when some processors do not need to evaluate some claims in
order to determine if a claim set is acceptable.</t>

<section anchor="env-enveloped-claim"><name>env (Enveloped) Claim</name>
<t>The &quot;env&quot; (Enveloped) claim allows an issuer to make private claims that cannot
be read by a processor that does not possess the decryption key. The type of
this claim is a map; the keys of the map are either claim keys (string,
unsigned integer, or negative integer) or arrays of claim keys; the values of
the map are COSE_Encrypt or COSE_Encrypt0 objects, as defined by
<xref target="RFC9052" sectionFormat="of" relative="#" section="5"></xref>. The plaintext of the Enveloped Message is either a CBOR
data item or a CBOR array of data items.</t>
<t>Each element of the map is interpreted as follows:</t>

<ul spacing="compact">
<li>If the key is a claim key, the plaintext of the Enveloped Message in its
value is a CBOR data item that is appropriate as a value for that claim.</li>
<li>If the key is an array of claim keys, the plaintext of the Enveloped
Message in its value is an array with the cardinality equal to or larger
than the array of claim keys. Each member of the array in the plaintext
corresponds with the member in the array in the key with the same index.
Elements of the value array with indexes that do not correspond with
elements of the key array MUST be ignored. The members of the array in the
plaintext are CBOR data items that are appropriate as values for the
corresponding claim. The array of claim keys <bcp14>MUST</bcp14> contain at least one
element.</li>
</ul>
<t>These claims described in the &quot;env&quot; claim <bcp14>MAY</bcp14> be processed exactly as
though the &quot;env&quot; claim were replaced with the decrypted claims, including the
limitation that a map of claims is invalid if it contains a claim more than
once. The &quot;env&quot; claim is removed from the map before looking for duplicates, so
an &quot;env&quot; claim that contains an &quot;env&quot; claim may potentially be accepted. An
invalid claim set <bcp14>MUST</bcp14> be rejected. A claim set that contains
duplicate claims <bcp14>MUST</bcp14> be rejected, even if the duplicates are not
decrypted.</t>
<t>Since claims are optionally decrypted and added as sibling claims, issuers can
ensure that this occurs by adding them to the &quot;crit&quot; claim. In the absence of a
&quot;crit&quot; claim, the relying party <bcp14>MAY</bcp14> choose not to decrypt the claims.
Indeed, a relying party may not even have the decryption key for claims that
are not relevant to its processing.</t>
<t>Use of this claim is <bcp14>OPTIONAL</bcp14>. The Claim Key [add key number] is used to
identify this claim.</t>
</section>

<section anchor="crit-critical-claim"><name>crit (Critical) Claim</name>
<t>The &quot;crit&quot; (Critical) claim lists the claims required to process this token.</t>
<t>The type of this claim is array and the elements of the array are strings,
negative integers, or unsigned integers. The elements of the array correspond
to claims that MUST be present in the token.</t>
<t>If a claim listed in the &quot;crit&quot; claim is present in a claim set and the
processor cannot process the claim for any reason, the claim set <bcp14>MUST</bcp14> be
rejected.</t>
<t>If a claim listed in the &quot;crit&quot; claim is not present in a claim set, the claim
set <bcp14>MUST</bcp14> be rejected.</t>
<t>If a claim listed in the &quot;crit&quot; claim is present in a claim set as part of an
&quot;env&quot; claim (and, should it be decrypted, be processed as a sibling of that
&quot;env&quot; claim), if the value of the claim is not decrypted (for any reason) and
processed and any possible value of the claim would result in the request being
rejected, the claim set <bcp14>MUST</bcp14> be rejected. Since any processor <bcp14>MAY</bcp14>
decrypt or not decrypt claim values in a &quot;env&quot; claim, this means a processor
<bcp14>MAY</bcp14> reject any claim set that contains a claim that could have a value that
would require rejection.</t>
<t>If a &quot;crit&quot; claim is present in a claim set, a processor <bcp14>SHOULD</bcp14> consider
claims it does not understand to be acceptable if they are not present in the
&quot;crit&quot; claim, unless application-specific processing defines otherwise. That
is, when a &quot;crit&quot; claim is present, any claims not listed may by default be
assumed to be non-critical.</t>
<t>Use of this claim is <bcp14>OPTIONAL</bcp14>. The Claim Key [add key number] is used to
identify this claim.</t>
</section>

<section anchor="example"><name>Example</name>
<t>Consider a very simple token that might be passed like this:</t>

<artwork>{
  /iss/ 1: &quot;https://example.com&quot;,
  /sub/ 2: &quot;george@example.net&quot;,
  /aud/ 3: &quot;https://example.com&quot;
}
</artwork>
<t>The identity of George is present and clear in the token. Some parties
receiving this token might need to know that George is the subject. However,
some may not. For example:</t>

<ul spacing="compact">
<li>An intermediary proxy that only needs to know that the issuer is
<eref target="https://example.com">https://example.com</eref> and the audience is <eref target="https://example.com">https://example.com</eref>.</li>
<li>An origin behind the proxy that needs to know that George is the subject as
well, so that it can customize its response.</li>
</ul>
<t>The intermediary is a relying party but does not need to know George's
identity. The origin, however does. A token that permits this might look like
this:</t>

<artwork>{
  /iss/ 1: &quot;https://example.com&quot;,
  /aud/ 3: &quot;https://example.com&quot;,
  /env/ TBD: {
    [/sub/ 2]: [
      h'&lt;cose-protected-header&gt;',
      h'&lt;cose-unprotected-header&gt;',
      h'&lt;cose-ciphertext&gt;'
    ]
  }
}
</artwork>
<t>And the contents of the ciphertext might be:</t>

<artwork>[&quot;george@example.net&quot;, h'b73814740f877e8aa691fdab6cda']
</artwork>
<t>The intermediary can process the token without decrypting the &quot;env&quot; claim. The
origin can decrypt the &quot;env&quot; claim and learn that George is the subject. The
issuer used additional padding in the plaintext in order to avoid disclosing
the length of the subject value.</t>
</section>

<section anchor="profiling-the-env-claim"><name>Profiling the &quot;env&quot; Claim</name>
<t>The &quot;env&quot; claim is only useful when the issuer can reliably expect a relying
party that needs to understand the claim to be able to decrypt it. This
document does not specify several important required details:</t>

<ul spacing="compact">
<li>How the issuer and relying party establish trust.</li>
<li>How the issuer conveys the decryption key to the relying party.</li>
<li>How the issuer and relying party agree on the supported ciphers.</li>
</ul>
<t>These details are of necessity left to the application profile, since they will
vary between applications. The &quot;crit&quot; claim can be used to ensure that the
relying party knows which claims are encrypted and must be decrypted.</t>
</section>

<section anchor="other-methods-of-selectively-disclosing-claims"><name>Other methods of selectively disclosing claims</name>
<t>The &quot;env&quot; claim is only suitable for protecting claims under the following
circumstances:</t>

<ul spacing="compact">
<li>The issuer is the one that decides which claims are disclosed and to whom.</li>
<li>The issuer can reasonably pad the plaintext to avoid revealing the length of
the claim. This requires the issuer to know the maximum length of claims that
might be present.</li>
<li>The bearer does not need to control which claims are disclosed.</li>
<li>The claim labels are not sensitive information.</li>
</ul>
<t>If these are not the case, the &quot;env&quot; claim is not suitable. If the bearer is
the one that controls selective disclosure,
[draft-ietf-oauth-selective-disclosure-08] may be more appropriate. SD-JWTs
also protect the claim labels, which the &quot;env&quot; claim does not.</t>
<t>When the claims for different audiences are significantly different, multiple
encrypted tokens can be used. This is likely to lead to larger sets of tokens
in general, but is a very flexible approach. This protects the entire contents
of each token from all parties that do not possess the decryption key for that
token.</t>
</section>
</section>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>All security considerations relevant to CWTs in general will apply to CWTs that
use composition claims.</t>
<t>Additionally, processors of CWTs with composition claims will need to be aware
of the possibility of receiving highly nested tokens. Excessive nesting can
lead to overflows or other processing errors.</t>
<t>The security of the &quot;env&quot; claim is subject to all the considerations detailed
for COSE objects in <xref target="RFC9052" sectionFormat="of" relative="#" section="12"></xref>. Particular attention is required
to length attacks. If the length of the Enveloped Claims is revealing as to its
contents, as it most often will be in this context, issuers MUST pad the
content appropriately in order to maintain the secrecy of its contents. &quot;env&quot;
claims permit additional elements to be added after arrays of claim keys that
can be used for padding when it is required.</t>
<t>Since the &quot;env&quot; claim only encrypts the contents of the claim and not its key,
it discloses the presence of a given claim. When this is undesirable, another
composite claim like &quot;and&quot;, &quot;or&quot;, or even potentially &quot;env&quot; can be be used to
mask the presence of the claim within.</t>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>This specification requests that IANA register the following claim keys in the
&quot;CBOR Web Token (CWT) Claims&quot; registry established by <xref target="RFC8392"></xref>:</t>
<t>Claim Name: or
Claim Description: Logical OR
JWT Claim Name: N/A
Claim Key: TBD (greater than 285)
Claim Value Type(s): array
Change Controller: IETF</t>
<t>Claim Name: nor
Claim Description: Logical NOR
JWT Claim Name: N/A
Claim Key: TBD (greater than 285)
Claim Value Type(s): array
Change Controller: IETF</t>
<t>Claim Name: and
Claim Description: Logical AND
JWT Claim Name: N/A
Claim Key: TBD (greater than 285)
Claim Value Type(s): array
Change Controller: IETF</t>
<t>Claim Name: enc
Claim Description: Logical AND
JWT Claim Name: N/A
Claim Key: TBD (greater than 285)
Claim Value Type(s): array
Change Controller: IETF</t>
<t>Claim Name: crit
Claim Description: Logical AND
JWT Claim Name: N/A
Claim Key: TBD (between 41 and 255)
Claim Value Type(s): array
Change Controller: IETF</t>
</section>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8392.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.9052.xml"/>
</references>
<references><name>Informative References</name>
<reference anchor="CTA5009A" target="https://shop.cta.tech/products/fast-and-readable-geographical-hashing-cta-5009">
  <front>
    <title>CTA 5009-A: Fast and Readable Geographical Hashing</title>
    <author>
      <organization>Consumer Technology Association</organization>
    </author>
    <date year="2024"></date>
  </front>
</reference>
</references>

</back>

</rfc>
