<?xml version='1.0' encoding='utf-8'?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" category="info" consensus="true" docName="draft-ietf-capport-architecture-10" indexInclude="true" ipr="trust200902" number="8952" prepTime="2020-11-30T18:43:00" scripts="Common,Latin" sortRefs="true" submissionType="IETF" symRefs="true" tocDepth="4" tocInclude="true" xml:lang="en">
  <link href="https://datatracker.ietf.org/doc/draft-ietf-capport-architecture-10" rel="prev"/>
  <link href="https://dx.doi.org/10.17487/rfc8952" rel="alternate"/>
  <link href="urn:issn:2070-1721" rel="alternate"/>
  <front>
    <title abbrev="Captive Portal Architecture">Captive Portal Architecture</title>
    <seriesInfo name="RFC" value="8952" stream="IETF"/>
    <author fullname="Kyle Larose" initials="K." surname="Larose">
      <organization showOnFrontPage="true">Agilicus</organization>
      <address>
        <email>kyle@agilicus.com</email>
      </address>
    </author>
    <author fullname="David Dolson" initials="D." surname="Dolson">
      <address>
        <email>ddolson@acm.org</email>
      </address>
    </author>
    <author fullname="Heng Liu" initials="H." surname="Liu">
      <organization showOnFrontPage="true">Google</organization>
      <address>
        <email>liucougar@google.com</email>
      </address>
    </author>
    <date month="11" year="2020"/>
    <area>art</area>
    <workgroup>Internet Engineering Task Force</workgroup>
    <keyword>Captive Portal</keyword>
    <keyword>Architecture</keyword>
    <keyword>Wifi</keyword>
    <keyword>Wi-Fi</keyword>
    <keyword>Wireless</keyword>
    <keyword>Roaming</keyword>
    <keyword>Mobile</keyword>
    <keyword>API</keyword>
    <abstract pn="section-abstract">
      <t indent="0" pn="section-abstract-1">This document describes a captive portal architecture.
        Network provisioning protocols such as DHCP or Router Advertisements (RAs),
        an optional signaling protocol, and an HTTP API are used to provide the solution.
      </t>
    </abstract>
    <boilerplate>
      <section anchor="status-of-memo" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.1">
        <name slugifiedName="name-status-of-this-memo">Status of This Memo</name>
        <t indent="0" pn="section-boilerplate.1-1">
            This document is not an Internet Standards Track specification; it is
            published for informational purposes.  
        </t>
        <t indent="0" pn="section-boilerplate.1-2">
            This document is a product of the Internet Engineering Task Force
            (IETF).  It represents the consensus of the IETF community.  It has
            received public review and has been approved for publication by the
            Internet Engineering Steering Group (IESG).  Not all documents
            approved by the IESG are candidates for any level of Internet
            Standard; see Section 2 of RFC 7841. 
        </t>
        <t indent="0" pn="section-boilerplate.1-3">
            Information about the current status of this document, any
            errata, and how to provide feedback on it may be obtained at
            <eref target="https://www.rfc-editor.org/info/rfc8952" brackets="none"/>.
        </t>
      </section>
      <section anchor="copyright" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.2">
        <name slugifiedName="name-copyright-notice">Copyright Notice</name>
        <t indent="0" pn="section-boilerplate.2-1">
            Copyright (c) 2020 IETF Trust and the persons identified as the
            document authors. All rights reserved.
        </t>
        <t indent="0" pn="section-boilerplate.2-2">
            This document is subject to BCP 78 and the IETF Trust's Legal
            Provisions Relating to IETF Documents
            (<eref target="https://trustee.ietf.org/license-info" brackets="none"/>) in effect on the date of
            publication of this document. Please review these documents
            carefully, as they describe your rights and restrictions with
            respect to this document. Code Components extracted from this
            document must include Simplified BSD License text as described in
            Section 4.e of the Trust Legal Provisions and are provided without
            warranty as described in the Simplified BSD License.
        </t>
      </section>
    </boilerplate>
    <toc>
      <section anchor="toc" numbered="false" removeInRFC="false" toc="exclude" pn="section-toc.1">
        <name slugifiedName="name-table-of-contents">Table of Contents</name>
        <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1">
          <li pn="section-toc.1-1.1">
            <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.1"><xref derivedContent="1" format="counter" sectionFormat="of" target="section-1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-introduction">Introduction</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.1.2">
              <li pn="section-toc.1-1.1.2.1">
                <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.1.1"><xref derivedContent="1.1" format="counter" sectionFormat="of" target="section-1.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-requirements-language">Requirements Language</xref></t>
              </li>
              <li pn="section-toc.1-1.1.2.2">
                <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.2.1"><xref derivedContent="1.2" format="counter" sectionFormat="of" target="section-1.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-terminology">Terminology</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.2">
            <t indent="0" pn="section-toc.1-1.2.1"><xref derivedContent="2" format="counter" sectionFormat="of" target="section-2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-components">Components</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.2.2">
              <li pn="section-toc.1-1.2.2.1">
                <t indent="0" pn="section-toc.1-1.2.2.1.1"><xref derivedContent="2.1" format="counter" sectionFormat="of" target="section-2.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-user-equipment">User Equipment</xref></t>
              </li>
              <li pn="section-toc.1-1.2.2.2">
                <t indent="0" pn="section-toc.1-1.2.2.2.1"><xref derivedContent="2.2" format="counter" sectionFormat="of" target="section-2.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-provisioning-service">Provisioning Service</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.2.2.2.2">
                  <li pn="section-toc.1-1.2.2.2.2.1">
                    <t indent="0" pn="section-toc.1-1.2.2.2.2.1.1"><xref derivedContent="2.2.1" format="counter" sectionFormat="of" target="section-2.2.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-dhcp-or-router-advertisemen">DHCP or Router Advertisements</xref></t>
                  </li>
                  <li pn="section-toc.1-1.2.2.2.2.2">
                    <t indent="0" pn="section-toc.1-1.2.2.2.2.2.1"><xref derivedContent="2.2.2" format="counter" sectionFormat="of" target="section-2.2.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-provisioning-domains">Provisioning Domains</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.2.2.3">
                <t indent="0" pn="section-toc.1-1.2.2.3.1"><xref derivedContent="2.3" format="counter" sectionFormat="of" target="section-2.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-captive-portal-api-server">Captive Portal API Server</xref></t>
              </li>
              <li pn="section-toc.1-1.2.2.4">
                <t indent="0" pn="section-toc.1-1.2.2.4.1"><xref derivedContent="2.4" format="counter" sectionFormat="of" target="section-2.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-captive-portal-enforcement-">Captive Portal Enforcement Device</xref></t>
              </li>
              <li pn="section-toc.1-1.2.2.5">
                <t indent="0" pn="section-toc.1-1.2.2.5.1"><xref derivedContent="2.5" format="counter" sectionFormat="of" target="section-2.5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-captive-portal-signal">Captive Portal Signal</xref></t>
              </li>
              <li pn="section-toc.1-1.2.2.6">
                <t indent="0" pn="section-toc.1-1.2.2.6.1"><xref derivedContent="2.6" format="counter" sectionFormat="of" target="section-2.6"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-component-diagram">Component Diagram</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.3">
            <t indent="0" pn="section-toc.1-1.3.1"><xref derivedContent="3" format="counter" sectionFormat="of" target="section-3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-user-equipment-identity">User Equipment Identity</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.3.2">
              <li pn="section-toc.1-1.3.2.1">
                <t indent="0" pn="section-toc.1-1.3.2.1.1"><xref derivedContent="3.1" format="counter" sectionFormat="of" target="section-3.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-identifiers">Identifiers</xref></t>
              </li>
              <li pn="section-toc.1-1.3.2.2">
                <t indent="0" pn="section-toc.1-1.3.2.2.1"><xref derivedContent="3.2" format="counter" sectionFormat="of" target="section-3.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-recommended-properties">Recommended Properties</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.3.2.2.2">
                  <li pn="section-toc.1-1.3.2.2.2.1">
                    <t indent="0" pn="section-toc.1-1.3.2.2.2.1.1"><xref derivedContent="3.2.1" format="counter" sectionFormat="of" target="section-3.2.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-uniquely-identify-user-equi">Uniquely Identify User Equipment</xref></t>
                  </li>
                  <li pn="section-toc.1-1.3.2.2.2.2">
                    <t indent="0" pn="section-toc.1-1.3.2.2.2.2.1"><xref derivedContent="3.2.2" format="counter" sectionFormat="of" target="section-3.2.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-hard-to-spoof">Hard to Spoof</xref></t>
                  </li>
                  <li pn="section-toc.1-1.3.2.2.2.3">
                    <t indent="0" pn="section-toc.1-1.3.2.2.2.3.1"><xref derivedContent="3.2.3" format="counter" sectionFormat="of" target="section-3.2.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-visible-to-the-api-server">Visible to the API Server</xref></t>
                  </li>
                  <li pn="section-toc.1-1.3.2.2.2.4">
                    <t indent="0" pn="section-toc.1-1.3.2.2.2.4.1"><xref derivedContent="3.2.4" format="counter" sectionFormat="of" target="section-3.2.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-visible-to-the-enforcement-">Visible to the Enforcement Device</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.3.2.3">
                <t indent="0" pn="section-toc.1-1.3.2.3.1"><xref derivedContent="3.3" format="counter" sectionFormat="of" target="section-3.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-evaluating-types-of-identif">Evaluating Types of Identifiers</xref></t>
              </li>
              <li pn="section-toc.1-1.3.2.4">
                <t indent="0" pn="section-toc.1-1.3.2.4.1"><xref derivedContent="3.4" format="counter" sectionFormat="of" target="section-3.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-example-identifier-types">Example Identifier Types</xref></t>
                <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.3.2.4.2">
                  <li pn="section-toc.1-1.3.2.4.2.1">
                    <t indent="0" pn="section-toc.1-1.3.2.4.2.1.1"><xref derivedContent="3.4.1" format="counter" sectionFormat="of" target="section-3.4.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-physical-interface">Physical Interface</xref></t>
                  </li>
                  <li pn="section-toc.1-1.3.2.4.2.2">
                    <t indent="0" pn="section-toc.1-1.3.2.4.2.2.1"><xref derivedContent="3.4.2" format="counter" sectionFormat="of" target="section-3.4.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-ip-address">IP Address</xref></t>
                  </li>
                  <li pn="section-toc.1-1.3.2.4.2.3">
                    <t indent="0" pn="section-toc.1-1.3.2.4.2.3.1"><xref derivedContent="3.4.3" format="counter" sectionFormat="of" target="section-3.4.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-media-access-control-mac-ad">Media Access Control (MAC) Address</xref></t>
                  </li>
                </ul>
              </li>
              <li pn="section-toc.1-1.3.2.5">
                <t indent="0" pn="section-toc.1-1.3.2.5.1"><xref derivedContent="3.5" format="counter" sectionFormat="of" target="section-3.5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-context-free-uri">Context-Free URI</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.4">
            <t indent="0" pn="section-toc.1-1.4.1"><xref derivedContent="4" format="counter" sectionFormat="of" target="section-4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-solution-workflow">Solution Workflow</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.4.2">
              <li pn="section-toc.1-1.4.2.1">
                <t indent="0" pn="section-toc.1-1.4.2.1.1"><xref derivedContent="4.1" format="counter" sectionFormat="of" target="section-4.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-initial-connection">Initial Connection</xref></t>
              </li>
              <li pn="section-toc.1-1.4.2.2">
                <t indent="0" pn="section-toc.1-1.4.2.2.1"><xref derivedContent="4.2" format="counter" sectionFormat="of" target="section-4.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-conditions-about-to-expire">Conditions about to Expire</xref></t>
              </li>
              <li pn="section-toc.1-1.4.2.3">
                <t indent="0" pn="section-toc.1-1.4.2.3.1"><xref derivedContent="4.3" format="counter" sectionFormat="of" target="section-4.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-handling-of-changes-in-port">Handling of Changes in Portal URI</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.5">
            <t indent="0" pn="section-toc.1-1.5.1"><xref derivedContent="5" format="counter" sectionFormat="of" target="section-5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-iana-considerations">IANA Considerations</xref></t>
          </li>
          <li pn="section-toc.1-1.6">
            <t indent="0" pn="section-toc.1-1.6.1"><xref derivedContent="6" format="counter" sectionFormat="of" target="section-6"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-security-considerations">Security Considerations</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.6.2">
              <li pn="section-toc.1-1.6.2.1">
                <t indent="0" pn="section-toc.1-1.6.2.1.1"><xref derivedContent="6.1" format="counter" sectionFormat="of" target="section-6.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-trusting-the-network">Trusting the Network</xref></t>
              </li>
              <li pn="section-toc.1-1.6.2.2">
                <t indent="0" pn="section-toc.1-1.6.2.2.1"><xref derivedContent="6.2" format="counter" sectionFormat="of" target="section-6.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-authenticated-apis">Authenticated APIs</xref></t>
              </li>
              <li pn="section-toc.1-1.6.2.3">
                <t indent="0" pn="section-toc.1-1.6.2.3.1"><xref derivedContent="6.3" format="counter" sectionFormat="of" target="section-6.3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-secure-apis">Secure APIs</xref></t>
              </li>
              <li pn="section-toc.1-1.6.2.4">
                <t indent="0" pn="section-toc.1-1.6.2.4.1"><xref derivedContent="6.4" format="counter" sectionFormat="of" target="section-6.4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-risks-associated-with-the-s">Risks Associated with the Signaling Protocol</xref></t>
              </li>
              <li pn="section-toc.1-1.6.2.5">
                <t indent="0" pn="section-toc.1-1.6.2.5.1"><xref derivedContent="6.5" format="counter" sectionFormat="of" target="section-6.5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-user-options">User Options</xref></t>
              </li>
              <li pn="section-toc.1-1.6.2.6">
                <t indent="0" pn="section-toc.1-1.6.2.6.1"><xref derivedContent="6.6" format="counter" sectionFormat="of" target="section-6.6"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-privacy">Privacy</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.7">
            <t indent="0" pn="section-toc.1-1.7.1"><xref derivedContent="7" format="counter" sectionFormat="of" target="section-7"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-references">References</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.7.2">
              <li pn="section-toc.1-1.7.2.1">
                <t indent="0" pn="section-toc.1-1.7.2.1.1"><xref derivedContent="7.1" format="counter" sectionFormat="of" target="section-7.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-normative-references">Normative References</xref></t>
              </li>
              <li pn="section-toc.1-1.7.2.2">
                <t indent="0" pn="section-toc.1-1.7.2.2.1"><xref derivedContent="7.2" format="counter" sectionFormat="of" target="section-7.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-informative-references">Informative References</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.8">
            <t indent="0" pn="section-toc.1-1.8.1"><xref derivedContent="Appendix A" format="default" sectionFormat="of" target="section-appendix.a"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-existing-captive-portal-det">Existing Captive Portal Detection Implementations</xref></t>
          </li>
          <li pn="section-toc.1-1.9">
            <t indent="0" pn="section-toc.1-1.9.1"><xref derivedContent="" format="none" sectionFormat="of" target="section-appendix.b"/><xref derivedContent="" format="title" sectionFormat="of" target="name-acknowledgments">Acknowledgments</xref></t>
          </li>
          <li pn="section-toc.1-1.10">
            <t indent="0" pn="section-toc.1-1.10.1"><xref derivedContent="" format="none" sectionFormat="of" target="section-appendix.c"/><xref derivedContent="" format="title" sectionFormat="of" target="name-authors-addresses">Authors' Addresses</xref></t>
          </li>
        </ul>
      </section>
    </toc>
  </front>
  <middle>
    <section numbered="true" removeInRFC="false" toc="include" pn="section-1">
      <name slugifiedName="name-introduction">Introduction</name>
      <t indent="0" pn="section-1-1">
       In this document, "Captive Portal" is used to describe a network to
       which a device may be voluntarily attached, such that network access is
       limited until some requirements have been fulfilled.  Typically, a user
       is required to use a web browser to fulfill requirements imposed by the
       network operator, such as reading advertisements, accepting an
       acceptable-use policy, or providing some form of credentials.
      </t>
      <t indent="0" pn="section-1-2">
       Implementations of captive portals generally require a web server, some
       method to allow/block traffic, and some method to alert the user.
       Common methods of alerting the user in implementations prior to this
       work involve modifying HTTP or DNS traffic.
      </t>
      <t indent="0" pn="section-1-3">
       This document describes an architecture for implementing captive
       portals while addressing most of the problems arising for current
       captive portal mechanisms. The architecture is guided by these
       requirements:
      </t>
      <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-1-4">
        <li pn="section-1-4.1">Current captive portal solutions typically implement some variations
            of forging DNS or HTTP responses.
            Some attempt man-in-the-middle (MITM) proxy of HTTPS in
            order to forge responses.
            Captive portal solutions should not have to break any protocols or
            otherwise act in the manner of an attacker.
            Therefore, solutions <bcp14>MUST NOT</bcp14> require the forging of responses from
            DNS or HTTP servers or from any other protocol.</li>
        <li pn="section-1-4.2">Solutions <bcp14>MUST</bcp14> permit clients to perform DNSSEC validation, which rules out solutions
            that forge DNS responses.
            Solutions <bcp14>SHOULD</bcp14> permit clients to detect and avoid TLS man-in-the-middle attacks
            without requiring a human to perform any kind of "exception" processing.</li>
        <li pn="section-1-4.3">To maximize universality and adoption, solutions <bcp14>MUST</bcp14> operate at the
            layer of Internet Protocol (IP) or above, not being specific to any
            particular access technology such as cable, Wi-Fi, or mobile
            telecom.</li>
        <li pn="section-1-4.4">Solutions <bcp14>SHOULD</bcp14> allow a device to query the
        network to determine whether the device is captive, without the
        solution being coupled to forging intercepted protocols or requiring
        the device to make sacrificial queries to "canary" URIs to check for
        response tampering (see <xref target="app-additional" format="default" sectionFormat="of" derivedContent="Appendix A"/>). Current
        captive portal solutions that work by affecting DNS or HTTP generally
        only function as intended with browsers, breaking other applications
        using those protocols; applications using other protocols are not
        alerted that the network is a captive portal.</li>
        <li pn="section-1-4.5">The state of captivity <bcp14>SHOULD</bcp14> be explicitly available to devices via
            a standard protocol, rather than having to infer the state indirectly.</li>
        <li pn="section-1-4.6">The architecture <bcp14>MUST</bcp14> provide a path of incremental migration,
            acknowledging the existence of a huge variety of pre-existing
            portals and end-user device implementations and software versions.
            This requirement is not to recommend or standardize existing
            approaches, but rather to provide device and portal implementors a path
            to a new standard.</li>
      </ul>
      <t indent="0" pn="section-1-5">
       A side benefit of the architecture described in this document is that
       devices without user interfaces are able to identify parameters of
       captivity. However, this document does not describe a mechanism for
       such devices to negotiate for unrestricted network access. A future
       document could provide a solution to devices without user
       interfaces. This document focuses on devices with user interfaces.
      </t>
      <t indent="0" pn="section-1-6">
       The architecture uses the following mechanisms:
      </t>
      <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-1-7">
        <li pn="section-1-7.1">Network provisioning protocols provide end-user devices with a
        Uniform Resource Identifier (URI) <xref target="RFC3986" format="default" sectionFormat="of" derivedContent="RFC3986"/> for the API
        that end-user devices query for information about what is required to
        escape captivity. DHCP, DHCPv6, and Router Advertisement options for
        this purpose are available in <xref target="RFC8910" format="default" sectionFormat="of" derivedContent="RFC8910"/>. Other
        protocols (such as RADIUS), Provisioning Domains <xref target="I-D.pfister-capport-pvd" format="default" sectionFormat="of" derivedContent="CAPPORT-PVD"/>, or static configuration may also
        be used to convey this Captive Portal API URI.  A device
        <bcp14>MAY</bcp14> query this API at any time to determine whether the
        network is holding the device in a captive state.
         </li>
        <li pn="section-1-7.2">A Captive Portal can signal User Equipment in response to
        transmissions by the User Equipment. This signal works in response to
        any Internet protocol and is not done by modifying protocols in band.
        This signal does not carry the Captive Portal API URI; rather, it
        provides a signal to the User Equipment that it is in a captive state.
        </li>
        <li pn="section-1-7.3">
            Receipt of a Captive Portal Signal provides a hint that User Equipment could be captive.
            In response, the device <bcp14>MAY</bcp14> query the provisioned API to obtain
            information about the network state.
            The device can take immediate action to satisfy the portal
            (according to its configuration/policy).
         </li>
      </ul>
      <t indent="0" pn="section-1-8">
       The architecture attempts to provide confidentiality, authentication, and safety mechanisms
       to the extent possible.
      </t>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-1.1">
        <name slugifiedName="name-requirements-language">Requirements Language</name>
        <t indent="0" pn="section-1.1-1">
    The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
    "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
    "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
    "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are
    to be interpreted as described in BCP 14 <xref target="RFC2119" format="default" sectionFormat="of" derivedContent="RFC2119"/>
          <xref target="RFC8174" format="default" sectionFormat="of" derivedContent="RFC8174"/> when, and only when, they appear in all capitals,
    as shown here.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-1.2">
        <name slugifiedName="name-terminology">Terminology</name>
        <dl newline="true" indent="3" spacing="normal" pn="section-1.2-1">
          <dt pn="section-1.2-1.1">Captive Portal
