RFC 8908
Captive Portal API
RFC 8908: Captive Portal API π§β¨
okay bestie, RFC 8908 is the Captive Portal API πΈ It's a Standards Track doc from the IETF, dated September 2020, so it's a real, official spec, not a vibe π
π Title block tea: Written by T. Pauly, Ed. (Apple Inc.) and D. Thakore, Ed. (CableLabs). Category is Standards Track, ISSN 2070-1721. The header doesn't list anything it obsoletes or updates. This is part 1 of 3, so more is coming π«Ά
Abstract
This doc describes an HTTP API that lets clients talk to a Captive Portal system π With it, clients can figure out how to escape captivity and fetch the state of their Captive Portal sessions. Main character energy π
Status of This Memo
okay so this one's the official paperwork π
This is an Internet Standards Track document.
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). Further information on Internet Standards is available in Section 2 of RFC 7841.
Info about the current status of this doc, any errata, and how to send feedback can be found at https://www.rfc-editor.org/info/rfc8908 π
Copyright Notice
Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved. π
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) 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.
Table of Contents πΊοΈ
1. Introduction
2. Terminology
3. Workflow
4. API Connection Details
4.1. Server Authentication
5. API State Structure
6. Example Interaction
7. Security Considerations
7.1. Privacy Considerations
8. IANA Considerations
8.1. Captive Portal API JSON Media Type Registration
8.2. Captive Portal API Keys Registry
9. References
9.1. Normative References
9.2. Informative References
Acknowledgments
Authors' Addresses
1. Introduction β¨
okay so this doc describes a HyperText Transfer Protocol (HTTP) Application Programming Interface (API) that lets clients interact with a Captive Portal system π¦ The API was designed to meet the requirements in the Captive Portal Architecture [CAPPORT-ARCH]. Specifically, it gives you:
- The state of captivity, which is whether or not the client has access to the Internet.
- A URI for a user-facing web portal that you can use to get out of captivity.
- Authenticated and encrypted connections, using TLS for both the API and the user-facing web portal π
2. Terminology π
This doc uses the terms and components from [CAPPORT-ARCH] and also defines these:
Captive Portal Client The client that talks to the Captive Portal API is usually some app running on the user equipment that's connected to the captive network. In this doc it's also called the "client" π
Captive Portal API Server The server that exposes the APIs defined here to the client. In this doc it's also called the "API server" π₯οΈ
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. π―
3. Workflow π
The Captive Portal Architecture defines several categories of interaction between clients and Captive Portal systems:
- Provisioning, where a client finds out that a network has a captive portal and learns the URI of the API server.
- API Server interaction, where a client queries the state of captivity and gets the info it needs to get out of captivity.
- Enforcement, where the enforcement device in the network blocks disallowed traffic. π«
This doc defines the mechanisms used in the second category. It's assumed that the client has already found the location of the Captive Portal API server as part of provisioning. A set of mechanisms for discovering the API server endpoint is defined in [RFC8910] π§
4. API Connection Details π
The API server endpoint MUST be accessed over HTTP using an https URI [RFC2818] and SHOULD use the default https port. For example, if the Captive Portal API server is hosted at "example.org", the URI of the API could be https://example.org/captive-portal/api. π
The client SHOULD NOT assume that the URI of the API server for a given network will stay the same. It SHOULD rely on the discovery or provisioning process each time it joins the network. π
As described in Section 3 of [CAPPORT-ARCH], the identity of the client needs to be visible to the Captive Portal API server so the server can reply with the client's portal state correctly. If the identifier the Captive Portal system uses is the client's set of IP addresses, the system needs to make sure those same IP addresses are visible to both the API server and the enforcement device π
If the API server needs info about the client's identity that isn't otherwise visible to it, the URI given to the client during provisioning SHOULD be distinct per client. So depending on how the Captive Portal system is set up, the URI will be unique for each client host and between sessions for the same client host. β¨
For example, a Captive Portal system that uses per-client session URIs could use https://example.org/captive-portal/api/X54PD39JV as its API URI. π
4.1. Server Authentication π‘οΈ
Accessing the Captive Portal API over an HTTPS connection is a two-for-one deal π«Ά First, the encrypted connection protects the integrity and confidentiality of the API exchange from other parties on the local network. Second, it gives the client a chance to authenticate the server hosting the API. This authentication lets the client make sure the entity providing the Captive Portal API has a valid certificate for the hostname the network provisioned using the mechanisms in [RFC8910], by validating that a DNS-ID [RFC6125] on the certificate equals the provisioned hostname.
Clients doing revocation checking will need some way to access revocation info for the certificates the API server presents. Online Certificate Status Protocol [RFC6960] (OCSP) stapling, using the TLS Certificate Status Request extension [RFC6066], SHOULD be used. OCSP stapling lets a client do revocation checks without opening new connections π For other forms of revocation checking, especially for clients that don't support OCSP stapling, a captive network SHOULD permit connections to OCSP responders or Certificate Revocation Lists (CRLs) referenced by the certificates the API server provides. For more on certificate revocation checks, see Section 6.5 of BCP 195 [RFC7525]. Besides OCSP responders and CRLs, a captive network SHOULD also permit connections to Network Time Protocol (NTP) [RFC5905] servers or other time-sync mechanisms, so clients can accurately validate certificates. β°
Certificates with missing intermediate certificates that rely on clients validating the certificate chain using the URI in the Authority Information Access (AIA) extension [RFC5280] SHOULD NOT be used by the Captive Portal API server. If the certificates do need AIA, the captive network MUST allow client access to the host specified in that URI. π§
π¨ Big deal alert: If the client can't validate the certificate the API server presents, it MUST NOT proceed with any of the API interaction behavior described in this document. The client will go on interacting with the captive network as if the API capabilities weren't there at all. It may still be possible for the user to get on the network if the network redirects a cleartext webpage to a web portal π«
5. API State Structure π¦β¨
Okay so the Captive Portal API data is all written in JavaScript Object Notation (JSON) [RFC8259] π Requests and responses use the "application/captive+json" media type. Clients SHOULD put this media type in an Accept header on their GET requests π, and servers MUST mark it as their Content-Type header in responses π«Ά
There's one key that absolutely MUST show up at the top level of the JSON the API server sends back π
+=========+=========+============================================+
| Key | Type | Description |
+=========+=========+============================================+
| captive | boolean | Indicates whether the client is in a state |
| | | of captivity, i.e, it has not satisfied |
| | | the conditions to access the external |
| | | network. If the client is captive (i.e., |
| | | captive=true), it will still be allowed |
| | | enough access for it to perform server |
| | | authentication (Section 4.1). |
+---------+---------+--------------------------------------------+
Table 1
Then there are some optional keys that can also show up at the top level πΈ
+====================+=========+==================================+
| Key | Type | Description |
+====================+=========+==================================+
| user-portal-url | string | Provides the URL of a web portal |
| | | that MUST be accessed over TLS |
| | | with which a user can interact. |
+--------------------+---------+----------------------------------+
| venue-info-url | string | Provides the URL of a webpage or |
| | | site that SHOULD be accessed |
| | | over TLS on which the operator |
| | | of the network has information |
| | | that it wishes to share with the |
| | | user (e.g., store info, maps, |
| | | flight status, or |
| | | entertainment). |
+--------------------+---------+----------------------------------+
| can-extend-session | boolean | Indicates that the URL specified |
| | | as "user-portal-url" allows the |
| | | user to extend a session once |
| | | the client is no longer in a |
| | | state of captivity. This |
| | | provides a hint that a client |
| | | system can suggest accessing the |
| | | portal URL to the user when the |
| | | session is near its limit in |
| | | terms of time or bytes. |
+--------------------+---------+----------------------------------+
| seconds-remaining | number | An integer that indicates the |
| | | number of seconds remaining, |
| | | after which the client will be |
| | | placed into a captive state. |
| | | The API server SHOULD include |
| | | this value if the client is not |
| | | captive (i.e., captive=false) |
| | | and the client session is time- |
| | | limited and SHOULD omit this |
| | | value for captive clients (i.e., |
| | | captive=true) or when the |
| | | session is not time-limited. |
+--------------------+---------+----------------------------------+
| bytes-remaining | number | An integer that indicates the |
| | | number of bytes remaining, after |
| | | which the client will be placed |
| | | into a captive state. The byte |
| | | count represents the sum of the |
| | | total number of IP packet (layer |
| | | 3) bytes sent and received by |
| | | the client, including IP |
| | | headers. Captive Portal systems |
| | | might not count traffic to |
| | | whitelisted servers, such as the |
| | | API server, but clients cannot |
| | | rely on such behavior. The API |
| | | server SHOULD include this value |
| | | if the client is not captive |
| | | (i.e., captive=false) and the |
| | | client session is byte-limited |
| | | and SHOULD omit this value for |
| | | captive clients (i.e., |
| | | captive=true) or when the |
| | | session is not byte-limited. |
+--------------------+---------+----------------------------------+
Table 2
You can extend the valid JSON keys by adding entries to the Captive Portal API Keys Registry (Section 8.2) π§ If a client gets a key it doesn't recognize, it MUST ignore that key and any values attached to it π Every key that isn't defined in this document as "required" counts as optional, so no stress π
Captive Portal JSON can carry per-client data that really shouldn't be stored in an intermediary cache π So API servers SHOULD set the Cache-Control header field to "private" or something even stricter, like "no-store" [RFC7234] π
How often the client asks for fresh JSON is up to the implementation π€·ββοΈ It can be based on user interaction or on those seconds and bytes remaining numbers β±οΈ If at any point the client doesn't get valid JSON from the API server, whether because of an error or because nothing came back at all, it SHOULD keep using the most recent valid content it received. If it never received any content before, it SHOULD proceed to interact with the captive network as if the API capabilities weren't present π
6. Example Interaction π¦
Once a client connected to a captive network finds the URI of the API server, it asks the API server what its captive state is and what it needs to escape captivity π In this example, the client discovered https://example.org/captive-portal/api/X54PD39JV using one of the mechanisms defined in [RFC8910] π
To ask for the Captive Portal JSON content, the client sends an HTTP GET request π¨
GET /captive-portal/api/X54PD39JV HTTP/1.1
Host: example.org
Accept: application/captive+json
The server then answers with the JSON content for that client π
HTTP/1.1 200 OK
Cache-Control: private
Date: Mon, 02 Mar 2020 05:07:35 GMT
Content-Type: application/captive+json
{
"captive": true,
"user-portal-url": "https://example.org/portal.html"
}
Once the client has that info, it uses it to send the user to the web portal (the one named in the user-portal-url value) so they can get access to the external network πͺ After the user meets the requirements for external network access, the client SHOULD query the API server again to check that it's no longer captive β
When the client asks for the Captive Portal JSON content after getting external network access, the server responds with updated JSON content π
HTTP/1.1 200 OK
Cache-Control: private
Date: Mon, 02 Mar 2020 05:08:13 GMT
Content-Type: application/captive+json
{
"captive": false,
"user-portal-url": "https://example.org/portal.html",
"venue-info-url": "https://flight.example.com/entertainment",
"seconds-remaining": 326,
"can-extend-session": true
}
7. Security Considerations π
Making communication between client hosts and Captive Portal systems safer is one of the main goals of this protocol, so it's giving security glow-up π Client traffic is protected from passive listeners on the local network, because clients and the API server have to use TLS-encrypted connections, as Section 4 describes π‘οΈ All communication between the clients and the API server MUST be encrypted π
On top of encryption, this protocol asks for a basic level of authentication from the API server, as Section 4.1 describes π«‘ The API server MUST present a valid certificate that the client can run revocation checks on π That lets the client confirm the API server actually has authority for the hostname the network gave it through [RFC8910] β Just a heads up, though: this check only confirms the API server matches what the network's provisioning mechanism (like DHCP or IPv6 Router Advertisements) handed over. It doesn't validate the security of those provisioning mechanisms or the user's trust relationship with the network β οΈ
7.1. Privacy Considerations π΅οΈ
Info passed between a client and the user-facing web portal can include personal stuff like a full name and credit card details π³ So it's really important that both the user-facing web portal and the API server that points a client to the web portal are only accessed over encrypted connections π
Here's the tea, though π΅ Even though the web portal uses TLS, the authentication only checks that the web portal server matches the name in the URI the API server gave. Since the user never typed that name in, the hostname shown to them might contain "confusable characters" that can mislead them π¬ See Section 12.5 of [RFC8264] for more on confusable characters π
8. IANA Considerations π
IANA has registered the "application/captive+json" media type (Section 8.1) and created a registry for fields in that format (Section 8.2) π
8.1. Captive Portal API JSON Media Type Registration β¨
okay so this is the bit where we officially register the media type for Captive Portal API JSON text, which is application/captive+json π it's giving official paperwork energy but it's SO important for the vibe π
Type name: application
Subtype name: captive+json
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: Encoding considerations are identical to
those specified for the "application/json" media type.
Security considerations: See Section 7
Interoperability considerations: This document specifies format of
conforming messages and the interpretation thereof.
Published specification: RFC 8908
Applications that use this media type: This media type is intended
to be used by servers presenting the Captive Portal API, and
clients connecting to such captive networks.
Fragment identifier considerations: N/A
Additional Information: N/A
Person and email address to contact for further information:
See Authors' Addresses section
Intended usage: COMMON
Restrictions on usage: N/A
Author: CAPPORT IETF WG
Change controller: IETF
8.2. Captive Portal API Keys Registry π¦
so IANA is making a brand new registry called "Captive Portal API Keys" π§ its whole job is reserving JSON keys for the Captive Portal API data structures. the starter lineup lives in Section 5, so go check that out if you want the full guest list π
every entry in this registry has these fields:
Key: the JSON key being registered, written as a string πType: the type of the JSON value stored, picked from one of the value types defined in [RFC8259] πΈDescription: a short explanation of what the value means, how it might get used, and/or how clients should read it π«ΆReference: a pointer to a spec that defines the key and explains how to use it β¨
new entries get handed out by IANA under the Specification Required policy [RFC8126] ngl this is lowkey a pretty serious bouncer situation π the designated expert is expected to check that there's real documentation for the new key in a permanent, publicly available spec, like an Internet-Draft or an RFC π they're also expected to make sure the new key has a clear meaning and won't cause confusion or overlap with the keys that already exist π₯ and if a key is for a niche, non-generic use case, especially one that isn't part of an IETF document, it's encouraged to wear a domain-specific prefix π main character energy, but make it specific π
9. References π
9.1. Normative References
Okay bestie, these are the must-read-first references π they're the ones this document literally leans on.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818,
DOI 10.17487/RFC2818, May 2000,
<https://www.rfc-editor.org/info/rfc2818>.
[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
Housley, R., and W. Polk, "Internet X.509 Public Key
Infrastructure Certificate and Certificate Revocation List
(CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008,
<https://www.rfc-editor.org/info/rfc5280>.
[RFC5905] Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch,
"Network Time Protocol Version 4: Protocol and Algorithms
Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010,
<https://www.rfc-editor.org/info/rfc5905>.
[RFC6066] Eastlake 3rd, D., "Transport Layer Security (TLS)
Extensions: Extension Definitions", RFC 6066,
DOI 10.17487/RFC6066, January 2011,
<https://www.rfc-editor.org/info/rfc6066>.
[RFC6125] Saint-Andre, P. and J. Hodges, "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)", RFC 6125, DOI 10.17487/RFC6125, March
2011, <https://www.rfc-editor.org/info/rfc6125>.
[RFC6960] Santesson, S., Myers, M., Ankney, R., Malpani, A.,
Galperin, S., and C. Adams, "X.509 Internet Public Key
Infrastructure Online Certificate Status Protocol - OCSP",
RFC 6960, DOI 10.17487/RFC6960, June 2013,
<https://www.rfc-editor.org/info/rfc6960>.
[RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
RFC 7234, DOI 10.17487/RFC7234, June 2014,
<https://www.rfc-editor.org/info/rfc7234>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>.
9.2. Informative References
These ones are extra reading for the curious π€ useful background, not required homework.
[CAPPORT-ARCH]
Larose, K., Dolson, D., and H. Liu, "CAPPORT
Architecture", Work in Progress, Internet-Draft, draft-
ietf-capport-architecture-08, 11 May 2020,
<https://tools.ietf.org/html/draft-ietf-capport-
architecture-08>.
[RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre,
"Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May
2015, <https://www.rfc-editor.org/info/rfc7525>.
[RFC8264] Saint-Andre, P. and M. Blanchet, "PRECIS Framework:
Preparation, Enforcement, and Comparison of
Internationalized Strings in Application Protocols",
RFC 8264, DOI 10.17487/RFC8264, October 2017,
<https://www.rfc-editor.org/info/rfc8264>.
[RFC8910] Kumari, W. and E. Kline, "Captive-Portal Identification in
DHCP and Router Advertisement (RA)", RFC 8910,
DOI 10.17487/RFC8910, September 2020,
<https://www.rfc-editor.org/info/rfc8910>.
Acknowledgments π
this work was kicked off by Mark Donnelly and Margaret Cullen π«Ά huge thank-you to everyone in the CAPPORT Working Group who dropped their input. you all literally made this happen π
Authors' Addresses πΈ
here's where to find the editors if you have questions π
Tommy Pauly (editor)
Apple Inc.
One Apple Park Way
Cupertino, CA 95014
United States of America
Email: tpauly@apple.com
Darshak Thakore (editor)
CableLabs
858 Coal Creek Circle
Louisville, CO 80027
United States of America
Email: d.thakore@cablelabs.com
π¦ where this page comes from
- ietf: rfc8908 2020-09
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms