<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     ipr="trust200902" category="std" submissionType="IETF"
     docName="draft-srivastava-stir-sip-request-context-00"
     updates="9970" consensus="true" xml:lang="en" version="3">
  <front>
    <title abbrev="STIR SIP Request Context">SIP Request Context Binding for STIR Connected Identity</title>
    <seriesInfo name="Internet-Draft" value="draft-srivastava-stir-sip-request-context-00"/>
    <author fullname="Aviral Srivastava" initials="A." surname="Srivastava">
      <address>
        <email>aviralyash27@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="August"/>
    <area>Applications and Real-Time</area>
    <workgroup>Secure Telephone Identity Revisited</workgroup>
    <keyword>STIR</keyword>
    <keyword>PASSporT</keyword>
    <keyword>SIP</keyword>
    <keyword>connected identity</keyword>
    <abstract>
      <t>This document updates RFC 9970.</t>
      <t>
        RFC 9970 recommends STIR PASSporTs on re-INVITE and BYE requests
        after connected identity has been established in a SIP dialog, and
        states that this prevents spoofed mid-dialog or dialog-terminating
        events.
        The baseline PASSporT construction used by RFC 8224 does not bind the
        SIP request method, CSeq number, Call-ID, or dialog tags.  Consequently,
        a valid PASSporT can remain valid when a fresh signed in-dialog request
        is transformed into a different SIP request whose authenticated
        identity fields are unchanged.
      </t>
      <t>
        This document defines the "sipctx" PASSporT type.  It binds the SIP
        request method and dialog/sequence context to the PASSporT.
        Implementations relying on PASSporT validation for mid-dialog request
        authenticity use this context binding as specified in this document.
      </t>
    </abstract>
  </front>

  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>
        <xref target="RFC9970"/> recommends valid PASSporTs on re-INVITE and
        BYE requests after connected identity has been established and states
        that doing so prevents spoofed mid-dialog requests and denial-of-service
        teardowns.  That construction uses the SIP Identity mechanism of
        <xref target="RFC8224"/> and the PASSporT format of
        <xref target="RFC8225"/>.
      </t>
      <t>
        The baseline construction does not bind several SIP fields that select
        the operation and dialog context of a request.  In particular, the SIP
        method, CSeq number, Call-ID, From tag, and To tag are not baseline
        PASSporT claims.  This creates a semantic substitution gap when a
        PASSporT is used as evidence that a specific mid-dialog operation was
        authorized by its signer.
      </t>
      <t>
        This omission is historically significant.  The predecessor SIP
        Identity mechanism in <xref target="RFC4474"/> signed CSeq and
        specifically identified transformation of an INVITE into a BYE as the
        attack prevented by doing so.  <xref target="RFC8224"/> intentionally
        reduced the protected SIP fields when it replaced RFC 4474.  That
        reduction is compatible with the narrower origin-identity properties
        of RFC 8224, but it is insufficient for the request-semantic property
        later assigned to PASSporTs by RFC 9970.
      </t>
      <t>
        This document does not change baseline STIR origin-identity semantics.
        It defines an additional mandatory PASSporT type for applications that
        rely on cryptographic authentication of an in-dialog SIP request as a
        particular operation in a particular dialog.
      </t>
    </section>

    <section anchor="requirements">
      <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="counterexample">
      <name>Request-Method Substitution Counterexample</name>
      <t>
        Consider an established two-party SIP dialog in which the remote
        sequence number last accepted by the terminating UA is 80.  The
        originating UA creates a legitimate in-dialog re-INVITE using CSeq 81,
        adds a fresh RFC 8224 Identity field, and sends the request.  A
        downstream on-path intermediary suppresses that request before it
        reaches the terminating UA.
      </t>
      <t>
        The intermediary changes only the method token in the Request-Line and
        the method token in CSeq from INVITE to BYE.  The numeric CSeq value,
        From and To fields, Date, Call-ID, dialog tags, and Identity field are
        unchanged.  The resulting request therefore has the same baseline
        PASSporT inputs as the signed re-INVITE while carrying BYE semantics.
      </t>
      <sourcecode type="text"><![CDATA[
INVITE sip:bank@192.0.2.20:5060 SIP/2.0
...
Call-ID: DlgA-9f2@alice.example
CSeq: 81 INVITE
Date: Sun, 16 Aug 2026 11:00:00 GMT
Identity: <unchanged PASSporT>

                 changes only to

BYE sip:bank@192.0.2.20:5060 SIP/2.0
...
Call-ID: DlgA-9f2@alice.example
CSeq: 81 BYE
Date: Sun, 16 Aug 2026 11:00:00 GMT
Identity: <unchanged PASSporT>
      ]]></sourcecode>
      <t>
        The original re-INVITE can also retain its Contact field unchanged.
        RFC 3261 classifies Contact as not applicable to BYE, but requires a
        UAS to ignore a not-applicable header field if one is present by
        mistake.  The transformation therefore need not delete Contact or
        alter any other header field.
      </t>
      <t>
        The CSeq method still matches the Request-Line method as required by
        <xref target="RFC3261"/>, and the numeric CSeq is the exact next value
        in the dialog.  Because the authentic re-INVITE was suppressed, a
        replay cache at the receiver has not previously observed its Identity
        value.  Neither full-form nor compact baseline PASSporT verification
        reconstructs a request method or dialog identifier, so baseline
        identity verification cannot distinguish these two requests.
      </t>
    </section>

    <section anchor="sipctx">
      <name>The "sipctx" PASSporT Type</name>
      <t>
        This document defines a PASSporT type whose "ppt" value is "sipctx".
        The type makes five SIP request-context claims mandatory as a set:
        "sip_method", "sip_cseq_num", "sip_callid", "sip_from_tag", and
        "sip_to_tag".
      </t>
      <t>
        The "sip_callid", "sip_cseq_num", and "sip_from_tag" claim names are
        already registered by <xref target="RFC8055"/>.  This document reuses
        those claim names with the same SIP-field meanings.  It defines two
        additional JWT claim names, "sip_method" and "sip_to_tag".
      </t>
      <t>
        The serialization procedure in Section 5.5 of <xref target="RFC8055"/>
        is specific to reconstruction of the RFC 8055 received-realm detached
        JWS and <bcp14>MUST NOT</bcp14> be applied to a "sipctx" PASSporT.
        In particular, a Call-ID value <bcp14>MUST NOT</bcp14> be case-normalized.
        Construction and reconstruction of "sipctx" claims are instead
        specified by <xref target="claim-construction"/> and use PASSporT
        deterministic JSON serialization from <xref target="RFC8225"/>.
      </t>

      <section anchor="claim-construction">
        <name>Claim Construction</name>
        <t>
          An authentication service constructing a "sipctx" PASSporT for an
          in-dialog SIP request <bcp14>MUST</bcp14> populate the five mandatory
          claims as follows:
        </t>
        <dl newline="true">
          <dt>sip_method</dt>
          <dd>
            A JSON string containing the method token from the SIP Request-Line.
            SIP method names are case-sensitive as specified by
            <xref target="RFC4485"/>; no case normalization is performed.
          </dd>
          <dt>sip_cseq_num</dt>
          <dd>
            A JSON string containing the CSeq sequence number in canonical
            unsigned base-10 form.  The canonical form contains no leading
            zeroes except that zero itself is encoded as "0".  Signers and
            verifiers compare the underlying CSeq value numerically before
            producing this representation.
          </dd>
          <dt>sip_callid</dt>
          <dd>
            A JSON string containing the Call-ID value of the request.
            Call-ID is case-sensitive and is compared byte-for-byte as
            specified by <xref target="RFC3261"/>.
          </dd>
          <dt>sip_from_tag</dt>
          <dd>
            A JSON string containing the parsed From "tag" parameter value,
            converted to lowercase ASCII for deterministic representation.
            The "tag" parameter is a SIP token parameter and follows the SIP
            parameter-value comparison rules of <xref target="RFC3261"/>.
          </dd>
          <dt>sip_to_tag</dt>
          <dd>
            A JSON string containing the parsed To "tag" parameter value,
            converted to lowercase ASCII for deterministic representation.
          </dd>
        </dl>
        <t>
          The value of "sip_method" <bcp14>MUST</bcp14> equal the method token
          in CSeq.  A signer <bcp14>MUST NOT</bcp14> generate a "sipctx"
          PASSporT for a request for which those method tokens differ.
        </t>
      </section>

      <section anchor="payload-example">
        <name>Example Payload</name>
        <t>
          A full "sipctx" payload for the request in
          <xref target="counterexample"/> can contain the following claims in
          addition to any other claims required by the applicable STIR
          profile:
        </t>
        <sourcecode type="json"><![CDATA[
{
  "dest":{"tn":["12125550100"]},
  "iat":1786878000,
  "orig":{"tn":"12125550101"},
  "sip_callid":"DlgA-9f2@alice.example",
  "sip_cseq_num":"81",
  "sip_from_tag":"a1b2c3",
  "sip_method":"INVITE",
  "sip_to_tag":"b4c5d6"
}
        ]]></sourcecode>
      </section>
    </section>

    <section anchor="verification">
      <name>Verification Procedures</name>
      <t>
        A verification service that supports "sipctx" first performs the
        applicable RFC 8224 verification procedures, including credential,
        freshness, and baseline identity processing.  It then validates the
        mandatory request-context claims defined by this document.
      </t>
      <t>
        For a compact PASSporT, the verifier <bcp14>MUST</bcp14> reconstruct all
        five request-context claims from the received SIP request according to
        <xref target="claim-construction"/> before validating the PASSporT
        signature.  This reconstruction requirement makes the extension
        suitable for compact PASSporT use under <xref target="RFC8225"/>.
      </t>
      <t>
        For a full-form PASSporT, validating the JWS bytes alone is
        insufficient.  After cryptographic validation, the verifier
        <bcp14>MUST</bcp14> independently derive the five request-context values
        from the received SIP request and compare them to the signed claims
        using the rules in <xref target="claim-construction"/>.  Any mismatch
        causes that "sipctx" Identity field to be invalid for request-semantic
        authentication.
      </t>
    </section>

    <section anchor="rfc9970-update">
      <name>Update to RFC 9970</name>
      <t>
        This section updates the processing guidance in Section 6 of
        <xref target="RFC9970"/>.
      </t>
      <t>
        An implementation that relies on PASSporT validation to obtain the
        RFC 9970 property that an in-dialog re-INVITE or BYE request was
        authorized as that specific SIP operation <bcp14>MUST</bcp14> require a
        valid "sipctx" PASSporT for that request.  A valid baseline PASSporT
        without "sipctx" continues to authenticate the identity information
        defined by RFC 8224, but <bcp14>MUST NOT</bcp14> be treated as
        cryptographic authentication of the request method or dialog context.
      </t>
      <t>
        This requirement does not require every RFC 9970 deployment to reject
        requests that lack "sipctx".  Authorization policy remains local.
        Rather, a relying party <bcp14>MUST NOT</bcp14> claim or depend on the
        anti-spoofing or anti-teardown property described above unless the
        request-semantic binding has been successfully verified.
      </t>
    </section>

    <section anchor="downgrade">
      <name>Compatibility and Downgrade Handling</name>
      <t>
        <xref target="RFC8224"/> permits multiple Identity fields in a request.
        During incremental deployment, an authentication service
        <bcp14>MAY</bcp14> therefore include both a baseline Identity field and
        a "sipctx" Identity field for the same request.
      </t>
      <t>
        A relying party requiring request-semantic authentication
        <bcp14>MUST NOT</bcp14> fall back to a baseline Identity field when the
        "sipctx" Identity is absent, removed, unsupported, or invalid.  Such a
        fallback would permit an intermediary to strip the context-bound
        Identity while retaining a valid baseline Identity, defeating the
        property this document provides.
      </t>
      <t>
        A baseline Identity that remains valid after such stripping
        <bcp14>MAY</bcp14> still be used for the narrower identity assertions
        defined by RFC 8224, subject to local policy.
      </t>
    </section>

    <section anchor="b2bua">
      <name>Back-to-Back User Agents and Dialog Legs</name>
      <t>
        A Back-to-Back User Agent (B2BUA), as described by
        <xref target="RFC3261"/>, acts as a User Agent Server on one side and
        as a User Agent Client on the other, maintaining the dialogs it
        establishes.  The Call-ID, tags, CSeq state, and method sequencing are
        therefore properties of each dialog leg.  A B2BUA that
        provides request-semantic authentication on an outgoing leg
        <bcp14>MUST</bcp14> create a new "sipctx" PASSporT from the context of
        that outgoing request.  A "sipctx" PASSporT from one dialog leg
        <bcp14>MUST NOT</bcp14> be copied to another leg.
      </t>
    </section>

    <section anchor="excluded-fields">
      <name>Fields Deliberately Not Bound</name>
      <t>
        This document does not bind Via, Route, Record-Route, Max-Forwards,
        Contact, or the Request-URI.  Routing fields can be legitimately
        modified by SIP intermediaries, and Contact is not required to bind a
        request to its method, sequence position, or dialog.  None of these
        fields is required to close the method-substitution or same-identities
        cross-dialog substitution described here.
      </t>
      <t>
        This document also does not provide generic SIP message-body integrity.
        Existing or future PASSporT extensions can bind media keys or other
        application-specific bodies where required.
      </t>
    </section>

    <section anchor="related-work">
      <name>Related Work</name>
      <t>
        The individual Internet-Draft
        <xref target="I-D.hardman-verifiable-voice-protocol"/> independently
        binds "call-id" and "cseq" when verifying callee evidence against the
        preceding SIP INVITE.  That construction is scoped to VVP call setup
        and does not authenticate the method of an arbitrary RFC 9970
        mid-dialog request.  It is nevertheless useful design precedent for
        binding telephone-identity evidence to SIP transaction or dialog
        context rather than to identity claims alone.
      </t>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>
      <section anchor="iana-ppt">
        <name>PASSporT Type</name>
        <t>
          IANA is requested to add the following value to the "Personal
          Assertion Token (PASSporT) Extensions" registry:
        </t>
        <table>
          <thead><tr><th>ppt value</th><th>Reference</th></tr></thead>
          <tbody><tr><td>sipctx</td><td>This document, <xref target="sipctx"/></td></tr></tbody>
        </table>
      </section>
      <section anchor="iana-jwt">
        <name>JSON Web Token Claims</name>
        <t>
          IANA is requested to add the following values to the "JSON Web
          Token Claims" registry:
        </t>
        <table>
          <thead>
            <tr><th>Claim Name</th><th>Claim Description</th><th>Change Controller</th><th>Reference</th></tr>
          </thead>
          <tbody>
            <tr><td>sip_method</td><td>SIP request method</td><td>IESG</td><td>This document, <xref target="claim-construction"/></td></tr>
            <tr><td>sip_to_tag</td><td>SIP To tag header field parameter value</td><td>IESG</td><td>This document, <xref target="claim-construction"/></td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section anchor="security">
      <name>Security Considerations</name>
      <t>
        The security considerations of <xref target="RFC8224"/>,
        <xref target="RFC8225"/>, and <xref target="RFC9970"/> continue to
        apply.  This document adds integrity binding between a PASSporT and
        the SIP operation/dialog context in which it is used.
      </t>
      <t>
        This document does not revise RFC 8224's original statement that its
        Identity mechanism was not designed to provide generic end-to-end SIP
        message integrity against a man-in-the-middle.  The narrower issue is
        that RFC 9970 later relies on the same reduced signed envelope for a
        request-semantic anti-spoofing and anti-teardown property.
      </t>
      <t>
        The threat addressed here is semantic substitution by an entity that
        can modify signaling after a legitimate authentication service has
        created an Identity field.  The attacker does not need the signer's
        private key.  Suppression of the original signed request before the
        forged request reaches the verifier also means that first-observation
        replay state does not detect the substitution.
      </t>
      <t>
        The mechanism does not prevent an on-path attacker from dropping SIP
        messages.  An on-path party can always cause signaling-level denial of
        service by discarding traffic.  The additional property provided here
        is that such a party cannot transform a signed request into a
        different authenticated SIP operation or transplant the proof into a
        different dialog without invalidating the "sipctx" verification.
      </t>
      <t>
        Binding only the request method is insufficient.  Two simultaneous
        dialogs between the same authenticated identities have identical
        baseline "orig" and "dest" claims.  Call-ID and both dialog tags bind
        the proof to one dialog, while CSeq binds it to the request ordering
        context within that dialog.
      </t>
    </section>
  </middle>

  <back>
    <references>
      <name>Normative References</name>
      <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.3261.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4485.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8055.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8224.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8225.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9970.xml"/>
    </references>
    <references>
      <name>Informative References</name>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4474.xml"/>
      <reference anchor="I-D.hardman-verifiable-voice-protocol"
                 target="https://datatracker.ietf.org/doc/draft-hardman-verifiable-voice-protocol/">
        <front>
          <title>Verifiable Voice Protocol</title>
          <author initials="D." surname="Hardman" fullname="Daniel Hardman"/>
          <date year="2026" month="March" day="19"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-hardman-verifiable-voice-protocol-07"/>
        <refcontent>Work in Progress</refcontent>
      </reference>
    </references>

    <section anchor="test-model" numbered="false">
      <name>Executable Model</name>
      <t>
        An executable model used during development exercises full-form and
        compact baseline PASSporTs, an origin-identity negative control,
        compact-form Date reconstruction and full-form signed-iat repair, a
        two-token INVITE-to-BYE transformation with an unchanged numeric CSeq,
        a method-only control, a same-identities cross-dialog transplant,
        comparison-rule controls, and extension-stripping behavior.  The
        model is non-normative; the protocol requirements are the text in the
        body of this document.
      </t>
    </section>
  </back>
</rfc>