</dt>
          <dd pn="section-1.2-1.2">A network that limits the communication of attached devices to restricted
hosts until the user has satisfied Captive Portal Conditions, after which
access is permitted to a wider set of hosts (typically the Internet).
</dd>
          <dt pn="section-1.2-1.3">Captive Portal Conditions
</dt>
          <dd pn="section-1.2-1.4">Site-specific requirements that a user or device must satisfy in order to
gain access to the wider network.
</dd>
          <dt pn="section-1.2-1.5">Captive Portal Enforcement Device
</dt>
          <dd pn="section-1.2-1.6">The network equipment that enforces the traffic restriction. Also known
as "Enforcement Device".
</dd>
          <dt pn="section-1.2-1.7">Captive Portal User Equipment
</dt>
          <dd pn="section-1.2-1.8">A device that has voluntarily joined a
network for purposes of communicating beyond the constraints of the Captive
Portal. Also known as "User Equipment".
</dd>
          <dt pn="section-1.2-1.9">User Portal
</dt>
          <dd pn="section-1.2-1.10">The web server providing a user interface for assisting the user in
satisfying the conditions to escape captivity.
</dd>
          <dt pn="section-1.2-1.11">Captive Portal API
</dt>
          <dd pn="section-1.2-1.12">An HTTP API allowing User Equipment to query information about its state
