File: rfc8952.html

package info (click to toggle)
doc-rfc 20230121-1
  • links: PTS, VCS
  • area: non-free
  • in suites: bookworm, forky, sid, trixie
  • size: 1,609,944 kB
file content (2611 lines) | stat: -rw-r--r-- 121,569 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
<!DOCTYPE html>
<html lang="en" class="RFC">
<head>
<meta charset="utf-8">
<meta content="Common,Latin" name="scripts">
<meta content="initial-scale=1.0" name="viewport">
<title>RFC 8952: Captive Portal Architecture</title>
<meta content="Kyle Larose" name="author">
<meta content="David Dolson" name="author">
<meta content="Heng Liu" name="author">
<meta content="
       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.
       
    " name="description">
<meta content="xml2rfc 3.5.0" name="generator">
<meta content="Captive Portal" name="keyword">
<meta content="Architecture" name="keyword">
<meta content="Wifi" name="keyword">
<meta content="Wi-Fi" name="keyword">
<meta content="Wireless" name="keyword">
<meta content="Roaming" name="keyword">
<meta content="Mobile" name="keyword">
<meta content="API" name="keyword">
<meta content="8952" name="rfc.number">
<!-- Generator version information:
  xml2rfc 3.5.0
    Python 3.6.10
    appdirs 1.4.4
    ConfigArgParse 1.2.3
    google-i18n-address 2.3.5
    html5lib 1.0.1
    intervaltree 3.0.2
    Jinja2 2.11.2
    kitchen 1.2.6
    lxml 4.4.2
    pycairo 1.19.0
    pycountry 19.8.18
    pyflakes 2.1.1
    PyYAML 5.3.1
    requests 2.22.0
    setuptools 40.6.2
    six 1.14.0
    WeasyPrint 51
-->
<link href="rfc8952.xml" rel="alternate" type="application/rfc+xml">
<link href="#copyright" rel="license">
<style type="text/css">/*

  NOTE: Changes at the bottom of this file overrides some earlier settings.

  Once the style has stabilized and has been adopted as an official RFC style,
  this can be consolidated so that style settings occur only in one place, but
  for now the contents of this file consists first of the initial CSS work as
  provided to the RFC Formatter (xml2rfc) work, followed by itemized and
  commented changes found necssary during the development of the v3
  formatters.

*/

/* fonts */
@import url('https://fonts.googleapis.com/css?family=Noto+Sans'); /* Sans-serif */
@import url('https://fonts.googleapis.com/css?family=Noto+Serif'); /* Serif (print) */
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono'); /* Monospace */

@viewport {
  zoom: 1.0;
  width: extend-to-zoom;
}
@-ms-viewport {
  width: extend-to-zoom;
  zoom: 1.0;
}
/* general and mobile first */
html {
}
body {
  max-width: 90%;
  margin: 1.5em auto;
  color: #222;
  background-color: #fff;
  font-size: 14px;
  font-family: 'Noto Sans', Arial, Helvetica, sans-serif;
  line-height: 1.6;
  scroll-behavior: smooth;
}
.ears {
  display: none;
}

/* headings */
#title, h1, h2, h3, h4, h5, h6 {
  margin: 1em 0 0.5em;
  font-weight: bold;
  line-height: 1.3;
}
#title {
  clear: both;
  border-bottom: 1px solid #ddd;
  margin: 0 0 0.5em 0;
  padding: 1em 0 0.5em;
}
.author {
  padding-bottom: 4px;
}
h1 {
  font-size: 26px;
  margin: 1em 0;
}
h2 {
  font-size: 22px;
  margin-top: -20px;  /* provide offset for in-page anchors */
  padding-top: 33px;
}
h3 {
  font-size: 18px;
  margin-top: -36px;  /* provide offset for in-page anchors */
  padding-top: 42px;
}
h4 {
  font-size: 16px;
  margin-top: -36px;  /* provide offset for in-page anchors */
  padding-top: 42px;
}
h5, h6 {
  font-size: 14px;
}
#n-copyright-notice {
  border-bottom: 1px solid #ddd;
  padding-bottom: 1em;
  margin-bottom: 1em;
}
/* general structure */
p {
  padding: 0;
  margin: 0 0 1em 0;
  text-align: left;
}
div, span {
  position: relative;
}
div {
  margin: 0;
}
.alignRight.art-text {
  background-color: #f9f9f9;
  border: 1px solid #eee;
  border-radius: 3px;
  padding: 1em 1em 0;
  margin-bottom: 1.5em;
}
.alignRight.art-text pre {
  padding: 0;
}
.alignRight {
  margin: 1em 0;
}
.alignRight > *:first-child {
  border: none;
  margin: 0;
  float: right;
  clear: both;
}
.alignRight > *:nth-child(2) {
  clear: both;
  display: block;
  border: none;
}
svg {
  display: block;
}
.alignCenter.art-text {
  background-color: #f9f9f9;
  border: 1px solid #eee;
  border-radius: 3px;
  padding: 1em 1em 0;
  margin-bottom: 1.5em;
}
.alignCenter.art-text pre {
  padding: 0;
}
.alignCenter {
  margin: 1em 0;
}
.alignCenter > *:first-child {
  border: none;
  /* this isn't optimal, but it's an existence proof.  PrinceXML doesn't
     support flexbox yet.
  */
  display: table;
  margin: 0 auto;
}

/* lists */
ol, ul {
  padding: 0;
  margin: 0 0 1em 2em;
}
ol ol, ul ul, ol ul, ul ol {
  margin-left: 1em;
}
li {
  margin: 0 0 0.25em 0;
}
.ulCompact li {
  margin: 0;
}
ul.empty, .ulEmpty {
  list-style-type: none;
}
ul.empty li, .ulEmpty li {
  margin-top: 0.5em;
}
ul.compact, .ulCompact,
ol.compact, .olCompact {
  line-height: 100%;
  margin: 0 0 0 2em;
}

/* definition lists */
dl {
}
dl > dt {
  float: left;
  margin-right: 1em;
}
/* 
dl.nohang > dt {
  float: none;
}
*/
dl > dd {
  margin-bottom: .8em;
  min-height: 1.3em;
}
dl.compact > dd, .dlCompact > dd {
  margin-bottom: 0em;
}
dl > dd > dl {
  margin-top: 0.5em;
  margin-bottom: 0em;
}

/* links */
a {
  text-decoration: none;
}
a[href] {
  color: #22e; /* Arlen: WCAG 2019 */
}
a[href]:hover {
  background-color: #f2f2f2;
}
figcaption a[href],
a[href].selfRef {
  color: #222;
}
/* XXX probably not this:
a.selfRef:hover {
  background-color: transparent;
  cursor: default;
} */

/* Figures */
tt, code, pre, code {
  background-color: #f9f9f9;
  font-family: 'Roboto Mono', monospace;
}
pre {
  border: 1px solid #eee;
  margin: 0;
  padding: 1em;
}
img {
  max-width: 100%;
}
figure {
  margin: 0;
}
figure blockquote {
  margin: 0.8em 0.4em 0.4em;
}
figcaption {
  font-style: italic;
  margin: 0 0 1em 0;
}
@media screen {
  pre {
    overflow-x: auto;
    max-width: 100%;
    max-width: calc(100% - 22px);
  }
}

/* aside, blockquote */
aside, blockquote {
  margin-left: 0;
  padding: 1.2em 2em;
}
blockquote {
  background-color: #f9f9f9;
  color: #111; /* Arlen: WCAG 2019 */
  border: 1px solid #ddd;
  border-radius: 3px;
  margin: 1em 0;
}
cite {
  display: block;
  text-align: right;
  font-style: italic;
}

/* tables */
table {
  width: 100%;
  margin: 0 0 1em;
  border-collapse: collapse;
  border: 1px solid #eee;
}
th, td {
  text-align: left;
  vertical-align: top;
  padding: 0.5em 0.75em;
}
th {
  text-align: left;
  background-color: #e9e9e9;
}
tr:nth-child(2n+1) > td {
  background-color: #f5f5f5;
}
table caption {
  font-style: italic;
  margin: 0;
  padding: 0;
  text-align: left;
}
table p {
  /* XXX to avoid bottom margin on table row signifiers. If paragraphs should
     be allowed within tables more generally, it would be far better to select on a class. */
  margin: 0;
}

/* pilcrow */
a.pilcrow {
  color: #666; /* Arlen: AHDJ 2019 */
  text-decoration: none;
  visibility: hidden;
  user-select: none;
  -ms-user-select: none;
  -o-user-select:none;
  -moz-user-select: none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
@media screen {
  aside:hover > a.pilcrow,
  p:hover > a.pilcrow,
  blockquote:hover > a.pilcrow,
  div:hover > a.pilcrow,
  li:hover > a.pilcrow,
  pre:hover > a.pilcrow {
    visibility: visible;
  }
  a.pilcrow:hover {
    background-color: transparent;
  }
}

/* misc */
hr {
  border: 0;
  border-top: 1px solid #eee;
}
.bcp14 {
  font-variant: small-caps;
}

.role {
  font-variant: all-small-caps;
}

/* info block */
#identifiers {
  margin: 0;
  font-size: 0.9em;
}
#identifiers dt {
  width: 3em;
  clear: left;
}
#identifiers dd {
  float: left;
  margin-bottom: 0;
}
#identifiers .authors .author {
  display: inline-block;
  margin-right: 1.5em;
}
#identifiers .authors .org {
  font-style: italic;
}

/* The prepared/rendered info at the very bottom of the page */
.docInfo {
  color: #666; /* Arlen: WCAG 2019 */
  font-size: 0.9em;
  font-style: italic;
  margin-top: 2em;
}
.docInfo .prepared {
  float: left;
}
.docInfo .prepared {
  float: right;
}

/* table of contents */
#toc  {
  padding: 0.75em 0 2em 0;
  margin-bottom: 1em;
}
nav.toc ul {
  margin: 0 0.5em 0 0;
  padding: 0;
  list-style: none;
}
nav.toc li {
  line-height: 1.3em;
  margin: 0.75em 0;
  padding-left: 1.2em;
  text-indent: -1.2em;
}
/* references */
.references dt {
  text-align: right;
  font-weight: bold;
  min-width: 7em;
}
.references dd {
  margin-left: 8em;
  overflow: auto;
}

.refInstance {
  margin-bottom: 1.25em;
}

.references .ascii {
  margin-bottom: 0.25em;
}

/* index */
.index ul {
  margin: 0 0 0 1em;
  padding: 0;
  list-style: none;
}
.index ul ul {
  margin: 0;
}
.index li {
  margin: 0;
  text-indent: -2em;
  padding-left: 2em;
  padding-bottom: 5px;
}
.indexIndex {
  margin: 0.5em 0 1em;
}
.index a {
  font-weight: 700;
}
/* make the index two-column on all but the smallest screens */
@media (min-width: 600px) {
  .index ul {
    -moz-column-count: 2;
    -moz-column-gap: 20px;
  }
  .index ul ul {
    -moz-column-count: 1;
    -moz-column-gap: 0;
  }
}

/* authors */
address.vcard {
  font-style: normal;
  margin: 1em 0;
}

address.vcard .nameRole {
  font-weight: 700;
  margin-left: 0;
}
address.vcard .label {
  font-family: "Noto Sans",Arial,Helvetica,sans-serif;
  margin: 0.5em 0;
}
address.vcard .type {
  display: none;
}
.alternative-contact {
  margin: 1.5em 0 1em;
}
hr.addr {
  border-top: 1px dashed;
  margin: 0;
  color: #ddd;
  max-width: calc(100% - 16px);
}

/* temporary notes */
.rfcEditorRemove::before {
  position: absolute;
  top: 0.2em;
  right: 0.2em;
  padding: 0.2em;
  content: "The RFC Editor will remove this note";
  color: #9e2a00; /* Arlen: WCAG 2019 */
  background-color: #ffd; /* Arlen: WCAG 2019 */
}
.rfcEditorRemove {
  position: relative;
  padding-top: 1.8em;
  background-color: #ffd; /* Arlen: WCAG 2019 */
  border-radius: 3px;
}
.cref {
  background-color: #ffd; /* Arlen: WCAG 2019 */
  padding: 2px 4px;
}
.crefSource {
  font-style: italic;
}
/* alternative layout for smaller screens */
@media screen and (max-width: 1023px) {
  body {
    padding-top: 2em;
  }
  #title {
    padding: 1em 0;
  }
  h1 {
    font-size: 24px;
  }
  h2 {
    font-size: 20px;
    margin-top: -18px;  /* provide offset for in-page anchors */
    padding-top: 38px;
  }
  #identifiers dd {
    max-width: 60%;
  }
  #toc {
    position: fixed;
    z-index: 2;
    top: 0;
    right: 0;
    padding: 0;
    margin: 0;
    background-color: inherit;
    border-bottom: 1px solid #ccc;
  }
  #toc h2 {
    margin: -1px 0 0 0;
    padding: 4px 0 4px 6px;
    padding-right: 1em;
    min-width: 190px;
    font-size: 1.1em;
    text-align: right;
    background-color: #444;
    color: white;
    cursor: pointer;
  }
  #toc h2::before { /* css hamburger */
    float: right;
    position: relative;
    width: 1em;
    height: 1px;
    left: -164px;
    margin: 6px 0 0 0;
    background: white none repeat scroll 0 0;
    box-shadow: 0 4px 0 0 white, 0 8px 0 0 white;
    content: "";
  }
  #toc nav {
    display: none;
    padding: 0.5em 1em 1em;
    overflow: auto;
    height: calc(100vh - 48px);
    border-left: 1px solid #ddd;
  }
}

/* alternative layout for wide screens */
@media screen and (min-width: 1024px) {
  body {
    max-width: 724px;
    margin: 42px auto;
    padding-left: 1.5em;
    padding-right: 29em;
  }
  #toc {
    position: fixed;
    top: 42px;
    right: 42px;
    width: 25%;
    margin: 0;
    padding: 0 1em;
    z-index: 1;
  }
  #toc h2 {
    border-top: none;
    border-bottom: 1px solid #ddd;
    font-size: 1em;
    font-weight: normal;
    margin: 0;
    padding: 0.25em 1em 1em 0;
  }
  #toc nav {
    display: block;
    height: calc(90vh - 84px);
    bottom: 0;
    padding: 0.5em 0 0;
    overflow: auto;
  }
  img { /* future proofing */
    max-width: 100%;
    height: auto;
  }
}

/* pagination */
@media print {
  body {

    width: 100%;
  }
  p {
    orphans: 3;
    widows: 3;
  }
  #n-copyright-notice {
    border-bottom: none;
  }
  #toc, #n-introduction {
    page-break-before: always;
  }
  #toc {
    border-top: none;
    padding-top: 0;
  }
  figure, pre {
    page-break-inside: avoid;
  }
  figure {
    overflow: scroll;
  }
  h1, h2, h3, h4, h5, h6 {
    page-break-after: avoid;
  }
  h2+*, h3+*, h4+*, h5+*, h6+* {
    page-break-before: avoid;
  }
  pre {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-size: 10pt;
  }
  table {
    border: 1px solid #ddd;
  }
  td {
    border-top: 1px solid #ddd;
  }
}

/* This is commented out here, as the string-set: doesn't
   pass W3C validation currently */
/*
.ears thead .left {
  string-set: ears-top-left content();
}

.ears thead .center {
  string-set: ears-top-center content();
}

.ears thead .right {
  string-set: ears-top-right content();
}

.ears tfoot .left {
  string-set: ears-bottom-left content();
}

.ears tfoot .center {
  string-set: ears-bottom-center content();
}

.ears tfoot .right {
  string-set: ears-bottom-right content();
}
*/

@page :first {
  padding-top: 0;
  @top-left {
    content: normal;
    border: none;
  }
  @top-center {
    content: normal;
    border: none;
  }
  @top-right {
    content: normal;
    border: none;
  }
}

@page {
  size: A4;
  margin-bottom: 45mm;
  padding-top: 20px;
  /* The follwing is commented out here, but set appropriately by in code, as
     the content depends on the document */
  /*
  @top-left {
    content: 'Internet-Draft';
    vertical-align: bottom;
    border-bottom: solid 1px #ccc;
  }
  @top-left {
    content: string(ears-top-left);
    vertical-align: bottom;
    border-bottom: solid 1px #ccc;
  }
  @top-center {
    content: string(ears-top-center);
    vertical-align: bottom;
    border-bottom: solid 1px #ccc;
  }
  @top-right {
    content: string(ears-top-right);
    vertical-align: bottom;
    border-bottom: solid 1px #ccc;
  }
  @bottom-left {
    content: string(ears-bottom-left);
    vertical-align: top;
    border-top: solid 1px #ccc;
  }
  @bottom-center {
    content: string(ears-bottom-center);
    vertical-align: top;
    border-top: solid 1px #ccc;
  }
  @bottom-right {
      content: '[Page ' counter(page) ']';
      vertical-align: top;
      border-top: solid 1px #ccc;
  }
  */

}

/* Changes introduced to fix issues found during implementation */
/* Make sure links are clickable even if overlapped by following H* */
a {
  z-index: 2;
}
/* Separate body from document info even without intervening H1 */
section {
  clear: both;
}


/* Top align author divs, to avoid names without organization dropping level with org names */
.author {
  vertical-align: top;
}

/* Leave room in document info to show Internet-Draft on one line */
#identifiers dt {
  width: 8em;
}

/* Don't waste quite as much whitespace between label and value in doc info */
#identifiers dd {
  margin-left: 1em;
}

/* Give floating toc a background color (needed when it's a div inside section */
#toc {
  background-color: white;
}

/* Make the collapsed ToC header render white on gray also when it's a link */
@media screen and (max-width: 1023px) {
  #toc h2 a,
  #toc h2 a:link,
  #toc h2 a:focus,
  #toc h2 a:hover,
  #toc a.toplink,
  #toc a.toplink:hover {
    color: white;
    background-color: #444;
    text-decoration: none;
  }
}

/* Give the bottom of the ToC some whitespace */
@media screen and (min-width: 1024px) {
  #toc {
    padding: 0 0 1em 1em;
  }
}

/* Style section numbers with more space between number and title */
.section-number {
  padding-right: 0.5em;
}

/* prevent monospace from becoming overly large */
tt, code, pre, code {
  font-size: 95%;
}

/* Fix the height/width aspect for ascii art*/
pre.sourcecode,
.art-text pre {
  line-height: 1.12;
}


/* Add styling for a link in the ToC that points to the top of the document */
a.toplink {
  float: right;
  margin-right: 0.5em;
}

/* Fix the dl styling to match the RFC 7992 attributes */
dl > dt,
dl.dlParallel > dt {
  float: left;
  margin-right: 1em;
}
dl.dlNewline > dt {
  float: none;
}

/* Provide styling for table cell text alignment */
table td.text-left,
table th.text-left {
  text-align: left;
}
table td.text-center,
table th.text-center {
  text-align: center;
}
table td.text-right,
table th.text-right {
  text-align: right;
}

/* Make the alternative author contact informatio look less like just another
   author, and group it closer with the primary author contact information */
.alternative-contact {
  margin: 0.5em 0 0.25em 0;
}
address .non-ascii {
  margin: 0 0 0 2em;
}

/* With it being possible to set tables with alignment
  left, center, and right, { width: 100%; } does not make sense */
table {
  width: auto;
}

/* Avoid reference text that sits in a block with very wide left margin,
   because of a long floating dt label.*/
.references dd {
  overflow: visible;
}

/* Control caption placement */
caption {
  caption-side: bottom;
}

/* Limit the width of the author address vcard, so names in right-to-left
   script don't end up on the other side of the page. */

address.vcard {
  max-width: 30em;
  margin-right: auto;
}

/* For address alignment dependent on LTR or RTL scripts */
address div.left {
  text-align: left;
}
address div.right {
  text-align: right;
}

/* Provide table alignment support.  We can't use the alignX classes above
   since they do unwanted things with caption and other styling. */
table.right {
 margin-left: auto;
 margin-right: 0;
}
table.center {
 margin-left: auto;
 margin-right: auto;
}
table.left {
 margin-left: 0;
 margin-right: auto;
}

/* Give the table caption label the same styling as the figcaption */
caption a[href] {
  color: #222;
}

@media print {
  .toplink {
    display: none;
  }

  /* avoid overwriting the top border line with the ToC header */
  #toc {
    padding-top: 1px;
  }

  /* Avoid page breaks inside dl and author address entries */
  .vcard {
    page-break-inside: avoid;
  }

}
/* Tweak the bcp14 keyword presentation */
.bcp14 {
  font-variant: small-caps;
  font-weight: bold;
  font-size: 0.9em;
}
/* Tweak the invisible space above H* in order not to overlay links in text above */
 h2 {
  margin-top: -18px;  /* provide offset for in-page anchors */
  padding-top: 31px;
 }
 h3 {
  margin-top: -18px;  /* provide offset for in-page anchors */
  padding-top: 24px;
 }
 h4 {
  margin-top: -18px;  /* provide offset for in-page anchors */
  padding-top: 24px;
 }
/* Float artwork pilcrow to the right */
@media screen {
  .artwork a.pilcrow {
    display: block;
    line-height: 0.7;
    margin-top: 0.15em;
  }
}
/* Make pilcrows on dd visible */
@media screen {
  dd:hover > a.pilcrow {
    visibility: visible;
  }
}
/* Make the placement of figcaption match that of a table's caption
   by removing the figure's added bottom margin */
.alignLeft.art-text,
.alignCenter.art-text,
.alignRight.art-text {
   margin-bottom: 0;
}
.alignLeft,
.alignCenter,
.alignRight {
  margin: 1em 0 0 0;
}
/* In print, the pilcrow won't show on hover, so prevent it from taking up space,
   possibly even requiring a new line */
@media print {
  a.pilcrow {
    display: none;
  }
}
/* Styling for the external metadata */
div#external-metadata {
  background-color: #eee;
  padding: 0.5em;
  margin-bottom: 0.5em;
  display: none;
}
div#internal-metadata {
  padding: 0.5em;                       /* to match the external-metadata padding */
}
/* Styling for title RFC Number */
h1#rfcnum {
  clear: both;
  margin: 0 0 -1em;
  padding: 1em 0 0 0;
}
/* Make .olPercent look the same as <ol><li> */
dl.olPercent > dd {
  margin-bottom: 0.25em;
  min-height: initial;
}
/* Give aside some styling to set it apart */
aside {
  border-left: 1px solid #ddd;
  margin: 1em 0 1em 2em;
  padding: 0.2em 2em;
}
aside > dl,
aside > ol,
aside > ul,
aside > table,
aside > p {
  margin-bottom: 0.5em;
}
/* Additional page break settings */
@media print {
  figcaption, table caption {
    page-break-before: avoid;
  }
}
/* Font size adjustments for print */
@media print {
  body  { font-size: 10pt;      line-height: normal; max-width: 96%; }
  h1    { font-size: 1.72em;    padding-top: 1.5em; } /* 1*1.2*1.2*1.2 */
  h2    { font-size: 1.44em;    padding-top: 1.5em; } /* 1*1.2*1.2 */
  h3    { font-size: 1.2em;     padding-top: 1.5em; } /* 1*1.2 */
  h4    { font-size: 1em;       padding-top: 1.5em; }
  h5, h6 { font-size: 1em;      margin: initial; padding: 0.5em 0 0.3em; }
}
/* Sourcecode margin in print, when there's no pilcrow */
@media print {
  .artwork,
  .sourcecode {
    margin-bottom: 1em;
  }
}
/* Avoid narrow tables forcing too narrow table captions, which may render badly */
table {
  min-width: 20em;
}
/* ol type a */
ol.type-a { list-style-type: lower-alpha; }
ol.type-A { list-style-type: upper-alpha; }
ol.type-i { list-style-type: lower-roman; }
ol.type-I { list-style-type: lower-roman; }
/* Apply the print table and row borders in general, on request from the RPC,
and increase the contrast between border and odd row background sligthtly */
table {
  border: 1px solid #ddd;
}
td {
  border-top: 1px solid #ddd;
}
tr:nth-child(2n+1) > td {
  background-color: #f8f8f8;
}
/* Use style rules to govern display of the TOC. */
@media screen and (max-width: 1023px) {
  #toc nav { display: none; }
  #toc.active nav { display: block; }
}
/* Add support for keepWithNext */
.keepWithNext {
  break-after: avoid-page;
  break-after: avoid-page;
}
/* Add support for keepWithPrevious */
.keepWithPrevious {
  break-before: avoid-page;
}
/* Change the approach to avoiding breaks inside artwork etc. */
figure, pre, table, .artwork, .sourcecode  {
  break-before: avoid-page;
  break-after: auto;
}
/* Avoid breaks between <dt> and <dd> */
dl {
  break-before: auto;
  break-inside: auto;
}
dt {
  break-before: auto;
  break-after: avoid-page;
}
dd {
  break-before: avoid-page;
  break-after: auto;
  orphans: 3;
  widows: 3
}
span.break, dd.break {
  margin-bottom: 0;
  min-height: 0;
  break-before: auto;
  break-inside: auto;
  break-after: auto;
}
/* Undo break-before ToC */
@media print {
  #toc {
    break-before: auto;
  }
}
/* Text in compact lists should not get extra bottim margin space,
   since that would makes the list not compact */
ul.compact p, .ulCompact p,
ol.compact p, .olCompact p {
 margin: 0;
}
/* But the list as a whole needs the extra space at the end */
section ul.compact,
section .ulCompact,
section ol.compact,
section .olCompact {
  margin-bottom: 1em;                    /* same as p not within ul.compact etc. */
}
/* The tt and code background above interferes with for instance table cell
   backgrounds.  Changed to something a bit more selective. */
tt, code {
  background-color: transparent;
}
p tt, p code, li tt, li code {
  background-color: #f8f8f8;
}
/* Tweak the pre margin -- 0px doesn't come out well */
pre {
   margin-top: 0.5px;
}
/* Tweak the comact list text */
ul.compact, .ulCompact,
ol.compact, .olCompact,
dl.compact, .dlCompact {
  line-height: normal;
}
/* Don't add top margin for nested lists */
li > ul, li > ol, li > dl,
dd > ul, dd > ol, dd > dl,
dl > dd > dl {
  margin-top: initial;
}
/* Elements that should not be rendered on the same line as a <dt> */
/* This should match the element list in writer.text.TextWriter.render_dl() */
dd > div.artwork:first-child,
dd > aside:first-child,
dd > figure:first-child,
dd > ol:first-child,
dd > div:first-child > pre.sourcecode,
dd > table:first-child,
dd > ul:first-child {
  clear: left;
}
/* fix for weird browser behaviour when <dd/> is empty */
dt+dd:empty::before{
  content: "\00a0";
}
</style>
<link href="rfc-local.css" rel="stylesheet" type="text/css">
<link href="https://dx.doi.org/10.17487/rfc8952" rel="alternate">
  <link href="urn:issn:2070-1721" rel="alternate">
  <link href="https://datatracker.ietf.org/doc/draft-ietf-capport-architecture-10" rel="prev">
  </head>
<body>
<script src="https://www.rfc-editor.org/js/metadata.min.js"></script>
<table class="ears">
<thead><tr>
<td class="left">RFC 8952</td>
<td class="center">Captive Portal Architecture</td>
<td class="right">November 2020</td>
</tr></thead>
<tfoot><tr>
<td class="left">Larose, et al.</td>
<td class="center">Informational</td>
<td class="right">[Page]</td>
</tr></tfoot>
</table>
<div id="external-metadata" class="document-information"></div>
<div id="internal-metadata" class="document-information">
<dl id="identifiers">
<dt class="label-stream">Stream:</dt>
<dd class="stream">Internet Engineering Task Force (IETF)</dd>
<dt class="label-rfc">RFC:</dt>
<dd class="rfc"><a href="https://www.rfc-editor.org/rfc/rfc8952" class="eref">8952</a></dd>
<dt class="label-category">Category:</dt>
<dd class="category">Informational</dd>
<dt class="label-published">Published:</dt>
<dd class="published">
<time datetime="2020-11" class="published">November 2020</time>
    </dd>
<dt class="label-issn">ISSN:</dt>
<dd class="issn">2070-1721</dd>
<dt class="label-authors">Authors:</dt>
<dd class="authors">
<div class="author">
      <div class="author-name">K. Larose</div>
<div class="org">Agilicus</div>
</div>
<div class="author">
      <div class="author-name">D. Dolson</div>
</div>
<div class="author">
      <div class="author-name">H. Liu</div>
<div class="org">Google</div>
</div>
</dd>
</dl>
</div>
<h1 id="rfcnum">RFC 8952</h1>
<h1 id="title">Captive Portal Architecture</h1>
<section id="section-abstract">
      <h2 id="abstract"><a href="#abstract" class="selfRef">Abstract</a></h2>
<p id="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.<a href="#section-abstract-1" class="pilcrow">¶</a></p>
</section>
<div id="status-of-memo">
<section id="section-boilerplate.1">
        <h2 id="name-status-of-this-memo">
<a href="#name-status-of-this-memo" class="section-name selfRef">Status of This Memo</a>
        </h2>
<p id="section-boilerplate.1-1">
            This document is not an Internet Standards Track specification; it is
            published for informational purposes.<a href="#section-boilerplate.1-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-boilerplate.1-2" class="pilcrow">¶</a></p>
<p id="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
            <span><a href="https://www.rfc-editor.org/info/rfc8952">https://www.rfc-editor.org/info/rfc8952</a></span>.<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p>
</section>
</div>
<div id="copyright">
<section id="section-boilerplate.2">
        <h2 id="name-copyright-notice">
<a href="#name-copyright-notice" class="section-name selfRef">Copyright Notice</a>
        </h2>
<p id="section-boilerplate.2-1">
            Copyright (c) 2020 IETF Trust and the persons identified as the
            document authors. All rights reserved.<a href="#section-boilerplate.2-1" class="pilcrow">¶</a></p>
<p id="section-boilerplate.2-2">
            This document is subject to BCP 78 and the IETF Trust's Legal
            Provisions Relating to IETF Documents
            (<span><a href="https://trustee.ietf.org/license-info">https://trustee.ietf.org/license-info</a></span>) 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.<a href="#section-boilerplate.2-2" class="pilcrow">¶</a></p>
</section>
</div>
<div id="toc">
<section id="section-toc.1">
        <a href="#" onclick="scroll(0,0)" class="toplink">▲</a><h2 id="name-table-of-contents">
<a href="#name-table-of-contents" class="section-name selfRef">Table of Contents</a>
        </h2>
<nav class="toc"><ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.1">
            <p id="section-toc.1-1.1.1" class="keepWithNext"><a href="#section-1" class="xref">1</a>.  <a href="#name-introduction" class="xref">Introduction</a><a href="#section-toc.1-1.1.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.1.2.1">
                <p id="section-toc.1-1.1.2.1.1" class="keepWithNext"><a href="#section-1.1" class="xref">1.1</a>.  <a href="#name-requirements-language" class="xref">Requirements Language</a><a href="#section-toc.1-1.1.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.1.2.2">
                <p id="section-toc.1-1.1.2.2.1" class="keepWithNext"><a href="#section-1.2" class="xref">1.2</a>.  <a href="#name-terminology" class="xref">Terminology</a><a href="#section-toc.1-1.1.2.2.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.2">
            <p id="section-toc.1-1.2.1"><a href="#section-2" class="xref">2</a>.  <a href="#name-components" class="xref">Components</a><a href="#section-toc.1-1.2.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.2.2.1">
                <p id="section-toc.1-1.2.2.1.1"><a href="#section-2.1" class="xref">2.1</a>.  <a href="#name-user-equipment" class="xref">User Equipment</a><a href="#section-toc.1-1.2.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.2">
                <p id="section-toc.1-1.2.2.2.1"><a href="#section-2.2" class="xref">2.2</a>.  <a href="#name-provisioning-service" class="xref">Provisioning Service</a><a href="#section-toc.1-1.2.2.2.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.2.2.2.2.1">
                    <p id="section-toc.1-1.2.2.2.2.1.1"><a href="#section-2.2.1" class="xref">2.2.1</a>.  <a href="#name-dhcp-or-router-advertisemen" class="xref">DHCP or Router Advertisements</a><a href="#section-toc.1-1.2.2.2.2.1.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.2.2.2">
                    <p id="section-toc.1-1.2.2.2.2.2.1"><a href="#section-2.2.2" class="xref">2.2.2</a>.  <a href="#name-provisioning-domains" class="xref">Provisioning Domains</a><a href="#section-toc.1-1.2.2.2.2.2.1" class="pilcrow">¶</a></p>
</li>
                </ul>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.3">
                <p id="section-toc.1-1.2.2.3.1"><a href="#section-2.3" class="xref">2.3</a>.  <a href="#name-captive-portal-api-server" class="xref">Captive Portal API Server</a><a href="#section-toc.1-1.2.2.3.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.4">
                <p id="section-toc.1-1.2.2.4.1"><a href="#section-2.4" class="xref">2.4</a>.  <a href="#name-captive-portal-enforcement-" class="xref">Captive Portal Enforcement Device</a><a href="#section-toc.1-1.2.2.4.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.5">
                <p id="section-toc.1-1.2.2.5.1"><a href="#section-2.5" class="xref">2.5</a>.  <a href="#name-captive-portal-signal" class="xref">Captive Portal Signal</a><a href="#section-toc.1-1.2.2.5.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.2.2.6">
                <p id="section-toc.1-1.2.2.6.1"><a href="#section-2.6" class="xref">2.6</a>.  <a href="#name-component-diagram" class="xref">Component Diagram</a><a href="#section-toc.1-1.2.2.6.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.3">
            <p id="section-toc.1-1.3.1"><a href="#section-3" class="xref">3</a>.  <a href="#name-user-equipment-identity" class="xref">User Equipment Identity</a><a href="#section-toc.1-1.3.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.3.2.1">
                <p id="section-toc.1-1.3.2.1.1"><a href="#section-3.1" class="xref">3.1</a>.  <a href="#name-identifiers" class="xref">Identifiers</a><a href="#section-toc.1-1.3.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.2">
                <p id="section-toc.1-1.3.2.2.1"><a href="#section-3.2" class="xref">3.2</a>.  <a href="#name-recommended-properties" class="xref">Recommended Properties</a><a href="#section-toc.1-1.3.2.2.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.3.2.2.2.1">
                    <p id="section-toc.1-1.3.2.2.2.1.1"><a href="#section-3.2.1" class="xref">3.2.1</a>.  <a href="#name-uniquely-identify-user-equi" class="xref">Uniquely Identify User Equipment</a><a href="#section-toc.1-1.3.2.2.2.1.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.2.2.2">
                    <p id="section-toc.1-1.3.2.2.2.2.1"><a href="#section-3.2.2" class="xref">3.2.2</a>.  <a href="#name-hard-to-spoof" class="xref">Hard to Spoof</a><a href="#section-toc.1-1.3.2.2.2.2.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.2.2.3">
                    <p id="section-toc.1-1.3.2.2.2.3.1"><a href="#section-3.2.3" class="xref">3.2.3</a>.  <a href="#name-visible-to-the-api-server" class="xref">Visible to the API Server</a><a href="#section-toc.1-1.3.2.2.2.3.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.2.2.4">
                    <p id="section-toc.1-1.3.2.2.2.4.1"><a href="#section-3.2.4" class="xref">3.2.4</a>.  <a href="#name-visible-to-the-enforcement-" class="xref">Visible to the Enforcement Device</a><a href="#section-toc.1-1.3.2.2.2.4.1" class="pilcrow">¶</a></p>
</li>
                </ul>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.3">
                <p id="section-toc.1-1.3.2.3.1"><a href="#section-3.3" class="xref">3.3</a>.  <a href="#name-evaluating-types-of-identif" class="xref">Evaluating Types of Identifiers</a><a href="#section-toc.1-1.3.2.3.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.4">
                <p id="section-toc.1-1.3.2.4.1"><a href="#section-3.4" class="xref">3.4</a>.  <a href="#name-example-identifier-types" class="xref">Example Identifier Types</a><a href="#section-toc.1-1.3.2.4.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.3.2.4.2.1">
                    <p id="section-toc.1-1.3.2.4.2.1.1"><a href="#section-3.4.1" class="xref">3.4.1</a>.  <a href="#name-physical-interface" class="xref">Physical Interface</a><a href="#section-toc.1-1.3.2.4.2.1.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.4.2.2">
                    <p id="section-toc.1-1.3.2.4.2.2.1"><a href="#section-3.4.2" class="xref">3.4.2</a>.  <a href="#name-ip-address" class="xref">IP Address</a><a href="#section-toc.1-1.3.2.4.2.2.1" class="pilcrow">¶</a></p>
</li>
                  <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.4.2.3">
                    <p id="section-toc.1-1.3.2.4.2.3.1"><a href="#section-3.4.3" class="xref">3.4.3</a>.  <a href="#name-media-access-control-mac-ad" class="xref">Media Access Control (MAC) Address</a><a href="#section-toc.1-1.3.2.4.2.3.1" class="pilcrow">¶</a></p>
</li>
                </ul>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.3.2.5">
                <p id="section-toc.1-1.3.2.5.1"><a href="#section-3.5" class="xref">3.5</a>.  <a href="#name-context-free-uri" class="xref">Context-Free URI</a><a href="#section-toc.1-1.3.2.5.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.4">
            <p id="section-toc.1-1.4.1"><a href="#section-4" class="xref">4</a>.  <a href="#name-solution-workflow" class="xref">Solution Workflow</a><a href="#section-toc.1-1.4.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.4.2.1">
                <p id="section-toc.1-1.4.2.1.1"><a href="#section-4.1" class="xref">4.1</a>.  <a href="#name-initial-connection" class="xref">Initial Connection</a><a href="#section-toc.1-1.4.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.4.2.2">
                <p id="section-toc.1-1.4.2.2.1"><a href="#section-4.2" class="xref">4.2</a>.  <a href="#name-conditions-about-to-expire" class="xref">Conditions about to Expire</a><a href="#section-toc.1-1.4.2.2.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.4.2.3">
                <p id="section-toc.1-1.4.2.3.1"><a href="#section-4.3" class="xref">4.3</a>.  <a href="#name-handling-of-changes-in-port" class="xref">Handling of Changes in Portal URI</a><a href="#section-toc.1-1.4.2.3.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.5">
            <p id="section-toc.1-1.5.1"><a href="#section-5" class="xref">5</a>.  <a href="#name-iana-considerations" class="xref">IANA Considerations</a><a href="#section-toc.1-1.5.1" class="pilcrow">¶</a></p>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.6">
            <p id="section-toc.1-1.6.1"><a href="#section-6" class="xref">6</a>.  <a href="#name-security-considerations" class="xref">Security Considerations</a><a href="#section-toc.1-1.6.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.6.2.1">
                <p id="section-toc.1-1.6.2.1.1"><a href="#section-6.1" class="xref">6.1</a>.  <a href="#name-trusting-the-network" class="xref">Trusting the Network</a><a href="#section-toc.1-1.6.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.6.2.2">
                <p id="section-toc.1-1.6.2.2.1"><a href="#section-6.2" class="xref">6.2</a>.  <a href="#name-authenticated-apis" class="xref">Authenticated APIs</a><a href="#section-toc.1-1.6.2.2.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.6.2.3">
                <p id="section-toc.1-1.6.2.3.1"><a href="#section-6.3" class="xref">6.3</a>.  <a href="#name-secure-apis" class="xref">Secure APIs</a><a href="#section-toc.1-1.6.2.3.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.6.2.4">
                <p id="section-toc.1-1.6.2.4.1"><a href="#section-6.4" class="xref">6.4</a>.  <a href="#name-risks-associated-with-the-s" class="xref">Risks Associated with the Signaling Protocol</a><a href="#section-toc.1-1.6.2.4.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.6.2.5">
                <p id="section-toc.1-1.6.2.5.1"><a href="#section-6.5" class="xref">6.5</a>.  <a href="#name-user-options" class="xref">User Options</a><a href="#section-toc.1-1.6.2.5.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.6.2.6">
                <p id="section-toc.1-1.6.2.6.1"><a href="#section-6.6" class="xref">6.6</a>.  <a href="#name-privacy" class="xref">Privacy</a><a href="#section-toc.1-1.6.2.6.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.7">
            <p id="section-toc.1-1.7.1"><a href="#section-7" class="xref">7</a>.  <a href="#name-references" class="xref">References</a><a href="#section-toc.1-1.7.1" class="pilcrow">¶</a></p>
<ul class="ulEmpty toc compact">
<li class="ulEmpty toc compact" id="section-toc.1-1.7.2.1">
                <p id="section-toc.1-1.7.2.1.1"><a href="#section-7.1" class="xref">7.1</a>.  <a href="#name-normative-references" class="xref">Normative References</a><a href="#section-toc.1-1.7.2.1.1" class="pilcrow">¶</a></p>
</li>
              <li class="ulEmpty toc compact" id="section-toc.1-1.7.2.2">
                <p id="section-toc.1-1.7.2.2.1"><a href="#section-7.2" class="xref">7.2</a>.  <a href="#name-informative-references" class="xref">Informative References</a><a href="#section-toc.1-1.7.2.2.1" class="pilcrow">¶</a></p>
</li>
            </ul>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.8">
            <p id="section-toc.1-1.8.1"><a href="#section-appendix.a" class="xref">Appendix A</a>.  <a href="#name-existing-captive-portal-det" class="xref">Existing Captive Portal Detection Implementations</a><a href="#section-toc.1-1.8.1" class="pilcrow">¶</a></p>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.9">
            <p id="section-toc.1-1.9.1"><a href="#section-appendix.b" class="xref"></a><a href="#name-acknowledgments" class="xref">Acknowledgments</a><a href="#section-toc.1-1.9.1" class="pilcrow">¶</a></p>
</li>
          <li class="ulEmpty toc compact" id="section-toc.1-1.10">
            <p id="section-toc.1-1.10.1"><a href="#section-appendix.c" class="xref"></a><a href="#name-authors-addresses" class="xref">Authors' Addresses</a><a href="#section-toc.1-1.10.1" class="pilcrow">¶</a></p>
</li>
        </ul>
</nav>
</section>
</div>
<section id="section-1">
      <h2 id="name-introduction">
<a href="#section-1" class="section-number selfRef">1. </a><a href="#name-introduction" class="section-name selfRef">Introduction</a>
      </h2>
<p id="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.<a href="#section-1-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-1-2" class="pilcrow">¶</a></p>
<p id="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:<a href="#section-1-3" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="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 <span class="bcp14">MUST NOT</span> require the forging of responses from
            DNS or HTTP servers or from any other protocol.<a href="#section-1-4.1" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-4.2">Solutions <span class="bcp14">MUST</span> permit clients to perform DNSSEC validation, which rules out solutions
            that forge DNS responses.
            Solutions <span class="bcp14">SHOULD</span> permit clients to detect and avoid TLS man-in-the-middle attacks
            without requiring a human to perform any kind of "exception" processing.<a href="#section-1-4.2" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-4.3">To maximize universality and adoption, solutions <span class="bcp14">MUST</span> 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.<a href="#section-1-4.3" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-4.4">Solutions <span class="bcp14">SHOULD</span> 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 <a href="#app-additional" class="xref">Appendix A</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.<a href="#section-1-4.4" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-4.5">The state of captivity <span class="bcp14">SHOULD</span> be explicitly available to devices via
            a standard protocol, rather than having to infer the state indirectly.<a href="#section-1-4.5" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-4.6">The architecture <span class="bcp14">MUST</span> 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.<a href="#section-1-4.6" class="pilcrow">¶</a>
</li>
      </ul>
<p id="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.<a href="#section-1-5" class="pilcrow">¶</a></p>
<p id="section-1-6">
       The architecture uses the following mechanisms:<a href="#section-1-6" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="section-1-7.1">Network provisioning protocols provide end-user devices with a
        Uniform Resource Identifier (URI) <span>[<a href="#RFC3986" class="xref">RFC3986</a>]</span> 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 <span>[<a href="#RFC8910" class="xref">RFC8910</a>]</span>. Other
        protocols (such as RADIUS), Provisioning Domains <span>[<a href="#I-D.pfister-capport-pvd" class="xref">CAPPORT-PVD</a>]</span>, or static configuration may also
        be used to convey this Captive Portal API URI.  A device
        <span class="bcp14">MAY</span> query this API at any time to determine whether the
        network is holding the device in a captive state.<a href="#section-1-7.1" class="pilcrow">¶</a>
</li>
        <li class="normal" id="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.<a href="#section-1-7.2" class="pilcrow">¶</a>
</li>
        <li class="normal" id="section-1-7.3">
            Receipt of a Captive Portal Signal provides a hint that User Equipment could be captive.
            In response, the device <span class="bcp14">MAY</span> 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).<a href="#section-1-7.3" class="pilcrow">¶</a>
</li>
      </ul>
<p id="section-1-8">
       The architecture attempts to provide confidentiality, authentication, and safety mechanisms
       to the extent possible.<a href="#section-1-8" class="pilcrow">¶</a></p>
<section id="section-1.1">
        <h3 id="name-requirements-language">
<a href="#section-1.1" class="section-number selfRef">1.1. </a><a href="#name-requirements-language" class="section-name selfRef">Requirements Language</a>
        </h3>
<p id="section-1.1-1">
    The key words "<span class="bcp14">MUST</span>", "<span class="bcp14">MUST NOT</span>",
    "<span class="bcp14">REQUIRED</span>", "<span class="bcp14">SHALL</span>", "<span class="bcp14">SHALL NOT</span>", "<span class="bcp14">SHOULD</span>", "<span class="bcp14">SHOULD NOT</span>",
    "<span class="bcp14">RECOMMENDED</span>", "<span class="bcp14">NOT RECOMMENDED</span>",
    "<span class="bcp14">MAY</span>", and "<span class="bcp14">OPTIONAL</span>" in this document are
    to be interpreted as described in BCP 14 <span>[<a href="#RFC2119" class="xref">RFC2119</a>]</span>
          <span>[<a href="#RFC8174" class="xref">RFC8174</a>]</span> when, and only when, they appear in all capitals,
    as shown here.<a href="#section-1.1-1" class="pilcrow">¶</a></p>
</section>
<section id="section-1.2">
        <h3 id="name-terminology">
<a href="#section-1.2" class="section-number selfRef">1.2. </a><a href="#name-terminology" class="section-name selfRef">Terminology</a>
        </h3>
<span class="break"></span><dl class="dlNewline" id="section-1.2-1">
          <dt id="section-1.2-1.1">Captive Portal
</dt>
          <dd style="margin-left: 1.5em" id="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).<a href="#section-1.2-1.2" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.3">Captive Portal Conditions
</dt>
          <dd style="margin-left: 1.5em" id="section-1.2-1.4">Site-specific requirements that a user or device must satisfy in order to
gain access to the wider network.<a href="#section-1.2-1.4" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.5">Captive Portal Enforcement Device
</dt>
          <dd style="margin-left: 1.5em" id="section-1.2-1.6">The network equipment that enforces the traffic restriction. Also known
as "Enforcement Device".<a href="#section-1.2-1.6" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.7">Captive Portal User Equipment
</dt>
          <dd style="margin-left: 1.5em" id="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".<a href="#section-1.2-1.8" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.9">User Portal
</dt>
          <dd style="margin-left: 1.5em" id="section-1.2-1.10">The web server providing a user interface for assisting the user in
satisfying the conditions to escape captivity.<a href="#section-1.2-1.10" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.11">Captive Portal API
</dt>
          <dd style="margin-left: 1.5em" id="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".<a href="#section-1.2-1.12" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.13">Captive Portal API Server
</dt>
          <dd style="margin-left: 1.5em" id="section-1.2-1.14">A server hosting the Captive Portal API. Also known as "API Server".<a href="#section-1.2-1.14" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.15">Captive Portal Signal
</dt>
          <dd style="margin-left: 1.5em" id="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.<a href="#section-1.2-1.16" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.17">Captive Portal Signaling Protocol
</dt>
          <dd style="margin-left: 1.5em" id="section-1.2-1.18">The protocol for communicating Captive Portal Signals. Also known as 
"Signaling Protocol".<a href="#section-1.2-1.18" class="pilcrow">¶</a>
</dd>
          <dd class="break"></dd>
<dt id="section-1.2-1.19">Captive Portal Session
</dt>
          <dd style="margin-left: 1.5em" id="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 <a href="#ue_identity" class="xref">Section 3</a>).<a href="#section-1.2-1.20" class="pilcrow">¶</a>
</dd>
        <dd class="break"></dd>
</dl>
</section>
</section>
<section id="section-2">
      <h2 id="name-components">
<a href="#section-2" class="section-number selfRef">2. </a><a href="#name-components" class="section-name selfRef">Components</a>
      </h2>
<div id="section_client">
<section id="section-2.1">
        <h3 id="name-user-equipment">
<a href="#section-2.1" class="section-number selfRef">2.1. </a><a href="#name-user-equipment" class="section-name selfRef">User Equipment</a>
        </h3>
<p id="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 <a href="#section_capport_enforcement" class="xref">Section 2.4</a>,
       until site-specific requirements have been met.<a href="#section-2.1-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-2.1-2" class="pilcrow">¶</a></p>
<p id="section-2.1-3">
        The User Equipment:<a href="#section-2.1-3" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="section-2.1-4.1">
            <span class="bcp14">SHOULD</span> support provisioning of the URI for the
          Captive Portal API (e.g., by DHCP).<a href="#section-2.1-4.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.1-4.2">
            <span class="bcp14">SHOULD</span> distinguish Captive Portal API access per
          network interface, in the manner of Provisioning Domain Architecture
          <span>[<a href="#RFC7556" class="xref">RFC7556</a>]</span>.<a href="#section-2.1-4.2" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.1-4.3">
            <span class="bcp14">SHOULD</span> have a non-spoofable mechanism for
          notifying the user of the Captive Portal.<a href="#section-2.1-4.3" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.1-4.4">
            <span class="bcp14">SHOULD</span> have a web browser so that the user may
          navigate to the User Portal.<a href="#section-2.1-4.4" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.1-4.5">
            <span class="bcp14">SHOULD</span> support updates to the Captive Portal API
          URI from the Provisioning Service.<a href="#section-2.1-4.5" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.1-4.6">
            <span class="bcp14">MAY</span> 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".<a href="#section-2.1-4.6" class="pilcrow">¶</a>
</li>
        </ul>
<p id="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.<a href="#section-2.1-5" class="pilcrow">¶</a></p>
<p id="section-2.1-6">
        If User Equipment supports the Captive Portal API, it
        <span class="bcp14">MUST</span> validate the API Server's TLS certificate (see
        <span>[<a href="#RFC2818" class="xref">RFC2818</a>]</span>) according to the procedures in <span>[<a href="#RFC6125" class="xref">RFC6125</a>]</span>.  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 <span class="bcp14">SHOULD</span> 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 <span><a href="https://www.rfc-editor.org/rfc/rfc8908#section-4.1" class="relref">Section 4.1</a> of [<a href="#RFC8908" class="xref">RFC8908</a>]</span>
        for more information.  If certificate validation fails, User Equipment
        <span class="bcp14">MUST NOT</span> make any calls to the API Server.<a href="#section-2.1-6" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-2.1-7" class="pilcrow">¶</a></p>
</section>
</div>
<div id="section_provisioning">
<section id="section-2.2">
        <h3 id="name-provisioning-service">
<a href="#section-2.2" class="section-number selfRef">2.2. </a><a href="#name-provisioning-service" class="section-name selfRef">Provisioning Service</a>
        </h3>
<p id="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.<a href="#section-2.2-1" class="pilcrow">¶</a></p>
<div id="section_dhcp">
<section id="section-2.2.1">
          <h4 id="name-dhcp-or-router-advertisemen">
<a href="#section-2.2.1" class="section-number selfRef">2.2.1. </a><a href="#name-dhcp-or-router-advertisemen" class="section-name selfRef">DHCP or Router Advertisements</a>
          </h4>
<p id="section-2.2.1-1">
           A standard for providing a Captive Portal API URI using DHCP or Router
           Advertisements is described in <span>[<a href="#RFC8910" class="xref">RFC8910</a>]</span>.  The
           captive portal architecture expects this URI to indicate the API described
           in <a href="#section_api" class="xref">Section 2.3</a>.<a href="#section-2.2.1-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="section_pvd">
<section id="section-2.2.2">
          <h4 id="name-provisioning-domains">
<a href="#section-2.2.2" class="section-number selfRef">2.2.2. </a><a href="#name-provisioning-domains" class="section-name selfRef">Provisioning Domains</a>
          </h4>
<p id="section-2.2.2-1">
           <span>[<a href="#I-D.pfister-capport-pvd" class="xref">CAPPORT-PVD</a>]</span>
           proposes a mechanism for User Equipment to be provided with
           Provisioning Domain (PvD) Bootstrap Information containing the URI
           for the API described in <a href="#section_api" class="xref">Section 2.3</a>.<a href="#section-2.2.2-1" class="pilcrow">¶</a></p>
</section>
</div>
</section>
</div>
<div id="section_api">
<section id="section-2.3">
        <h3 id="name-captive-portal-api-server">
<a href="#section-2.3" class="section-number selfRef">2.3. </a><a href="#name-captive-portal-api-server" class="section-name selfRef">Captive Portal API Server</a>
        </h3>
<p id="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 <a href="#app-additional" class="xref">Appendix A</a>) queries to check for response
         tampering.<a href="#section-2.3-1" class="pilcrow">¶</a></p>
<p id="section-2.3-2">
         The URI of this API will have been provisioned to the User Equipment.
         (Refer to <a href="#section_provisioning" class="xref">Section 2.2</a>.)<a href="#section-2.3-2" class="pilcrow">¶</a></p>
<p id="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 <span class="bcp14">MUST</span> support multiple repeated queries from the same
         User Equipment and return the state of captivity for the equipment.<a href="#section-2.3-3" class="pilcrow">¶</a></p>
<p id="section-2.3-4">
         At minimum, the API <span class="bcp14">MUST</span> provide the state of captivity. Further, the
         API <span class="bcp14">MUST</span> be able to provide a URI for the User Portal. The scheme for
         the URI <span class="bcp14">MUST</span> be "https" so that the User Equipment communicates with
         the User Portal over TLS.<a href="#section-2.3-4" class="pilcrow">¶</a></p>
<p id="section-2.3-5">
         If the API receives a request for state that does not correspond to the
         requesting User Equipment, the API <span class="bcp14">SHOULD</span> deny access.  Given that the
         API might use the User Equipment's identifier for authentication, this
         requirement motivates <a href="#id_recommended_hard" class="xref">Section 3.2.2</a>.<a href="#section-2.3-5" class="pilcrow">¶</a></p>
<p id="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 <span>[<a href="#RFC8908" class="xref">RFC8908</a>]</span>, this might be achieved by using a content type
         that is unique to the protocol.<a href="#section-2.3-6" class="pilcrow">¶</a></p>
<p id="section-2.3-7">
         When User Equipment receives Captive Portal Signals, the User Equipment
         <span class="bcp14">MAY</span> query the API to check its state of captivity.
         The User Equipment <span class="bcp14">SHOULD</span> rate-limit these API queries in the event of
         the signal being flooded. (See <a href="#Security" class="xref">Section 6</a>.)<a href="#section-2.3-7" class="pilcrow">¶</a></p>
<p id="section-2.3-8">
         The API <span class="bcp14">MUST</span> be extensible to support future use cases by allowing
         extensible information elements.<a href="#section-2.3-8" class="pilcrow">¶</a></p>
<p id="section-2.3-9">
         The API <span class="bcp14">MUST</span> use TLS to ensure server authentication.
         The implementation of the API <span class="bcp14">MUST</span> ensure both confidentiality and 
         integrity of any information provided by or required by it.<a href="#section-2.3-9" class="pilcrow">¶</a></p>
<p id="section-2.3-10">
         This document does not specify the details of the API.<a href="#section-2.3-10" class="pilcrow">¶</a></p>
</section>
</div>
<div id="section_capport_enforcement">
<section id="section-2.4">
        <h3 id="name-captive-portal-enforcement-">
<a href="#section-2.4" class="section-number selfRef">2.4. </a><a href="#name-captive-portal-enforcement-" class="section-name selfRef">Captive Portal Enforcement Device</a>
        </h3>
<p id="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.<a href="#section-2.4-1" class="pilcrow">¶</a></p>
<p id="section-2.4-2">
       The Enforcement Device component:<a href="#section-2.4-2" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="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.<a href="#section-2.4-3.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-2.4-3.2" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.4-3.3">Optionally signals User Equipment using the Captive Portal Signaling Protocol
           if certain traffic is blocked.<a href="#section-2.4-3.3" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-2.4-3.4" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.4-3.5">Updates allow/block rules per User Equipment in response to operations
           from the User Portal.<a href="#section-2.4-3.5" class="pilcrow">¶</a>
</li>
        </ul>
</section>
</div>
<div id="section_signal">
<section id="section-2.5">
        <h3 id="name-captive-portal-signal">
<a href="#section-2.5" class="section-number selfRef">2.5. </a><a href="#name-captive-portal-signal" class="section-name selfRef">Captive Portal Signal</a>
        </h3>
<p id="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 <span class="bcp14">SHOULD</span> be considered
        equivalent by the User Equipment as a hint to contact the API.
        If future solutions have multiple signal types, each type <span class="bcp14">SHOULD</span> be rate-limited
        independently.<a href="#section-2.5-1" class="pilcrow">¶</a></p>
<p id="section-2.5-2">
        An Enforcement Device <span class="bcp14">MUST</span> rate-limit any signal generated in response to these conditions.  See <a href="#section_signal_risks" class="xref">Section 6.4</a> for a discussion of
        risks related to a Captive Portal Signal.<a href="#section-2.5-2" class="pilcrow">¶</a></p>
</section>
</div>
<section id="section-2.6">
        <h3 id="name-component-diagram">
<a href="#section-2.6" class="section-number selfRef">2.6. </a><a href="#name-component-diagram" class="section-name selfRef">Component Diagram</a>
        </h3>
<p id="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.<a href="#section-2.6-1" class="pilcrow">¶</a></p>
<span id="name-captive-portal-architecture"></span><div id="components">
<figure id="figure-1">
          <div class="artwork art-text alignLeft" id="section-2.6-2.1">
<pre>
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
</pre>
</div>
<figcaption><a href="#figure-1" class="selfRef">Figure 1</a>:
<a href="#name-captive-portal-architecture" class="selfRef">Captive Portal Architecture Component Diagram</a>
          </figcaption></figure>
</div>
<p id="section-2.6-3">
        In the diagram:<a href="#section-2.6-3" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="section-2.6-4.1">During provisioning (e.g., DHCP), and possibly later, the User
          Equipment acquires the Captive Portal API URI.<a href="#section-2.6-4.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-2.6-4.2" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-2.6-4.3" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-2.6-4.4">The User Equipment attempts to communicate to the external
          network through the Enforcement Device.<a href="#section-2.6-4.4" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-2.6-4.5" class="pilcrow">¶</a>
</li>
        </ul>
<p id="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.<a href="#section-2.6-5" class="pilcrow">¶</a></p>
</section>
</section>
<div id="ue_identity">
<section id="section-3">
      <h2 id="name-user-equipment-identity">
<a href="#section-3" class="section-number selfRef">3. </a><a href="#name-user-equipment-identity" class="section-name selfRef">User Equipment Identity</a>
      </h2>
<p id="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.<a href="#section-3-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3-2" class="pilcrow">¶</a></p>
<div id="id_identifiers">
<section id="section-3.1">
        <h3 id="name-identifiers">
<a href="#section-3.1" class="section-number selfRef">3.1. </a><a href="#name-identifiers" class="section-name selfRef">Identifiers</a>
        </h3>
<p id="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.<a href="#section-3.1-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_recommended_props">
<section id="section-3.2">
        <h3 id="name-recommended-properties">
<a href="#section-3.2" class="section-number selfRef">3.2. </a><a href="#name-recommended-properties" class="section-name selfRef">Recommended Properties</a>
        </h3>
<p id="section-3.2-1">
             The set of possible identifiers is quite large. However, in order
             to be considered a good identifier, an identifier <span class="bcp14">SHOULD</span> 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 <span class="bcp14">SHOULD</span>:<a href="#section-3.2-1" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="section-3.2-2.1">uniquely identify the User Equipment<a href="#section-3.2-2.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-3.2-2.2">be hard to spoof<a href="#section-3.2-2.2" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-3.2-2.3">be visible to the API Server<a href="#section-3.2-2.3" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-3.2-2.4">be visible to the Enforcement Device<a href="#section-3.2-2.4" class="pilcrow">¶</a>
</li>
        </ul>
<p id="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.<a href="#section-3.2-3" class="pilcrow">¶</a></p>
<div id="id_recommended_unique">
<section id="section-3.2.1">
          <h4 id="name-uniquely-identify-user-equi">
<a href="#section-3.2.1" class="section-number selfRef">3.2.1. </a><a href="#name-uniquely-identify-user-equi" class="section-name selfRef">Uniquely Identify User Equipment</a>
          </h4>
<p id="section-3.2.1-1">
                  The Captive Portal <span class="bcp14">MUST</span> associate the User
                  Equipment with an identifier that is unique among all of the
                  User Equipment interacting with the Captive Portal at that
                  time.<a href="#section-3.2.1-1" class="pilcrow">¶</a></p>
<p id="section-3.2.1-2">
                  Over time, the User Equipment assigned to an identifier
                  value <span class="bcp14">MAY</span> change. Allowing the identified
                  device to change over time ensures that the space of
                  possible identifying values need not be overly large.<a href="#section-3.2.1-2" class="pilcrow">¶</a></p>
<p id="section-3.2.1-3">
                  Independent Captive Portals <span class="bcp14">MAY</span> 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.<a href="#section-3.2.1-3" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_recommended_hard">
<section id="section-3.2.2">
          <h4 id="name-hard-to-spoof">
<a href="#section-3.2.2" class="section-number selfRef">3.2.2. </a><a href="#name-hard-to-spoof" class="section-name selfRef">Hard to Spoof</a>
          </h4>
<p id="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.<a href="#section-3.2.2-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_recommended_visible_api">
<section id="section-3.2.3">
          <h4 id="name-visible-to-the-api-server">
<a href="#section-3.2.3" class="section-number selfRef">3.2.3. </a><a href="#name-visible-to-the-api-server" class="section-name selfRef">Visible to the API Server</a>
          </h4>
<p id="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.<a href="#section-3.2.3-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_recommended_visible_ed">
<section id="section-3.2.4">
          <h4 id="name-visible-to-the-enforcement-">
<a href="#section-3.2.4" class="section-number selfRef">3.2.4. </a><a href="#name-visible-to-the-enforcement-" class="section-name selfRef">Visible to the Enforcement Device</a>
          </h4>
<p id="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.<a href="#section-3.2.4-1" class="pilcrow">¶</a></p>
</section>
</div>
</section>
</div>
<div id="id_evaluating">
<section id="section-3.3">
        <h3 id="name-evaluating-types-of-identif">
<a href="#section-3.3" class="section-number selfRef">3.3. </a><a href="#name-evaluating-types-of-identif" class="section-name selfRef">Evaluating Types of Identifiers</a>
        </h3>
<p id="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.<a href="#section-3.3-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_examples">
<section id="section-3.4">
        <h3 id="name-example-identifier-types">
<a href="#section-3.4" class="section-number selfRef">3.4. </a><a href="#name-example-identifier-types" class="section-name selfRef">Example Identifier Types</a>
        </h3>
<p id="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.<a href="#section-3.4-1" class="pilcrow">¶</a></p>
<div id="id_example_interface">
<section id="section-3.4.1">
          <h4 id="name-physical-interface">
<a href="#section-3.4.1" class="section-number selfRef">3.4.1. </a><a href="#name-physical-interface" class="section-name selfRef">Physical Interface</a>
          </h4>
<p id="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.<a href="#section-3.4.1-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3.4.1-2" class="pilcrow">¶</a></p>
<p id="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
                 <span class="bcp14">MUST</span> invalidate their state related to the
                 User Equipment.<a href="#section-3.4.1-3" class="pilcrow">¶</a></p>
<p id="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).<a href="#section-3.4.1-4" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3.4.1-5" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_example_IP_address">
<section id="section-3.4.2">
          <h4 id="name-ip-address">
<a href="#section-3.4.2" class="section-number selfRef">3.4.2. </a><a href="#name-ip-address" class="section-name selfRef">IP Address</a>
          </h4>
<p id="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.<a href="#section-3.4.2-1" class="pilcrow">¶</a></p>
<p id="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
                  <span class="bcp14">SHOULD</span> 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 <span class="bcp14">MUST</span> 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).<a href="#section-3.4.2-2" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3.4.2-3" class="pilcrow">¶</a></p>
<p id="section-3.4.2-4">
                In some situations, the User Equipment may have multiple IP
                addresses (either IPv4, IPv6, or a dual-stack <span>[<a href="#RFC4213" class="xref">RFC4213</a>]</span> 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 <span class="bcp14">MAY</span> 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.<a href="#section-3.4.2-4" class="pilcrow">¶</a></p>
</section>
</div>
<div id="id_example_mac_address">
<section id="section-3.4.3">
          <h4 id="name-media-access-control-mac-ad">
<a href="#section-3.4.3" class="section-number selfRef">3.4.3. </a><a href="#name-media-access-control-mac-ad" class="section-name selfRef">Media Access Control (MAC) Address</a>
          </h4>
<p id="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 <a href="#id_recommended_props" class="xref">Section 3.2</a>.<a href="#section-3.4.3-1" class="pilcrow">¶</a></p>
</section>
</div>
</section>
</div>
<div id="context_free_uri">
<section id="section-3.5">
        <h3 id="name-context-free-uri">
<a href="#section-3.5" class="section-number selfRef">3.5. </a><a href="#name-context-free-uri" class="section-name selfRef">Context-Free URI</a>
        </h3>
<p id="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.<a href="#section-3.5-1" class="pilcrow">¶</a></p>
<p id="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
            <span>[<a href="#RFC8499" class="xref">RFC8499</a>]</span>).<a href="#section-3.5-2" class="pilcrow">¶</a></p>
<p id="section-3.5-3">
            Accessing the API <span class="bcp14">MAY</span> depend on contextual information. However,
            the URIs provided in the API <span class="bcp14">SHOULD</span> be unique to the User Equipment and not
            dependent on contextual information to function correctly.<a href="#section-3.5-3" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3.5-4" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-3.5-5" class="pilcrow">¶</a></p>
</section>
</div>
</section>
</div>
<div id="section_workflow">
<section id="section-4">
      <h2 id="name-solution-workflow">
<a href="#section-4" class="section-number selfRef">4. </a><a href="#name-solution-workflow" class="section-name selfRef">Solution Workflow</a>
      </h2>
<p id="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.<a href="#section-4-1" class="pilcrow">¶</a></p>
<section id="section-4.1">
        <h3 id="name-initial-connection">
<a href="#section-4.1" class="section-number selfRef">4.1. </a><a href="#name-initial-connection" class="section-name selfRef">Initial Connection</a>
        </h3>
<p id="section-4.1-1">
      This section describes a possible workflow when User Equipment initially
      joins a Captive Portal.<a href="#section-4.1-1" class="pilcrow">¶</a></p>
<ol start="1" type="1" class="normal type-1" id="section-4.1-2">
          <li id="section-4.1-2.1">The User Equipment joins the Captive Portal by acquiring a DHCP
         lease, RA, or similar, acquiring provisioning information.<a href="#section-4.1-2.1" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.2">The User Equipment learns the URI for the Captive Portal API from the
         provisioning information (e.g., <span>[<a href="#RFC8910" class="xref">RFC8910</a>]</span>).<a href="#section-4.1-2.2" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.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.)<a href="#section-4.1-2.3" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.4">If necessary, the user navigates to the User Portal to gain access to the
         external network.<a href="#section-4.1-2.4" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.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.<a href="#section-4.1-2.5" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.6">The User Equipment attempts a connection outside the Captive Portal.<a href="#section-4.1-2.6" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.7">If the requirements have been satisfied, the access is
          permitted; otherwise, the "Expired" behavior occurs.<a href="#section-4.1-2.7" class="pilcrow">¶</a>
</li>
          <li id="section-4.1-2.8">The User Equipment accesses the network until conditions expire.<a href="#section-4.1-2.8" class="pilcrow">¶</a>
</li>
        </ol>
</section>
<section id="section-4.2">
        <h3 id="name-conditions-about-to-expire">
<a href="#section-4.2" class="section-number selfRef">4.2. </a><a href="#name-conditions-about-to-expire" class="section-name selfRef">Conditions about to Expire</a>
        </h3>
<p id="section-4.2-1">
      This section describes a possible workflow when access is about to expire.<a href="#section-4.2-1" class="pilcrow">¶</a></p>
<ol start="1" type="1" class="normal type-1" id="section-4.2-2">
          <li id="section-4.2-2.1">Precondition: the API has provided the User Equipment with a duration
         over which its access is valid.<a href="#section-4.2-2.1" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.2">The User Equipment is communicating with the outside network.<a href="#section-4.2-2.2" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.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.<a href="#section-4.2-2.3" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.4">The User Equipment visits the API again to validate the expiry time.<a href="#section-4.2-2.4" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.5">If expiry is still imminent, the User Equipment prompts the user to access the
         User Portal URI again.<a href="#section-4.2-2.5" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.6">The user accepts the prompt displayed by the User Equipment.<a href="#section-4.2-2.6" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.7">The user extends their access through the User Portal via the User Equipment's user interface.<a href="#section-4.2-2.7" class="pilcrow">¶</a>
</li>
          <li id="section-4.2-2.8">The User Equipment's access to the outside network continues uninterrupted.<a href="#section-4.2-2.8" class="pilcrow">¶</a>
</li>
        </ol>
</section>
<section id="section-4.3">
        <h3 id="name-handling-of-changes-in-port">
<a href="#section-4.3" class="section-number selfRef">4.3. </a><a href="#name-handling-of-changes-in-port" class="section-name selfRef">Handling of Changes in Portal URI</a>
        </h3>
<p id="section-4.3-1">A different Captive Portal API URI could be returned in the following cases:<a href="#section-4.3-1" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="section-4.3-2.1">If DHCP is used, a lease renewal/rebind may return a different Captive
          Portal API URI.<a href="#section-4.3-2.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-4.3-2.2" class="pilcrow">¶</a>
</li>
        </ul>
<p id="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.<a href="#section-4.3-3" class="pilcrow">¶</a></p>
</section>
</section>
</div>
<div id="IANA">
<section id="section-5">
      <h2 id="name-iana-considerations">
<a href="#section-5" class="section-number selfRef">5. </a><a href="#name-iana-considerations" class="section-name selfRef">IANA Considerations</a>
      </h2>
<p id="section-5-1">This document has no IANA actions.<a href="#section-5-1" class="pilcrow">¶</a></p>
</section>
</div>
<div id="Security">
<section id="section-6">
      <h2 id="name-security-considerations">
<a href="#section-6" class="section-number selfRef">6. </a><a href="#name-security-considerations" class="section-name selfRef">Security Considerations</a>
      </h2>
<section id="section-6.1">
        <h3 id="name-trusting-the-network">
<a href="#section-6.1" class="section-number selfRef">6.1. </a><a href="#name-trusting-the-network" class="section-name selfRef">Trusting the Network</a>
        </h3>
<p id="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 <span>[<a href="#RFC7556" class="xref">RFC7556</a>]</span> provides some discussion on
         authenticating an operator.<a href="#section-6.1-1" class="pilcrow">¶</a></p>
<p id="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 <span class="bcp14">SHOULD</span> 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.<a href="#section-6.1-2" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-6.1-3" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-6.1-4" class="pilcrow">¶</a></p>
</section>
<section id="section-6.2">
        <h3 id="name-authenticated-apis">
<a href="#section-6.2" class="section-number selfRef">6.2. </a><a href="#name-authenticated-apis" class="section-name selfRef">Authenticated APIs</a>
        </h3>
<p id="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 <a href="#section_client" class="xref">Section 2.1</a>.<a href="#section-6.2-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-6.2-2" class="pilcrow">¶</a></p>
</section>
<section id="section-6.3">
        <h3 id="name-secure-apis">
<a href="#section-6.3" class="section-number selfRef">6.3. </a><a href="#name-secure-apis" class="section-name selfRef">Secure APIs</a>
        </h3>
<p id="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 <span class="bcp14">MUST</span>
           ensure the integrity of this information, as well as its confidentiality.<a href="#section-6.3-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-6.3-2" class="pilcrow">¶</a></p>
</section>
<div id="section_signal_risks">
<section id="section-6.4">
        <h3 id="name-risks-associated-with-the-s">
<a href="#section-6.4" class="section-number selfRef">6.4. </a><a href="#name-risks-associated-with-the-s" class="section-name selfRef">Risks Associated with the Signaling Protocol</a>
        </h3>
<p id="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:<a href="#section-6.4-1" class="pilcrow">¶</a></p>
<ul class="normal">
<li class="normal" id="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.<a href="#section-6.4-2.1" class="pilcrow">¶</a>
</li>
          <li class="normal" id="section-6.4-2.2">Even when responding to the signal, the User Equipment securely authenticates
               with API Servers.<a href="#section-6.4-2.2" class="pilcrow">¶</a>
</li>
          <li class="normal" id="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.<a href="#section-6.4-2.3" class="pilcrow">¶</a>
</li>
        </ul>
</section>
</div>
<section id="section-6.5">
        <h3 id="name-user-options">
<a href="#section-6.5" class="section-number selfRef">6.5. </a><a href="#name-user-options" class="section-name selfRef">User Options</a>
        </h3>