of captivity within the Captive Portal. This information might include how to
obtain full network access (e.g., by visiting a URI). Also known as "API".
</dd>
          <dt pn="section-1.2-1.13">Captive Portal API Server
</dt>
          <dd pn="section-1.2-1.14">A server hosting the Captive Portal API. Also known as "API Server".
</dd>
          <dt pn="section-1.2-1.15">Captive Portal Signal
</dt>
          <dd pn="section-1.2-1.16">A notification from the network used to signal to the User Equipment that
the state of its captivity could have changed.
</dd>
          <dt pn="section-1.2-1.17">Captive Portal Signaling Protocol
</dt>
          <dd pn="section-1.2-1.18">The protocol for communicating Captive Portal Signals. Also known as 
"Signaling Protocol".
</dd>
          <dt pn="section-1.2-1.19">Captive Portal Session
</dt>
          <dd pn="section-1.2-1.20">Also referred to simply as the "Session", a Captive Portal Session is the
association for a particular User Equipment instance that starts when it interacts with
the Captive Portal and gains open access to the network and ends when the
User Equipment moves back into the original captive state. The Captive Network
maintains the state of each active Session and can limit Sessions based on a
length of time or a number of bytes used. The Session is associated with a
particular User Equipment instance using the User Equipment's identifier (see <xref target="ue_identity" format="default" sectionFormat="of" derivedContent="Section 3"/>).
</dd>
        </dl>
      </section>
    </section>
    <section numbered="true" removeInRFC="false" toc="include" pn="section-2">
      <name slugifiedName="name-components">Components</name>
      <section anchor="section_client" numbered="true" removeInRFC="false" toc="include" pn="section-2.1">
        <name slugifiedName="name-user-equipment">User Equipment</name>
        <t indent="0" pn="section-2.1-1">
       The User Equipment is the device that a user desires to be attached to
       a network with full access to all hosts on the network (e.g., to have
       Internet access). The User Equipment communication is typically
       restricted by the Enforcement Device, described in <xref target="section_capport_enforcement" format="default" sectionFormat="of" derivedContent="Section 2.4"/>,
       until site-specific requirements have been met.
        </t>
        <t indent="0" pn="section-2.1-2">
        This document only considers devices with web browsers, with web
        applications being the means of satisfying Captive Portal Conditions.
        An example of such User Equipment is a smart phone.
        </t>
        <t indent="0" pn="section-2.1-3">
        The User Equipment:
        </t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-2.1-4">
          <li pn="section-2.1-4.1">
            <bcp14>SHOULD</bcp14> support provisioning of the URI for the
          Captive Portal API (e.g., by DHCP).</li>
          <li pn="section-2.1-4.2">
            <bcp14>SHOULD</bcp14> distinguish Captive Portal API access per
          network interface, in the manner of Provisioning Domain Architecture
          <xref target="RFC7556" format="default" sectionFormat="of" derivedContent="RFC7556"/>.</li>
          <li pn="section-2.1-4.3">
            <bcp14>SHOULD</bcp14> have a non-spoofable mechanism for
          notifying the user of the Captive Portal.</li>
          <li pn="section-2.1-4.4">
            <bcp14>SHOULD</bcp14> have a web browser so that the user may
          navigate to the User Portal.</li>
          <li pn="section-2.1-4.5">
            <bcp14>SHOULD</bcp14> support updates to the Captive Portal API
          URI from the Provisioning Service.</li>
          <li pn="section-2.1-4.6">
            <bcp14>MAY</bcp14> prevent applications from using networks that
          do not grant full network access. For example, a device connected to a
          mobile network may be connecting to a captive Wi-Fi network; the
          operating system could avoid updating the default route to a device
          on the captive Wi-Fi network until network access restrictions have been
          lifted (excepting access to the User Portal) in the new
          network. This has been termed "make before break".</li>
        </ul>
        <t indent="0" pn="section-2.1-5">
        None of the above requirements are mandatory because (a) we do not wish
        to say users or devices must seek full access to the Captive Portal,
        (b) the requirements may be fulfilled by manually visiting the captive
	portal web application, and (c) legacy devices must continue to be
        supported.
        </t>
        <t indent="0" pn="section-2.1-6">
        If User Equipment supports the Captive Portal API, it
        <bcp14>MUST</bcp14> validate the API Server's TLS certificate (see
        <xref target="RFC2818" format="default" sectionFormat="of" derivedContent="RFC2818"/>) according to the procedures in <xref target="RFC6125" format="default" sectionFormat="of" derivedContent="RFC6125"/>.  The API Server's URI is obtained via a network
        provisioning protocol, which will typically provide a hostname to be
        used in TLS server certificate validation, against a DNS-ID in the
        server certificate.  If the API Server is identified by IP address,
        the iPAddress subjectAltName is used to validate the server
        certificate.  An Enforcement Device <bcp14>SHOULD</bcp14> allow access
        to any services that User Equipment could need to contact to perform
        certificate validation, such as Online Certificate Status Protocol
        (OCSP) responders, Certificate Revocation Lists (CRLs), and NTP
        servers; see <xref target="RFC8908" sectionFormat="of" section="4.1" format="default" derivedLink="https://rfc-editor.org/rfc/rfc8908#section-4.1" derivedContent="RFC8908"/>
        for more information.  If certificate validation fails, User Equipment
        <bcp14>MUST NOT</bcp14> make any calls to the API Server.
        </t>
        <t indent="0" pn="section-2.1-7">
        The User Equipment can store the last response it received from the
	Captive Portal API
        as a cached view of its state within the Captive Portal. This state can be used to
        determine whether its Captive Portal Session is near expiry. For example, the User
        Equipment might compare a timestamp indicating when the Session expires to the current
        time. Storing state in this way can reduce the need for communication with the
        Captive Portal API. However, it could lead to the state becoming
        stale if the User Equipment's view of the relevant conditions (byte quota, for example)
        is not consistent with the Captive Portal API's.
        </t>
      </section>
      <section anchor="section_provisioning" numbered="true" removeInRFC="false" toc="include" pn="section-2.2">
        <name slugifiedName="name-provisioning-service">Provisioning Service</name>
        <t indent="0" pn="section-2.2-1">
          The Provisioning Service is primarily responsible for providing a
          Captive Portal API URI to the User Equipment when it connects to the
          network, and later if the URI changes.  The Provisioning Service
          could also be the same service that is responsible for provisioning
          the User Equipment for access to the Captive Portal (e.g., by
          providing it with an IP address).  This section discusses two
          mechanisms that may be used to provide the Captive Portal API URI
          to the User Equipment.
        </t>
        <section anchor="section_dhcp" numbered="true" removeInRFC="false" toc="include" pn="section-2.2.1">
          <name slugifiedName="name-dhcp-or-router-advertisemen">DHCP or Router Advertisements</name>
          <t indent="0" pn="section-2.2.1-1">
           A standard for providing a Captive Portal API URI using DHCP or Router
           Advertisements is described in <xref target="RFC8910" format="default" sectionFormat="of" derivedContent="RFC8910"/>.  The
           captive portal architecture expects this URI to indicate the API described
           in <xref target="section_api" format="default" sectionFormat="of" derivedContent="Section 2.3"/>.
          </t>
        </section>
        <section anchor="section_pvd" numbered="true" removeInRFC="false" toc="include" pn="section-2.2.2">
          <name slugifiedName="name-provisioning-domains">Provisioning Domains</name>
          <t indent="0" pn="section-2.2.2-1">
           <xref target="I-D.pfister-capport-pvd" format="default" sectionFormat="of" derivedContent="CAPPORT-PVD"/>
           proposes a mechanism for User Equipment to be provided with
           Provisioning Domain (PvD) Bootstrap Information containing the URI
           for the API described in <xref target="section_api" format="default" sectionFormat="of" derivedContent="Section 2.3"/>.
          </t>
        </section>
      </section>
      <section anchor="section_api" numbered="true" removeInRFC="false" toc="include" pn="section-2.3">
        <name slugifiedName="name-captive-portal-api-server">Captive Portal API Server</name>
        <t indent="0" pn="section-2.3-1">
         The purpose of a Captive Portal API is to permit a query of
         Captive Portal state without interrupting the user.  This API thereby
         removes the need for User Equipment to perform clear-text "canary"
         (see <xref target="app-additional" format="default" sectionFormat="of" derivedContent="Appendix A"/>) queries to check for response
         tampering.
        </t>
        <t indent="0" pn="section-2.3-2">
         The URI of this API will have been provisioned to the User Equipment.
         (Refer to <xref target="section_provisioning" format="default" sectionFormat="of" derivedContent="Section 2.2"/>.)
        </t>
        <t indent="0" pn="section-2.3-3">
         This architecture expects the User Equipment to query the API when the
         User Equipment attaches to the network and multiple times thereafter.
         Therefore, the API <bcp14>MUST</bcp14> support multiple repeated queries from the same
         User Equipment and return the state of captivity for the equipment.
        </t>
        <t indent="0" pn="section-2.3-4">
         At minimum, the API <bcp14>MUST</bcp14> provide the state of captivity. Further, the
         API <bcp14>MUST</bcp14> be able to provide a URI for the User Portal. The scheme for
         the URI <bcp14>MUST</bcp14> be "https" so that the User Equipment communicates with
         the User Portal over TLS.
        </t>
        <t indent="0" pn="section-2.3-5">
         If the API receives a request for state that does not correspond to the
         requesting User Equipment, the API <bcp14>SHOULD</bcp14> deny access.  Given that the
         API might use the User Equipment's identifier for authentication, this
         requirement motivates <xref target="id_recommended_hard" format="default" sectionFormat="of" derivedContent="Section 3.2.2"/>.
        </t>
        <t indent="0" pn="section-2.3-6">
         A caller to the API needs to be presented with evidence that the
         content it is receiving is for a version of the API that it
         supports. For an HTTP-based interaction, such as in <xref target="RFC8908" format="default" sectionFormat="of" derivedContent="RFC8908"/>, this might be achieved by using a content type
         that is unique to the protocol.
        </t>
        <t indent="0" pn="section-2.3-7">
         When User Equipment receives Captive Portal Signals, the User Equipment
         <bcp14>MAY</bcp14> query the API to check its state of captivity.
         The User Equipment <bcp14>SHOULD</bcp14> rate-limit these API queries in the event of
         the signal being flooded. (See <xref target="Security" format="default" sectionFormat="of" derivedContent="Section 6"/>.)
        </t>
        <t indent="0" pn="section-2.3-8">
         The API <bcp14>MUST</bcp14> be extensible to support future use cases by allowing
         extensible information elements.
        </t>
        <t indent="0" pn="section-2.3-9">
         The API <bcp14>MUST</bcp14> use TLS to ensure server authentication.
         The implementation of the API <bcp14>MUST</bcp14> ensure both confidentiality and 
         integrity of any information provided by or required by it.
        </t>
        <t indent="0" pn="section-2.3-10">
         This document does not specify the details of the API.
        </t>
      </section>
      <section anchor="section_capport_enforcement" numbered="true" removeInRFC="false" toc="include" pn="section-2.4">
        <name slugifiedName="name-captive-portal-enforcement-">Captive Portal Enforcement Device</name>
        <t indent="0" pn="section-2.4-1">
        The Enforcement Device component restricts the network access of
        User Equipment according to the site-specific policy. Typically, User Equipment
        is permitted access to a small number of services (according to the policies
        of the network provider) and is denied general
        network access until it satisfies the Captive Portal Conditions.
        </t>
        <t indent="0" pn="section-2.4-2">
       The Enforcement Device component:
        </t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-2.4-3">
          <li pn="section-2.4-3.1">Allows traffic to pass for User Equipment that is permitted to
              use the network and has satisfied the Captive Portal Conditions.</li>
          <li pn="section-2.4-3.2">Blocks (discards) traffic according to the site-specific policy
            for User Equipment that has not yet satisfied the Captive Portal Conditions.</li>
          <li pn="section-2.4-3.3">Optionally signals User Equipment using the Captive Portal Signaling Protocol
           if certain traffic is blocked.</li>
          <li pn="section-2.4-3.4">Permits User Equipment that has not satisfied the Captive Portal Conditions 
          to access necessary APIs and web pages to fulfill requirements for escaping captivity.</li>
          <li pn="section-2.4-3.5">Updates allow/block rules per User Equipment in response to operations
           from the User Portal.</li>
        </ul>
      </section>
      <section anchor="section_signal" numbered="true" removeInRFC="false" toc="include" pn="section-2.5">
        <name slugifiedName="name-captive-portal-signal">Captive Portal Signal</name>
        <t indent="0" pn="section-2.5-1">
        When User Equipment first connects to a network, or when there are changes in status,
        the Enforcement Device could generate a signal toward the User Equipment.  This signal
        indicates that the User Equipment might need to contact the API Server to receive
        updated information.  For instance, this signal might be generated when the end of a
        Session is imminent or when network access was denied.
        For simplicity, and to reduce the attack surface, all signals <bcp14>SHOULD</bcp14> be considered
        equivalent by the User Equipment as a hint to contact the API.
        If future solutions have multiple signal types, each type <bcp14>SHOULD</bcp14> be rate-limited
        independently.
        </t>
        <t indent="0" pn="section-2.5-2">
        An Enforcement Device <bcp14>MUST</bcp14> rate-limit any signal generated in response to these conditions.  See <xref target="section_signal_risks" format="default" sectionFormat="of" derivedContent="Section 6.4"/> for a discussion of
        risks related to a Captive Portal Signal.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-2.6">
        <name slugifiedName="name-component-diagram">Component Diagram</name>
        <t indent="0" pn="section-2.6-1">
            The following diagram shows the communication between each component in the
            case where the Captive Portal has a User Portal and the User Equipment
            chooses to visit the User Portal in response to discovering and interacting
            with the API Server.
        </t>
        <figure anchor="components" align="left" suppress-title="false" pn="figure-1">
          <name slugifiedName="name-captive-portal-architecture">Captive Portal Architecture Component Diagram</name>
          <artwork align="left" pn="section-2.6-2.1">
o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o
. CAPTIVE PORTAL                                                .
. +------------+  Join Network               +--------------+   .
. |            |+---------------------------&gt;| Provisioning |   .
. |            |  Provision API URI          |  Service     |   .
. |            |&lt;---------------------------+|              |   .
. |   User     |                             +--------------+   .
. | Equipment  |  Query captivity status     +-------------+    .
. |            |+---------------------------&gt;|  API        |    .
. |            |  Captivity status response  |  Server     |    .
. |            |&lt;---------------------------+|             |    .
. |            |                             +------+------+    .
. |            |                                    | Status    .
. |            | Portal UI page requests     +------+------+    .
. |            |+---------------------------&gt;|             |    .
. |            | Portal UI pages             | User Portal |    .
. |            |&lt;---------------------------+|             |    .
. +------------+                             |             |    .
.     ^   ^ |                                +-------------+    .
.     |   | | Data to/from ext. network               |         .
.     |   | +-----------------&gt; +---------------+  Allow/Deny   .
.     |   +--------------------+|               |    Rules      .
.     |                         | Enforcement   |     |         .
.     |   Captive Portal Signal | Device        |&lt;----+         .
.     +-------------------------+---------------+               .
.                                      ^ |                      .
.                                      | |                      .
.                          Data to/from external network        .
.                                      | |                      .
o . . . . . . . . . . . . . . . . . . .| |. . . . . . . . . . . o
                                       | v
                                  EXTERNAL NETWORK
	   </artwork>
        </figure>
        <t indent="0" pn="section-2.6-3">
        In the diagram:
        </t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-2.6-4">
          <li pn="section-2.6-4.1">During provisioning (e.g., DHCP), and possibly later, the User
          Equipment acquires the Captive Portal API URI.</li>
          <li pn="section-2.6-4.2">The User Equipment queries the API to learn of its state of
          captivity. If captive, the User Equipment presents the portal user
          interface from the User Portal to the user.</li>
          <li pn="section-2.6-4.3">Based on user interaction, the User Portal directs the
          Enforcement Device to either allow or deny external network access
          for the User Equipment.</li>
          <li pn="section-2.6-4.4">The User Equipment attempts to communicate to the external
          network through the Enforcement Device.</li>
          <li pn="section-2.6-4.5">The Enforcement Device either allows the User Equipment's
          packets to the external network or blocks the packets. If blocking
          traffic and a signal has been implemented, it may respond with a
          Captive Portal Signal.</li>
        </ul>
        <t indent="0" pn="section-2.6-5">
        The Provisioning Service, API Server, and User Portal are
        described as discrete functions. An implementation might provide the
        multiple functions within a single entity. Furthermore, these functions, combined or not,
        as well as the Enforcement Device, could be replicated for redundancy or scale.
        </t>
      </section>
    </section>
    <section anchor="ue_identity" numbered="true" removeInRFC="false" toc="include" pn="section-3">
      <name slugifiedName="name-user-equipment-identity">User Equipment Identity</name>
      <t indent="0" pn="section-3-1">
             Multiple components in the architecture interact with both the User
             Equipment and each other. Since the User Equipment is the focus of
             these interactions, the components must be able to both identify the
             User Equipment from their interactions with it and agree
             on the identity of the User Equipment when interacting with each
             other.
      </t>
      <t indent="0" pn="section-3-2">
             The methods by which the components interact restrict the type of
             information that may be used as an identifying characteristic. This
             section discusses the identifying characteristics.
      </t>
      <section anchor="id_identifiers" numbered="true" removeInRFC="false" toc="include" pn="section-3.1">
        <name slugifiedName="name-identifiers">Identifiers</name>
        <t indent="0" pn="section-3.1-1">
                 An identifier is a characteristic of the User Equipment used by
                 the components of a Captive Portal to uniquely determine which
                 specific User Equipment instance is interacting with them.
                 An identifier can be a field contained in packets
                 sent by the User Equipment to the external network. Or, an
                 identifier can be an ephemeral property not contained in packets
                 destined for the external network, but instead correlated with
                 such information through knowledge available to the different
                 components.
        </t>
      </section>
      <section anchor="id_recommended_props" numbered="true" removeInRFC="false" toc="include" pn="section-3.2">
        <name slugifiedName="name-recommended-properties">Recommended Properties</name>
        <t indent="0" pn="section-3.2-1">
             The set of possible identifiers is quite large. However, in order
             to be considered a good identifier, an identifier <bcp14>SHOULD</bcp14> meet the
             following criteria. Note that the optimal identifier will likely
             change depending on the position of the components in the network
             as well as the information available to them.

             An identifier <bcp14>SHOULD</bcp14>:
        </t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-3.2-2">
          <li pn="section-3.2-2.1">uniquely identify the User Equipment</li>
          <li pn="section-3.2-2.2">be hard to spoof</li>
          <li pn="section-3.2-2.3">be visible to the API Server</li>
          <li pn="section-3.2-2.4">be visible to the Enforcement Device</li>
        </ul>
        <t indent="0" pn="section-3.2-3">

             An identifier might only apply to the current point of network attachment. If the
             device moves to a different network location, its identity could change.
        </t>
        <section anchor="id_recommended_unique" numbered="true" removeInRFC="false" toc="include" pn="section-3.2.1">
          <name slugifiedName="name-uniquely-identify-user-equi">Uniquely Identify User Equipment</name>
          <t indent="0" pn="section-3.2.1-1">
                  The Captive Portal <bcp14>MUST</bcp14> associate the User
                  Equipment with an identifier that is unique among all of the
                  User Equipment interacting with the Captive Portal at that
                  time.
          </t>
          <t indent="0" pn="section-3.2.1-2">
                  Over time, the User Equipment assigned to an identifier
                  value <bcp14>MAY</bcp14> change. Allowing the identified
                  device to change over time ensures that the space of
                  possible identifying values need not be overly large.
          </t>
          <t indent="0" pn="section-3.2.1-3">
                  Independent Captive Portals <bcp14>MAY</bcp14> use the same
                  identifying value to identify different User
                  Equipment instances. Allowing independent captive portals to reuse
                  identifying values allows the identifier to be a property of
                  the local network, expanding the space of possible
                  identifiers.
          </t>
        </section>
        <section anchor="id_recommended_hard" numbered="true" removeInRFC="false" toc="include" pn="section-3.2.2">
          <name slugifiedName="name-hard-to-spoof">Hard to Spoof</name>
          <t indent="0" pn="section-3.2.2-1">
                  A good identifier does not lend itself to being easily
                  spoofed. At no time should it be simple or straightforward
                  for one User Equipment instance to pretend to be another User
                  Equipment instance, regardless of whether both are active at the same
                  time. This property is particularly important when the User
                  Equipment identifier is referenced externally by devices
                  such as billing systems or when the identity of the User
                  Equipment could imply liability.
          </t>
        </section>
        <section anchor="id_recommended_visible_api" numbered="true" removeInRFC="false" toc="include" pn="section-3.2.3">
          <name slugifiedName="name-visible-to-the-api-server">Visible to the API Server</name>
          <t indent="0" pn="section-3.2.3-1">
                  Since the API Server will need to perform operations that rely on the identity
                  of the User Equipment, such as answering a query about
                  whether the User Equipment is captive, the API Server needs
                  to be able to relate a request to the User Equipment making
                  the request.
          </t>
        </section>
        <section anchor="id_recommended_visible_ed" numbered="true" removeInRFC="false" toc="include" pn="section-3.2.4">
          <name slugifiedName="name-visible-to-the-enforcement-">Visible to the Enforcement Device</name>
          <t indent="0" pn="section-3.2.4-1">
                  The Enforcement Device will decide on a per-packet basis
                  whether the packet should be forwarded to the external
                  network. Since this decision depends on which User Equipment
                  instance sent the packet, the Enforcement Device requires
                  that it be able to map the packet to its concept of the User
                  Equipment.
          </t>
        </section>
      </section>
      <section anchor="id_evaluating" numbered="true" removeInRFC="false" toc="include" pn="section-3.3">
        <name slugifiedName="name-evaluating-types-of-identif">Evaluating Types of Identifiers</name>
        <t indent="0" pn="section-3.3-1">
                 To evaluate whether a type of identifier is appropriate, one should consider
                 every recommended property from the perspective of interactions among
                 the components in the architecture. When comparing identifier types, choose
                 the one that best satisfies all of the recommended properties. The
                 architecture does not provide an exact measure of how well an identifier
                 type satisfies a given property; care should be taken in performing the
                 evaluation.
        </t>
      </section>
      <section anchor="id_examples" numbered="true" removeInRFC="false" toc="include" pn="section-3.4">
        <name slugifiedName="name-example-identifier-types">Example Identifier Types</name>
        <t indent="0" pn="section-3.4-1">
                 This section provides some example identifier types, along with some
                 evaluation of whether they are suitable types. The list of identifier types
                 is not exhaustive; other types may be used. An important point to note
                 is that whether a given identifier type is suitable depends heavily on the
                 capabilities of the components and where in the network the components exist.
        </t>
        <section anchor="id_example_interface" numbered="true" removeInRFC="false" toc="include" pn="section-3.4.1">
          <name slugifiedName="name-physical-interface">Physical Interface</name>
          <t indent="0" pn="section-3.4.1-1">
                 The physical interface by which the User Equipment is attached to the
                 network can be used to identify the User Equipment. This identifier type has
                 the property of being extremely difficult to spoof: the User Equipment is
                 unaware of the property; one User Equipment instance cannot manipulate its
                 interactions to appear as though it is another.
          </t>
          <t indent="0" pn="section-3.4.1-2">
                 Further, if only a single User Equipment instance is attached
                 to a given physical interface, then the identifier will be
                 unique. If multiple User Equipment instances are attached
                 to the network on the same physical interface, then this type
                 is not appropriate.
          </t>
          <t indent="0" pn="section-3.4.1-3">
                 Another consideration related to uniqueness of the User
                 Equipment is that if the attached User Equipment changes,
                 both the API Server and the Enforcement Device
                 <bcp14>MUST</bcp14> invalidate their state related to the
                 User Equipment.
          </t>
          <t indent="0" pn="section-3.4.1-4">
                 The Enforcement Device needs to be aware of the physical
                 interface, which constrains the environment; it must either
                 be part of the device providing physical access (e.g.,
                 implemented in firmware), or packets traversing the network
                 must be extended to include information about the source
                 physical interface (e.g., a tunnel).
          </t>
          <t indent="0" pn="section-3.4.1-5">
                 The API Server faces a similar problem, implying that it should co-exist with the
                 Enforcement Device or that the Enforcement Device should extend requests to it
                 with the identifying information.
          </t>
        </section>
        <section anchor="id_example_IP_address" numbered="true" removeInRFC="false" toc="include" pn="section-3.4.2">
          <name slugifiedName="name-ip-address">IP Address</name>
          <t indent="0" pn="section-3.4.2-1">
                  A natural identifier type to consider is the IP address of the User Equipment.
                  At any given time, no device on the network can have the same IP address
                  without causing the network to malfunction, so it is appropriate from the
                  perspective of uniqueness.
          </t>
          <t indent="0" pn="section-3.4.2-2">
                  However, it may be possible to spoof the IP address, particularly for
                  malicious reasons where proper functioning of the network is not necessary
                  for the malicious actor. Consequently, any solution using the IP address
                  <bcp14>SHOULD</bcp14> proactively try to prevent spoofing of the IP address. Similarly,
                  if the mapping of IP address to User Equipment is changed, the components
                  of the architecture <bcp14>MUST</bcp14> remove or update their mapping to prevent spoofing.
                  Demonstrations of return routability, such as that required for TCP
                  connection establishment, might be sufficient defense against spoofing,
                  though this might not be sufficient in networks that use broadcast media
                  (such as some wireless networks).
          </t>
          <t indent="0" pn="section-3.4.2-3">
                  Since the IP address may traverse multiple segments of the network, more
                  flexibility is afforded to the Enforcement Device and the API Server; they
                  simply must exist on a segment of the network where the IP address is still
                  unique. However, consider that a NAT may be deployed between the User Equipment
                  and the Enforcement Device. In such cases, it is possible for the components
                  to still uniquely identify the device if they are aware of the port mapping.
          </t>
          <t indent="0" pn="section-3.4.2-4">
                In some situations, the User Equipment may have multiple IP
                addresses (either IPv4, IPv6, or a dual-stack <xref target="RFC4213" format="default" sectionFormat="of" derivedContent="RFC4213"/> combination) while still satisfying all of
                the recommended properties. This raises some challenges to the
                components of the network. For example, if the User Equipment
                tries to access the network with multiple IP addresses, should
                the Enforcement Device and API Server treat each IP address as
                a unique User Equipment instance, or should it tie the multiple
                addresses together into one view of the subscriber?  An
                implementation <bcp14>MAY</bcp14> do either. Attention should
                be paid to IPv6 and the fact that it is expected for a device
                to have multiple IPv6 addresses on a single link. In such
                cases, identification could be performed by subnet, such as
                the /64 to which the IP belongs.
          </t>
        </section>
        <section anchor="id_example_mac_address" numbered="true" removeInRFC="false" toc="include" pn="section-3.4.3">
          <name slugifiedName="name-media-access-control-mac-ad">Media Access Control (MAC) Address</name>
          <t indent="0" pn="section-3.4.3-1">
            The MAC address of a device is often used as an identifier in existing implementations.
            This document does not discuss the use of MAC addresses within a captive portal system, but they can be used
            as an identifier type, subject to the criteria in <xref target="id_recommended_props" format="default" sectionFormat="of" derivedContent="Section 3.2"/>.
          </t>
        </section>
      </section>
      <section anchor="context_free_uri" numbered="true" removeInRFC="false" toc="include" pn="section-3.5">
        <name slugifiedName="name-context-free-uri">Context-Free URI</name>
        <t indent="0" pn="section-3.5-1">
            A Captive Portal API needs to present information to clients
            that is unique to that client. To do this, some systems use
            information from the context of a request, such as the source
            address, to identify the User Equipment.
        </t>
        <t indent="0" pn="section-3.5-2">
            Using information from context rather than information from the
            URI allows the same URI to be used for different clients. However,
            it also means that the resource is unable to provide relevant
            information if the User Equipment makes a request using a different network
            path. This might happen when User Equipment has multiple network interfaces.
            It might also happen if the address of the API provided by DNS
            depends on where the query originates (as in split DNS
            <xref target="RFC8499" format="default" sectionFormat="of" derivedContent="RFC8499"/>).
        </t>
        <t indent="0" pn="section-3.5-3">
            Accessing the API <bcp14>MAY</bcp14> depend on contextual information. However,
            the URIs provided in the API <bcp14>SHOULD</bcp14> be unique to the User Equipment and not
            dependent on contextual information to function correctly.
        </t>
        <t indent="0" pn="section-3.5-4">
            Though a URI might still correctly resolve when the User Equipment makes the
            request from a different network, it is possible that some
            functions could be limited to when the User Equipment makes requests using the
            Captive Portal. For example, payment options could be absent or a
            warning could be displayed to indicate the payment is not for the
            current connection.
        </t>
        <t indent="0" pn="section-3.5-5">
            URIs could include some means of identifying the User Equipment in
            the URIs.  However, including unauthenticated User Equipment
            identifiers in the URI may expose the service to spoofing or replay
            attacks.
        </t>
      </section>
    </section>
    <section anchor="section_workflow" numbered="true" removeInRFC="false" toc="include" pn="section-4">
      <name slugifiedName="name-solution-workflow">Solution Workflow</name>
      <t indent="0" pn="section-4-1">
      This section aims to improve understanding by describing a possible
      workflow of solutions adhering to the architecture. Note that the section is
      not normative; it describes only a subset of possible implementations.
      </t>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-4.1">
        <name slugifiedName="name-initial-connection">Initial Connection</name>
        <t indent="0" pn="section-4.1-1">
      This section describes a possible workflow when User Equipment initially
      joins a Captive Portal.
        </t>
        <ol spacing="normal" type="1" indent="adaptive" start="1" pn="section-4.1-2">
          <li pn="section-4.1-2.1" derivedCounter="1.">The User Equipment joins the Captive Portal by acquiring a DHCP
         lease, RA, or similar, acquiring provisioning information.</li>
          <li pn="section-4.1-2.2" derivedCounter="2.">The User Equipment learns the URI for the Captive Portal API from the
         provisioning information (e.g., <xref target="RFC8910" format="default" sectionFormat="of" derivedContent="RFC8910"/>).</li>
          <li pn="section-4.1-2.3" derivedCounter="3.">The User Equipment accesses the Captive Portal API to receive parameters
         of the Captive Portal, including the User Portal URI. (This step replaces
         the clear-text query to a canary URI.)</li>
          <li pn="section-4.1-2.4" derivedCounter="4.">If necessary, the user navigates to the User Portal to gain access to the
         external network.</li>
          <li pn="section-4.1-2.5" derivedCounter="5.">
            If the user interacted with the User Portal to gain access to the external
            network in the previous step, the User Portal indicates to the Enforcement
            Device that the User Equipment is allowed to access the external network.
         </li>
          <li pn="section-4.1-2.6" derivedCounter="6.">The User Equipment attempts a connection outside the Captive Portal.</li>
          <li pn="section-4.1-2.7" derivedCounter="7.">If the requirements have been satisfied, the access is
          permitted; otherwise, the "Expired" behavior occurs.</li>
          <li pn="section-4.1-2.8" derivedCounter="8.">The User Equipment accesses the network until conditions expire.</li>
        </ol>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-4.2">
        <name slugifiedName="name-conditions-about-to-expire">Conditions about to Expire</name>
        <t indent="0" pn="section-4.2-1">
      This section describes a possible workflow when access is about to expire.
        </t>
        <ol spacing="normal" type="1" indent="adaptive" start="1" pn="section-4.2-2">
          <li pn="section-4.2-2.1" derivedCounter="1.">Precondition: the API has provided the User Equipment with a duration
         over which its access is valid.</li>
          <li pn="section-4.2-2.2" derivedCounter="2.">The User Equipment is communicating with the outside network.</li>
          <li pn="section-4.2-2.3" derivedCounter="3.">
            The User Equipment detects that the length of time left
            for its access has fallen below a threshold by comparing its stored
            expiry time with the current time.
          </li>
          <li pn="section-4.2-2.4" derivedCounter="4.">The User Equipment visits the API again to validate the expiry time.</li>
          <li pn="section-4.2-2.5" derivedCounter="5.">If expiry is still imminent, the User Equipment prompts the user to access the
         User Portal URI again.</li>
          <li pn="section-4.2-2.6" derivedCounter="6.">The user accepts the prompt displayed by the User Equipment.</li>
          <li pn="section-4.2-2.7" derivedCounter="7.">The user extends their access through the User Portal via the User Equipment's user interface.</li>
          <li pn="section-4.2-2.8" derivedCounter="8.">The User Equipment's access to the outside network continues uninterrupted.</li>
        </ol>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-4.3">
        <name slugifiedName="name-handling-of-changes-in-port">Handling of Changes in Portal URI</name>
        <t indent="0" pn="section-4.3-1">A different Captive Portal API URI could be returned in the following cases:</t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-4.3-2">
          <li pn="section-4.3-2.1">If DHCP is used, a lease renewal/rebind may return a different Captive
          Portal API URI.</li>
          <li pn="section-4.3-2.2">If RA is used, a new Captive Portal API URI may be specified in a new RA
          message received by end User Equipment.</li>
        </ul>
        <t indent="0" pn="section-4.3-3">When the Provisioning Service updates the Captive Portal API URI, the User
           Equipment can retrieve updated state from the URI immediately, or it can wait
           as it normally would until the expiry conditions it retrieved from the old URI are
           about to expire.
        </t>
      </section>
    </section>
    <section anchor="IANA" numbered="true" removeInRFC="false" toc="include" pn="section-5">
      <name slugifiedName="name-iana-considerations">IANA Considerations</name>
      <t indent="0" pn="section-5-1">This document has no IANA actions.</t>
    </section>
    <section anchor="Security" numbered="true" removeInRFC="false" toc="include" pn="section-6">
      <name slugifiedName="name-security-considerations">Security Considerations</name>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-6.1">
        <name slugifiedName="name-trusting-the-network">Trusting the Network</name>
        <t indent="0" pn="section-6.1-1">
         When joining a network, some trust is placed in the network operator.
         This is usually considered to be a decision by a user on the basis of
         the reputation of an organization. However, once a user makes such a
         decision, protocols can support authenticating that a network is operated
         by who claims to be operating it.  The Provisioning Domain
         Architecture <xref target="RFC7556" format="default" sectionFormat="of" derivedContent="RFC7556"/> provides some discussion on
         authenticating an operator.
        </t>
        <t indent="0" pn="section-6.1-2">
         The user makes an informed choice to visit and trust the Captive
         Portal URI. Since the network provides the Captive Portal URI to the
         User Equipment, the network <bcp14>SHOULD</bcp14> do so securely so
         that the user's trust in the network can extend to their trust of the
         Captive Portal URI. For example, the DHCPv6 AUTH option can sign this
         information.
        </t>
        <t indent="0" pn="section-6.1-3">
         If a user decides to incorrectly trust an attacking network, they might
         be convinced to visit an attacking web page and unwittingly provide
         credentials to an attacker. Browsers can authenticate servers but
         cannot detect cleverly misspelled domains, for example.
        </t>
        <t indent="0" pn="section-6.1-4">
         Further, the possibility of an on-path attacker in an attacking network
         introduces some risks. The attacker could redirect traffic to arbitrary
         destinations. The attacker could analyze the user's
         traffic leading to loss of confidentiality, or the attacker could modify
         the traffic inline.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-6.2">
        <name slugifiedName="name-authenticated-apis">Authenticated APIs</name>
        <t indent="0" pn="section-6.2-1">
         The solution described here requires that when the User Equipment needs to
         access the API Server, the User Equipment authenticates the
         server; see <xref target="section_client" format="default" sectionFormat="of" derivedContent="Section 2.1"/>.
        </t>
        <t indent="0" pn="section-6.2-2">
         The Captive Portal API URI might change during the Captive Portal Session.
         The User Equipment can apply the same trust mechanisms to the new URI as it
         did to the URI it received initially from the Provisioning Service.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-6.3">
        <name slugifiedName="name-secure-apis">Secure APIs</name>
        <t indent="0" pn="section-6.3-1">
           The solution described here requires that the API be secured using TLS.
           This is required to allow the User Equipment and API Server to exchange
           secrets that can be used to validate future interactions. The API <bcp14>MUST</bcp14>
           ensure the integrity of this information, as well as its confidentiality.
        </t>
        <t indent="0" pn="section-6.3-2">
           An attacker with access to this information might be able to
           masquerade as a specific User Equipment instance when interacting with the
           API, which could then allow them to masquerade as that User
           Equipment instance when interacting with the User Portal. This could give
           them the ability to determine whether the User Equipment has
           accessed the portal, deny the User Equipment service by ending
           their Session using mechanisms provided by the User Portal, or
           consume that User Equipment's quota. An attacker with the ability
           to modify the information could deny service to the User Equipment
           or cause them to appear as different User Equipment instances.
        </t>
      </section>
      <section anchor="section_signal_risks" numbered="true" removeInRFC="false" toc="include" pn="section-6.4">
        <name slugifiedName="name-risks-associated-with-the-s">Risks Associated with the Signaling Protocol</name>
        <t indent="0" pn="section-6.4-1">
         If a Signaling Protocol is implemented, it may be possible for any user on
         the Internet to send signals in an attempt to cause the receiving equipment to
         communicate with the Captive Portal API. This has been considered, and implementations may
         address it in the following ways:
        </t>
        <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-6.4-2">
          <li pn="section-6.4-2.1">The signal only signals to the User Equipment to query the API. It does not
              carry any information that may mislead or misdirect the User Equipment.</li>
          <li pn="section-6.4-2.2">Even when responding to the signal, the User Equipment securely authenticates
               with API Servers.</li>
          <li pn="section-6.4-2.3">The User Equipment limits the rate at which it accesses the API,
          reducing the impact of an attack attempting to generate excessive
          load on either the User Equipment or API.  Note that because there
          is only one type of signal and one type of API request in response
          to the signal, this rate-limiting will not cause loss of signaling
          information.
              </li>
        </ul>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-6.5">
        <name slugifiedName="name-user-options">User Options</name>
        <t indent="0" pn="section-6.5-1">
         The Captive Portal Signal could signal to the User Equipment that it is being held
         captive.  There is no requirement that the User Equipment do something
         about this.
         Devices <bcp14>MAY</bcp14> permit users to disable automatic reaction to
         Captive Portal Signal indications for privacy reasons.
         However, there would be the trade-off that the user doesn't get notified
         when network access is restricted.
         Hence, end-user devices <bcp14>MAY</bcp14> allow users to manually control captive
         portal interactions, possibly on the granularity of Provisioning
         Domains.
        </t>
      </section>
      <section numbered="true" removeInRFC="false" toc="include" pn="section-6.6">
        <name slugifiedName="name-privacy">Privacy</name>
        <t indent="0" pn="section-6.6-1">
          <xref target="ue_identity" format="default" sectionFormat="of" derivedContent="Section 3"/> describes a mechanism by which all components within
          the Captive Portal are designed to use the same identifier to uniquely identify
          the User Equipment.  This identifier could be abused to track the user.
          Implementers and designers of Captive Portals should take care to ensure that
          identifiers, if stored, are stored securely. Likewise, if any component
          communicates the identifier over the network, it should ensure the confidentiality
          of the identifier on the wire by using encryption such as TLS.
        </t>
        <t indent="0" pn="section-6.6-2">
          There are benefits to choosing mutable anonymous identifiers. For
          example, User Equipment could cycle through multiple identifiers to
          help prevent long-term tracking. However, if the components of the
          network use an internal mapping to map the identity to a stable,
          long-term value in order to deal with changing identifiers, they
          need to treat that value as sensitive information; an attacker could
          use it to tie traffic back to the originating User Equipment, despite
          the User Equipment having changed identifiers.
        </t>
      </section>
    </section>
  </middle>
  <back>
    <displayreference target="I-D.pfister-capport-pvd" to="CAPPORT-PVD"/>
    <references pn="section-7">
      <name slugifiedName="name-references">References</name>
      <references pn="section-7.1">
        <name slugifiedName="name-normative-references">Normative References</name>
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119" quoteTitle="true" derivedAnchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author initials="S." surname="Bradner" fullname="S. Bradner">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="1997" month="March"/>
            <abstract>
              <t indent="0">In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC2818" target="https://www.rfc-editor.org/info/rfc2818" quoteTitle="true" derivedAnchor="RFC2818">
          <front>
            <title>HTTP Over TLS</title>
            <author initials="E." surname="Rescorla" fullname="E. Rescorla">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2000" month="May"/>
            <abstract>
              <t indent="0">This memo describes how to use Transport Layer Security (TLS) to secure Hypertext Transfer Protocol (HTTP) connections over the Internet.  This memo provides information for the Internet community.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2818"/>
          <seriesInfo name="DOI" value="10.17487/RFC2818"/>
        </reference>
        <reference anchor="RFC6125" target="https://www.rfc-editor.org/info/rfc6125" quoteTitle="true" derivedAnchor="RFC6125">
          <front>
            <title>Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)</title>
            <author initials="P." surname="Saint-Andre" fullname="P. Saint-Andre">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="J." surname="Hodges" fullname="J. Hodges">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2011" month="March"/>
            <abstract>
              <t indent="0">Many application technologies enable secure communication between two entities by means of Internet Public Key Infrastructure Using X.509 (PKIX) certificates in the context of Transport Layer Security (TLS). This document specifies procedures for representing and verifying the identity of application services in such interactions.   [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6125"/>
          <seriesInfo name="DOI" value="10.17487/RFC6125"/>
        </reference>
        <reference anchor="RFC7556" target="https://www.rfc-editor.org/info/rfc7556" quoteTitle="true" derivedAnchor="RFC7556">
          <front>
            <title>Multiple Provisioning Domain Architecture</title>
            <author initials="D." surname="Anipko" fullname="D. Anipko" role="editor">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2015" month="June"/>
            <abstract>
              <t indent="0">This document is a product of the work of the Multiple Interfaces Architecture Design team.  It outlines a solution framework for some of the issues experienced by nodes that can be attached to multiple networks simultaneously.  The framework defines the concept of a Provisioning Domain (PvD), which is a consistent set of network configuration information.  PvD-aware nodes learn PvD-specific information from the networks they are attached to and/or other sources.  PvDs are used to enable separation and configuration consistency in the presence of multiple concurrent connections.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7556"/>
          <seriesInfo name="DOI" value="10.17487/RFC7556"/>
        </reference>
        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174" quoteTitle="true" derivedAnchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author initials="B." surname="Leiba" fullname="B. Leiba">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2017" month="May"/>
            <abstract>
              <t indent="0">RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8910" target="https://www.rfc-editor.org/info/rfc8910" quoteTitle="true" derivedAnchor="RFC8910">
          <front>
            <title>Captive-Portal Identification in DHCP and Router Advertisements (RAs)</title>
            <author initials="W." surname="Kumari" fullname="W. Kumari">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="E." surname="Kline" fullname="E. Kline">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2020" month="September"/>
            <abstract>
              <t indent="0">In many environments offering short-term or temporary Internet access (such as coffee shops), it is common to start new connections in a captive portal mode. This highly restricts what the user can do until the user has satisfied the captive portal conditions.</t>
              <t indent="0">This document describes a DHCPv4 and DHCPv6 option and a Router Advertisement (RA) option to inform clients that they are behind some sort of captive portal enforcement device, and that they will need to satisfy the Captive Portal conditions to get Internet access. It is not a full solution to address all of the issues that clients may have with captive portals; it is designed to be one component of a standardized approach for hosts to interact with such portals. While this document defines how the network operator may convey the captive portal API endpoint to hosts, the specific methods of satisfying and interacting with the captive portal are out of scope of this document.</t>
              <t indent="0">This document replaces RFC 7710, which used DHCP code point 160. Due to a conflict, this document specifies 114.  Consequently, this document also updates RFC 3679.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8910"/>
          <seriesInfo name="DOI" value="10.17487/RFC8910"/>
        </reference>
      </references>
      <references pn="section-7.2">
        <name slugifiedName="name-informative-references">Informative References</name>
        <reference anchor="I-D.pfister-capport-pvd" quoteTitle="true" target="https://tools.ietf.org/html/draft-pfister-capport-pvd-00" derivedAnchor="CAPPORT-PVD">
          <front>
            <title>Using Provisioning Domains for Captive Portal Discovery</title>
            <author fullname="Pierre Pfister">
              <organization showOnFrontPage="true">Cisco</organization>
            </author>
            <author fullname="Tommy Pauly">
              <organization showOnFrontPage="true">Apple Inc.</organization>
            </author>
            <date month="June" day="30" year="2018"/>
            <abstract>
              <t indent="0">   Devices that connect to Captive Portals need a way to identify that
   the network is restricted and discover a method for opening up
   access.  This document defines how to use Provisioning Domain
   Additional Information to discover a Captive Portal API URI.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-pfister-capport-pvd-00"/>
          <format type="TXT" target="https://www.ietf.org/internet-drafts/draft-pfister-capport-pvd-00.txt"/>
          <refcontent>Work in Progress</refcontent>
        </reference>
        <reference anchor="RFC3986" target="https://www.rfc-editor.org/info/rfc3986" quoteTitle="true" derivedAnchor="RFC3986">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author initials="T." surname="Berners-Lee" fullname="T. Berners-Lee">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="R." surname="Fielding" fullname="R. Fielding">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="L." surname="Masinter" fullname="L. Masinter">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2005" month="January"/>
            <abstract>
              <t indent="0">A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource.  This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet.  The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier.  This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme.  [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>
        <reference anchor="RFC4213" target="https://www.rfc-editor.org/info/rfc4213" quoteTitle="true" derivedAnchor="RFC4213">
          <front>
            <title>Basic Transition Mechanisms for IPv6 Hosts and Routers</title>
            <author initials="E." surname="Nordmark" fullname="E. Nordmark">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="R." surname="Gilligan" fullname="R. Gilligan">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2005" month="October"/>
            <abstract>
              <t indent="0">This document specifies IPv4 compatibility mechanisms that can be implemented by IPv6 hosts and routers.  Two mechanisms are specified, dual stack and configured tunneling.  Dual stack implies providing complete implementations of both versions of the Internet Protocol (IPv4 and IPv6), and configured tunneling provides a means to carry IPv6 packets over unmodified IPv4 routing infrastructures.</t>
              <t indent="0">This document obsoletes RFC 2893.  [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4213"/>
          <seriesInfo name="DOI" value="10.17487/RFC4213"/>
        </reference>
        <reference anchor="RFC8499" target="https://www.rfc-editor.org/info/rfc8499" quoteTitle="true" derivedAnchor="RFC8499">
          <front>
            <title>DNS Terminology</title>
            <author initials="P." surname="Hoffman" fullname="P. Hoffman">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="A." surname="Sullivan" fullname="A. Sullivan">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="K." surname="Fujiwara" fullname="K. Fujiwara">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2019" month="January"/>
            <abstract>
              <t indent="0">The Domain Name System (DNS) is defined in literally dozens of different RFCs.  The terminology used by implementers and developers of DNS protocols, and by operators of DNS systems, has sometimes changed in the decades since the DNS was first defined.  This document gives current definitions for many of the terms used in the DNS in a single document.</t>
              <t indent="0">This document obsoletes RFC 7719 and updates RFC 2308.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="219"/>
          <seriesInfo name="RFC" value="8499"/>
          <seriesInfo name="DOI" value="10.17487/RFC8499"/>
        </reference>
        <reference anchor="RFC8908" target="https://www.rfc-editor.org/info/rfc8908" quoteTitle="true" derivedAnchor="RFC8908">
          <front>
            <title>Captive Portal API</title>
            <author initials="T." surname="Pauly" fullname="T. Pauly" role="editor">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="D." surname="Thakore" fullname="D. Thakore" role="editor">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2020" month="September"/>
            <abstract>
              <t indent="0">This document describes an HTTP API that allows clients to interact with a Captive Portal system. With this API, clients can discover how to get out of captivity and fetch state about their Captive Portal sessions.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8908"/>
          <seriesInfo name="DOI" value="10.17487/RFC8908"/>
        </reference>
      </references>
    </references>
    <section anchor="app-additional" numbered="true" removeInRFC="false" toc="include" pn="section-appendix.a">
      <name slugifiedName="name-existing-captive-portal-det">Existing Captive Portal Detection Implementations</name>
      <t indent="0" pn="section-appendix.a-1">
       Operating systems and user applications may perform various tests when
       network connectivity is established to determine if the device is
       attached to a network with a captive portal present. A common method is
       to attempt to make an HTTP request to a known, vendor-hosted endpoint with
       a fixed response. Any other response is interpreted as a signal that a
       captive portal is present. This check is typically not secured with TLS,
       as a network with a captive portal may intercept the connection, leading
       to a host name mismatch. This has been referred to as a "canary" request
       because, like the canary in the coal mine, it can be the first sign
       that something is wrong.
      </t>
      <t indent="0" pn="section-appendix.a-2">
       Another test that can be performed is a DNS lookup to a known address
       with an expected answer. If the answer differs from the expected answer,
       the equipment detects that a captive portal is present.
       DNS queries over TCP or HTTPS are less likely to be modified than DNS
       queries over UDP due to the complexity of implementation.
      </t>
      <t indent="0" pn="section-appendix.a-3">
       The different tests may produce different conclusions, varying by
       whether or not the implementation treats both TCP and UDP traffic
       and by which types of DNS are intercepted.
      </t>
      <t indent="0" pn="section-appendix.a-4">
       Malicious or misconfigured networks with a captive portal present may
       not intercept these canary requests and choose to pass them through or decide to
       impersonate, leading to the device having a false negative.
      </t>
    </section>
    <section anchor="Acknowledgments" numbered="false" removeInRFC="false" toc="include" pn="section-appendix.b">
      <name slugifiedName="name-acknowledgments">Acknowledgments</name>
      <t indent="0" pn="section-appendix.b-1">The authors thank <contact fullname="Lorenzo Colitti"/> for providing
      the majority of the content for the Captive Portal Signal
      requirements.</t>
      <t indent="0" pn="section-appendix.b-2">The authors thank <contact fullname="Benjamin Kaduk"/> for providing
      the content related to TLS certificate validation of the API Server.</t>
      <t indent="0" pn="section-appendix.b-3">The authors thank <contact fullname="Michael Richardson"/> for
      providing wording requiring DNSSEC and TLS to operate without the user
      adding exceptions.</t>
      <t indent="0" pn="section-appendix.b-4">The authors thank various individuals for their feedback on
        the mailing list and during the IETF 98 hackathon:
        <contact fullname="David Bird"/>,
        <contact fullname="Erik Kline"/>,
        <contact fullname="Alexis La Goulette"/>,
        <contact fullname="Alex Roscoe"/>,
        <contact fullname="Darshak Thakore"/>,
        and <contact fullname="Vincent van Dam"/>.
      </t>
    </section>
    <section anchor="authors-addresses" numbered="false" removeInRFC="false" toc="include" pn="section-appendix.c">
      <name slugifiedName="name-authors-addresses">Authors' Addresses</name>
      <author fullname="Kyle Larose" initials="K." surname="Larose">
        <organization showOnFrontPage="true">Agilicus</organization>
        <address>
          <email>kyle@agilicus.com</email>
        </address>
      </author>
      <author fullname="David Dolson" initials="D." surname="Dolson">
        <address>
          <email>ddolson@acm.org</email>
        </address>
      </author>
      <author fullname="Heng Liu" initials="H." surname="Liu">
        <organization showOnFrontPage="true">Google</organization>
        <address>
          <email>liucougar@google.com</email>
        </address>
      </author>
    </section>
  </back>
</rfc>