<p id="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 <span class="bcp14">MAY</span> 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 <span class="bcp14">MAY</span> allow users to manually control captive
         portal interactions, possibly on the granularity of Provisioning
         Domains.<a href="#section-6.5-1" class="pilcrow">¶</a></p>
</section>
<section id="section-6.6">
        <h3 id="name-privacy">
<a href="#section-6.6" class="section-number selfRef">6.6. </a><a href="#name-privacy" class="section-name selfRef">Privacy</a>
        </h3>
<p id="section-6.6-1">
          <a href="#ue_identity" class="xref">Section 3</a> 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.<a href="#section-6.6-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-6.6-2" class="pilcrow">¶</a></p>
</section>
</section>
</div>
<section id="section-7">
      <h2 id="name-references">
<a href="#section-7" class="section-number selfRef">7. </a><a href="#name-references" class="section-name selfRef">References</a>
      </h2>
<section id="section-7.1">
        <h3 id="name-normative-references">
<a href="#section-7.1" class="section-number selfRef">7.1. </a><a href="#name-normative-references" class="section-name selfRef">Normative References</a>
        </h3>
<dl class="references">
<dt id="RFC2119">[RFC2119]</dt>
        <dd>
<span class="refAuthor">Bradner, S.</span>, <span class="refTitle">"Key words for use in RFCs to Indicate Requirement Levels"</span>, <span class="seriesInfo">BCP 14</span>, <span class="seriesInfo">RFC 2119</span>, <span class="seriesInfo">DOI 10.17487/RFC2119</span>, <time datetime="1997-03" class="refDate">March 1997</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc2119">https://www.rfc-editor.org/info/rfc2119</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC2818">[RFC2818]</dt>
        <dd>
<span class="refAuthor">Rescorla, E.</span>, <span class="refTitle">"HTTP Over TLS"</span>, <span class="seriesInfo">RFC 2818</span>, <span class="seriesInfo">DOI 10.17487/RFC2818</span>, <time datetime="2000-05" class="refDate">May 2000</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc2818">https://www.rfc-editor.org/info/rfc2818</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC6125">[RFC6125]</dt>
        <dd>
<span class="refAuthor">Saint-Andre, P.</span><span class="refAuthor"> and J. Hodges</span>, <span class="refTitle">"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)"</span>, <span class="seriesInfo">RFC 6125</span>, <span class="seriesInfo">DOI 10.17487/RFC6125</span>, <time datetime="2011-03" class="refDate">March 2011</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc6125">https://www.rfc-editor.org/info/rfc6125</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC7556">[RFC7556]</dt>
        <dd>
<span class="refAuthor">Anipko, D., Ed.</span>, <span class="refTitle">"Multiple Provisioning Domain Architecture"</span>, <span class="seriesInfo">RFC 7556</span>, <span class="seriesInfo">DOI 10.17487/RFC7556</span>, <time datetime="2015-06" class="refDate">June 2015</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc7556">https://www.rfc-editor.org/info/rfc7556</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC8174">[RFC8174]</dt>
        <dd>
<span class="refAuthor">Leiba, B.</span>, <span class="refTitle">"Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"</span>, <span class="seriesInfo">BCP 14</span>, <span class="seriesInfo">RFC 8174</span>, <span class="seriesInfo">DOI 10.17487/RFC8174</span>, <time datetime="2017-05" class="refDate">May 2017</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8174">https://www.rfc-editor.org/info/rfc8174</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC8910">[RFC8910]</dt>
      <dd>
<span class="refAuthor">Kumari, W.</span><span class="refAuthor"> and E. Kline</span>, <span class="refTitle">"Captive-Portal Identification in DHCP and Router Advertisements (RAs)"</span>, <span class="seriesInfo">RFC 8910</span>, <span class="seriesInfo">DOI 10.17487/RFC8910</span>, <time datetime="2020-09" class="refDate">September 2020</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8910">https://www.rfc-editor.org/info/rfc8910</a>&gt;</span>. </dd>
<dd class="break"></dd>
</dl>
</section>
<section id="section-7.2">
        <h3 id="name-informative-references">
<a href="#section-7.2" class="section-number selfRef">7.2. </a><a href="#name-informative-references" class="section-name selfRef">Informative References</a>
        </h3>
<dl class="references">
<dt id="I-D.pfister-capport-pvd">[CAPPORT-PVD]</dt>
        <dd>
<span class="refAuthor">Pfister, P.</span><span class="refAuthor"> and T. Pauly</span>, <span class="refTitle">"Using Provisioning Domains for Captive Portal Discovery"</span>, <span class="refContent">Work in Progress</span>, <span class="seriesInfo">Internet-Draft, draft-pfister-capport-pvd-00</span>, <time datetime="2018-06-30" class="refDate">30 June 2018</time>, <span>&lt;<a href="https://tools.ietf.org/html/draft-pfister-capport-pvd-00">https://tools.ietf.org/html/draft-pfister-capport-pvd-00</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC3986">[RFC3986]</dt>
        <dd>
<span class="refAuthor">Berners-Lee, T.</span><span class="refAuthor">, Fielding, R.</span><span class="refAuthor">, and L. Masinter</span>, <span class="refTitle">"Uniform Resource Identifier (URI): Generic Syntax"</span>, <span class="seriesInfo">STD 66</span>, <span class="seriesInfo">RFC 3986</span>, <span class="seriesInfo">DOI 10.17487/RFC3986</span>, <time datetime="2005-01" class="refDate">January 2005</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc3986">https://www.rfc-editor.org/info/rfc3986</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC4213">[RFC4213]</dt>
        <dd>
<span class="refAuthor">Nordmark, E.</span><span class="refAuthor"> and R. Gilligan</span>, <span class="refTitle">"Basic Transition Mechanisms for IPv6 Hosts and Routers"</span>, <span class="seriesInfo">RFC 4213</span>, <span class="seriesInfo">DOI 10.17487/RFC4213</span>, <time datetime="2005-10" class="refDate">October 2005</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc4213">https://www.rfc-editor.org/info/rfc4213</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC8499">[RFC8499]</dt>
        <dd>
<span class="refAuthor">Hoffman, P.</span><span class="refAuthor">, Sullivan, A.</span><span class="refAuthor">, and K. Fujiwara</span>, <span class="refTitle">"DNS Terminology"</span>, <span class="seriesInfo">BCP 219</span>, <span class="seriesInfo">RFC 8499</span>, <span class="seriesInfo">DOI 10.17487/RFC8499</span>, <time datetime="2019-01" class="refDate">January 2019</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8499">https://www.rfc-editor.org/info/rfc8499</a>&gt;</span>. </dd>
<dd class="break"></dd>
<dt id="RFC8908">[RFC8908]</dt>
      <dd>
<span class="refAuthor">Pauly, T., Ed.</span><span class="refAuthor"> and D. Thakore, Ed.</span>, <span class="refTitle">"Captive Portal API"</span>, <span class="seriesInfo">RFC 8908</span>, <span class="seriesInfo">DOI 10.17487/RFC8908</span>, <time datetime="2020-09" class="refDate">September 2020</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8908">https://www.rfc-editor.org/info/rfc8908</a>&gt;</span>. </dd>
<dd class="break"></dd>
</dl>
</section>
</section>
<div id="app-additional">
<section id="section-appendix.a">
      <h2 id="name-existing-captive-portal-det">
<a href="#section-appendix.a" class="section-number selfRef">Appendix A. </a><a href="#name-existing-captive-portal-det" class="section-name selfRef">Existing Captive Portal Detection Implementations</a>
      </h2>
<p id="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.<a href="#section-appendix.a-1" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-appendix.a-2" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-appendix.a-3" class="pilcrow">¶</a></p>
<p id="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.<a href="#section-appendix.a-4" class="pilcrow">¶</a></p>
</section>
</div>
<div id="Acknowledgments">
<section id="section-appendix.b">
      <h2 id="name-acknowledgments">
<a href="#name-acknowledgments" class="section-name selfRef">Acknowledgments</a>
      </h2>
<p id="section-appendix.b-1">The authors thank <span class="contact-name">Lorenzo Colitti</span> for providing
      the majority of the content for the Captive Portal Signal
      requirements.<a href="#section-appendix.b-1" class="pilcrow">¶</a></p>
<p id="section-appendix.b-2">The authors thank <span class="contact-name">Benjamin Kaduk</span> for providing
      the content related to TLS certificate validation of the API Server.<a href="#section-appendix.b-2" class="pilcrow">¶</a></p>
<p id="section-appendix.b-3">The authors thank <span class="contact-name">Michael Richardson</span> for
      providing wording requiring DNSSEC and TLS to operate without the user
      adding exceptions.<a href="#section-appendix.b-3" class="pilcrow">¶</a></p>
<p id="section-appendix.b-4">The authors thank various individuals for their feedback on
        the mailing list and during the IETF 98 hackathon:
        <span class="contact-name">David Bird</span>,
        <span class="contact-name">Erik Kline</span>,
        <span class="contact-name">Alexis La Goulette</span>,
        <span class="contact-name">Alex Roscoe</span>,
        <span class="contact-name">Darshak Thakore</span>,
        and <span class="contact-name">Vincent van Dam</span>.<a href="#section-appendix.b-4" class="pilcrow">¶</a></p>
</section>
</div>
<div id="authors-addresses">
<section id="section-appendix.c">
      <h2 id="name-authors-addresses">
<a href="#name-authors-addresses" class="section-name selfRef">Authors' Addresses</a>
      </h2>
<address class="vcard">
        <div dir="auto" class="left"><span class="fn nameRole">Kyle Larose</span></div>
<div dir="auto" class="left"><span class="org">Agilicus</span></div>
<div class="email">
<span>Email:</span>
<a href="mailto:kyle@agilicus.com" class="email">kyle@agilicus.com</a>
</div>
</address>
<address class="vcard">
        <div dir="auto" class="left"><span class="fn nameRole">David Dolson</span></div>
<div class="email">
<span>Email:</span>
<a href="mailto:ddolson@acm.org" class="email">ddolson@acm.org</a>
</div>
</address>
<address class="vcard">
        <div dir="auto" class="left"><span class="fn nameRole">Heng Liu</span></div>
<div dir="auto" class="left"><span class="org">Google</span></div>
<div class="email">
<span>Email:</span>
<a href="mailto:liucougar@google.com" class="email">liucougar@google.com</a>
</div>
</address>
</section>
</div>
<script>const toc = document.getElementById("toc");
toc.querySelector("h2").addEventListener("click", e => {
  toc.classList.toggle("active");
});
toc.querySelector("nav").addEventListener("click", e => {
  toc.classList.remove("active");
});
</script>
</body>
</html>