File: configuration.rst

package info (click to toggle)
flask-security 5.6.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,420 kB
  • sloc: python: 23,164; javascript: 204; makefile: 138
file content (2137 lines) | stat: -rw-r--r-- 71,819 bytes parent folder | download | duplicates (2)
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
Configuration
=============

.. warning::
    Be sure to set all configuration (in app.config["xxx"]) *PRIOR* to instantiating
    the Security class or calling security.init_app().

The following configuration values are used by Flask-Security:

Core
--------------

These configuration keys are used globally across all features.

.. py:data:: SECRET_KEY

    This is actually part of Flask - but is used by Flask-Security to sign all tokens.
    It is critical this is set to a strong value. For python3 consider using: ``secrets.token_urlsafe()``

.. py:data:: SECRET_KEY_FALLBACKS

    This is part of Flask (>=3.1) but can be used by Flask-Security to unsign tokens.
    See Flask documentation https://flask.palletsprojects.com/en/stable/config/#SECRET_KEY_FALLBACKS

    .. versionadded:: 5.6.0

.. py:data:: SECURITY_BLUEPRINT_NAME

    Specifies the name for the Flask-Security blueprint.

    Default: ``"security"``.

.. py:data:: SECURITY_URL_PREFIX

    Specifies the URL prefix for the Flask-Security blueprint.

    Default: ``None``.

.. py:data:: SECURITY_STATIC_FOLDER

    Specifies the folder name for static files (webauthn).

    Default: ``"static"``.

    .. versionadded:: 5.1.0

.. py:data:: SECURITY_STATIC_FOLDER_URL

    Specifies the URL for static files used by Flask-Security (webauthn).
    See Flask documentation https://flask.palletsprojects.com/en/latest/blueprints/#static-files

    Default: ``"/fs-static"``.

    .. versionadded:: 5.1.0

.. py:data:: SECURITY_SUBDOMAIN

    Specifies the subdomain for the Flask-Security blueprint. If your authenticated
    content is on a different subdomain, also enable :py:data:`SECURITY_REDIRECT_ALLOW_SUBDOMAINS`.

    Default: ``None``.
.. py:data:: SECURITY_FLASH_MESSAGES

    Specifies whether or not to flash messages for actions certain endpoint perform.
    Normally Flash-Security views will flash informational or error messages only when the operation
    results in a redirect.

    Default: ``True``.
.. py:data:: SECURITY_I18N_DOMAIN

    Specifies the name for domain used for translations.

    Default: ``"flask_security"``.
.. py:data:: SECURITY_I18N_DIRNAME

    Specifies the directory containing the ``MO`` files used for translations.
    When using flask-babel this can also be a list of directory names - this
    enables application to override a subset of messages if desired. The
    default ``builtin`` uses translations shipped with Flask-Security.

    Default: ``"builtin"``.

    .. versionchanged:: 5.2.0
        "builtin" is a special name which will be interpreted as the ``translations``
        directory within the installation of Flask-Security.

.. py:data:: SECURITY_TOKEN_AUTHENTICATION_KEY

    Specifies the query string parameter to read when using token authentication.

    Default: ``"auth_token"``.

.. py:data:: SECURITY_TOKEN_AUTHENTICATION_HEADER

    Specifies the HTTP header to read when using token authentication.

    Default: ``"Authentication-Token"``.

.. py:data:: SECURITY_TOKEN_MAX_AGE

    Specifies the number of seconds before an authentication token expires.

    Default: ``None``, meaning the token never expires.

.. py:data:: SECURITY_TOKEN_EXPIRE_TIMESTAMP

    A callable that returns a unix timestamp in the future when this specific
    authentication token should expire. Returning 0 means no expiration.
    It is passed the currently authenticated User so any fields can be used
    to customize an expiration time. Of course it is called in a request
    context so any information about the current request can also be used.

    If BOTH this and :data:`SECURITY_TOKEN_MAX_AGE` are set - the shorter is used.

    .. note::
        These 2 expiry options work differently - with this one, the actual expire
        timestamp is in the auth_token. The signed token (using itsdangerous)
        has the timestamp the token was generated. On validation, that is checked
        against ``SECURITY_TOKEN_MAX_AGE``. So for MAX_AGE, at the time of
        validation, the token hasn't yet been associated with a User.

    Default: ``lambda user: 0``

.. py:data:: SECURITY_EMAIL_VALIDATOR_ARGS

    Email address are validated and normalized via the ``mail_util_cls`` which
    defaults to :class:`.MailUtil`. That uses the `email_validator`_ package whose methods
    have configurable options - these can be set here and will be passed in.
    For example setting this to: ``{"check_deliverability": False}`` is useful
    when unit testing if the emails are fake.

    ``mail_util_cls`` has 2 methods - ``normalize`` and ``validate``. Both
    ensure the passed value is a valid email address, and returns a normalized
    version. ``validate`` additionally, by default, verifies that the email
    address can likely actually receive an email.

    Default: ``None``, meaning use the defaults from email_validator package.

    .. versionadded:: 4.0.0

.. _email_validator: https://pypi.org/project/email-validator/

.. py:data:: SECURITY_DEFAULT_HTTP_AUTH_REALM

    Specifies the default authentication realm when using basic HTTP auth.

    Default: ``Login Required``

.. py:data:: SECURITY_REDIRECT_BEHAVIOR

    Passwordless login, confirmation, reset password, unified signin, change_email, and oauth signin
    have GET endpoints that validate the passed token and redirect to an action form.
    For Single-Page-Applications style UIs which need to control their own internal URL routing these redirects
    need to not contain forms, but contain relevant information as query parameters.
    Setting this to ``"spa"`` will enable that behavior.

    When this is enabled, the following must also be defined:

    - :py:data:`SECURITY_POST_OAUTH_LOGIN_VIEW`  (if :py:data:`SECURITY_OAUTH_ENABLE` is True)
    - :py:data:`SECURITY_LOGIN_ERROR_VIEW`
    - :py:data:`SECURITY_CONFIRM_ERROR_VIEW`
    - :py:data:`SECURITY_POST_CHANGE_EMAIL_VIEW`
    - :py:data:`SECURITY_CHANGE_EMAIL_ERROR_VIEW`
    - :py:data:`SECURITY_POST_CONFIRM_VIEW`
    - :py:data:`SECURITY_RESET_ERROR_VIEW`
    - :py:data:`SECURITY_RESET_VIEW`


    Default: ``None`` which is existing html-style form redirects.

    .. versionadded:: 3.3.0

.. py:data:: SECURITY_REDIRECT_HOST

    Mostly for development purposes, the UI is often developed
    separately and is running on a different port than the
    Flask application. In order to test redirects, the `netloc`
    of the redirect URL needs to be rewritten. Setting this to e.g. `localhost:8080` does that.

    .. tip::
        Be aware that when this is set, any of the `*_VIEW` configuration variables that are set
        to URLs and not endpoints, will be redirected to this host.

    Default: ``None``.

    .. versionadded:: 3.3.0

.. py:data:: SECURITY_REDIRECT_ALLOW_SUBDOMAINS

    If ``True`` then subdomains (and the root domain) of the top-level host set
    by Flask's ``SERVER_NAME`` configuration will be allowed as post-view redirect targets.
    This is beneficial if you wish to place your authentication on one subdomain and
    authenticated content on another, for example ``auth.domain.tld`` and ``app.domain.tld``.

    Default: ``False``.

    .. versionadded:: 4.0.0

.. py:data:: SECURITY_REDIRECT_BASE_DOMAIN

    Set the base domain for checking allowable redirects. The intent here is to
    allow an application to be server on e.g. "flaskapp.my.org" and redirect
    to "myservice.my.org" (which maybe isn't a Flask app). Flask's SERVER_NAME
    can't be used to verify redirects in this case. Note that in most cases
    the application will want to set Flask's SESSION_COOKIE_DOMAIN to be this base domain -
    otherwise authorization information won't be sent.

    Default: ``None``

    .. versionadded:: 5.5.0

.. py:data:: SECURITY_REDIRECT_ALLOWED_SUBDOMAINS

    A list of subdomains. Each will be prepended to
    ``SECURITY_REDIRECT_BASE_DOMAIN`` and checked against the requested redirect.

    Default: ``[]``

    .. versionadded:: 5.5.0


.. note::
    The above 4 config options apply BOTH to the handling of ``next`` parameter
    as well as all the ``XXX_VIEW`` URL configuration options
    for those views that perform a redirect after processing.

.. py:data:: SECURITY_CSRF_PROTECT_MECHANISMS

    Authentication mechanisms that require CSRF protection.
    These are the same mechanisms as are permitted in the ``@auth_required`` decorator.

    Default: ``("basic", "session", "token")``.

.. py:data:: SECURITY_CSRF_IGNORE_UNAUTH_ENDPOINTS

    If ``True`` then CSRF will not be required for endpoints
    that don't require authentication (e.g. login, logout, register, forgot_password).

    Default: ``False``.

.. py:data:: SECURITY_CSRF_COOKIE_NAME

    The name for the CSRF cookie. This usually should be dictated by your
    client-side code  - more information can be found at :ref:`csrf_topic`

    Default: ``None`` - meaning no cookie will be sent.

.. py:data:: SECURITY_CSRF_COOKIE

    A dict that defines the parameters required to
    set a CSRF cookie.
    The complete set of parameters is described in Flask's `set_cookie`_ documentation.

    Default: ``{"samesite": "Strict", "httponly": False, "secure": False}``

    .. versionchanged:: 4.1.0
        The 'key' attribute was deprecated in favor of a separate configuration
        variable :data:`SECURITY_CSRF_COOKIE_NAME`.

.. py:data:: SECURITY_CSRF_HEADER

    The HTTP Header name that will contain the CSRF token. ``X-XSRF-Token``
    is used by packages such as `axios`_.

    Default: ``"X-XSRF-Token"``.

.. py:data:: SECURITY_CSRF_COOKIE_REFRESH_EACH_REQUEST

    By default, csrf_tokens have an expiration (controlled
    by the configuration variable ``WTF_CSRF_TIME_LIMIT``.
    This can cause CSRF failures if say an application is left
    idle for a long time. You can set that time limit to ``None``
    or have the CSRF cookie sent on every request (which will give
    it a new expiration time).

    Default: ``False``.

.. py:data:: SECURITY_EMAIL_SENDER

    Specifies the email address to send emails as.

    Default: value set to ``MAIL_DEFAULT_SENDER`` if Flask-Mail is used otherwise ``no-reply@localhost``.

.. py:data:: SECURITY_USER_IDENTITY_ATTRIBUTES

    Specifies which attributes of the user object can be used for credential validation.

    Defines the order and matching that will be applied when validating login
    credentials (either via standard login form or the unified sign in form).
    The identity field in the form will be matched in order using this configuration
    - the FIRST match will then be used to look up the user in the DB.

    Mapping functions take a single argument - ``identity`` from the form
    and should return ``None`` if the ``identity`` argument isn't in a format
    suitable for the attribute. If the ``identity`` argument format matches, it
    should be returned, optionally having had some normalization performed.
    The returned result will be used to look up the identity in the UserDataStore
    using the column name specified in the key.

    The provided :meth:`flask_security.uia_phone_mapper` for example performs
    phone number normalization using the ``phonenumbers`` package.

    .. tip::
        If your mapper performs any sort of normalization,
        make sure you apply the exact same transformation in your form validator
        when setting the field.

    .. danger::
        Make sure that any attributes listed here are marked Unique in your UserDataStore
        model.

    .. danger::
        Make sure your mapper methods guard against malicious user input. For example,
        if you allow ``username`` as an identity method you could use `bleach`_::

            def uia_username_mapper(identity):
                # we allow pretty much anything - but we bleach it.
                return bleach.clean(identity, strip=True)

    Default::

        [
            {"email": {"mapper": uia_email_mapper, "case_insensitive": True}},
        ]

    If you enable :py:data:`SECURITY_UNIFIED_SIGNIN` and set ``sms`` as a :py:data:`SECURITY_US_ENABLED_METHODS`
    and your `SECURITY_USER_IDENTITY_ATTRIBUTES` contained::

        [
            {"email": {"mapper": uia_email_mapper, "case_insensitive": True}},
            {"us_phone_number": {"mapper": uia_phone_mapper}},
        ]

    Then after the user sets up their SMS - they could login using their phone number and
    get a text with the authentication code.

    .. versionchanged:: 4.0.0
        Changed from list to list of dict.

.. _bleach: https://pypi.org/project/bleach/

.. py:data:: SECURITY_USER_IDENTITY_MAPPINGS

    .. versionadded:: 3.4.0
    .. deprecated:: 4.0.0
        Superseded by :py:data:`SECURITY_USER_IDENTITY_ATTRIBUTES`

.. py:data:: SECURITY_API_ENABLED_METHODS

    Various endpoints of Flask-Security require the caller to be authenticated.
    This variable controls which of the methods - ``token``, ``session``, ``basic``
    will be allowed. The default does NOT include ``basic`` since if ``basic``
    is in the list, and if the user is NOT authenticated, then the standard/required
    response of 401 with the ``WWW-Authenticate`` header is returned. This is
    rarely what the client wants.

    Default: ``["session", "token"]``.

    .. versionadded:: 4.0.0

.. py:data:: SECURITY_DEFAULT_REMEMBER_ME

    Specifies the default "remember me" value used when logging in a user.

    Default: ``False``.

.. py:data:: SECURITY_RETURN_GENERIC_RESPONSES

    If set to ``True`` Flask-Security will return generic responses to endpoints
    that could be used to enumerate users. Please see :ref:`generic_responses`.

    Default: ``False``

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_FRESHNESS

    A timedelta used to protect endpoints that alter sensitive information.
    This is used to protect the following endpoints:

        - :py:data:`SECURITY_US_SETUP_URL`
        - :py:data:`SECURITY_TWO_FACTOR_SETUP_URL`
        - :py:data:`SECURITY_WAN_REGISTER_URL`
        - :py:data:`SECURITY_WAN_DELETE_URL`
        - :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_CODES`
        - :py:data:`SECURITY_CHANGE_EMAIL_URL`

    Setting this to a negative number will disable any freshness checking and
    the endpoints:

        - :py:data:`SECURITY_VERIFY_URL`
        - :py:data:`SECURITY_US_VERIFY_URL`
        - :py:data:`SECURITY_US_VERIFY_SEND_CODE_URL`
        - :py:data:`SECURITY_WAN_VERIFY_URL`

    won't be registered.
    Setting this to 0 results in undefined behavior.
    Please see :meth:`flask_security.check_and_update_authn_fresh` for details.

    .. note::
        The timestamp of when the caller/user last successfully authenticated is
        stored in the session as well as authentication token.

    Default: timedelta(hours=24)

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_FRESHNESS_GRACE_PERIOD

    A timedelta that provides a grace period when altering sensitive
    information. This ensures that multi-step operations don't get denied
    because the session/token happens to expire mid-step.

    Note that this is not implemented for freshness information carried in the
    auth token.

    N.B. To avoid strange behavior, be sure to set the grace period less than
    the freshness period.
    Please see :meth:`flask_security.check_and_update_authn_fresh` for details.

    Default: timedelta(hours=1)

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_FRESHNESS_ALLOW_AUTH_TOKEN

    Controls whether the freshness data set in the auth token can be used to
    satisfy freshness checks. Some applications might want to force freshness
    protected endpoints to always use browser based access with sessions - they
    should set this to ``False``.

    Default: ``True``


    .. versionadded:: 5.5.0

Core - Passwords and Tokens
----------------------------
.. py:data:: SECURITY_PASSWORD_HASH

    Specifies the password hash algorithm to use when hashing passwords.
    Recommended values for production systems are ``argon2``, ``bcrypt``, or
    ``pbkdf2_sha512``. Some algorithms require the installation  of a backend package (e.g. `bcrypt`_, `argon2`_).

    Default: ``"argon2"``.

    .. versionchanged:: 5.5.0
        Default changed from ``bcrypt`` to ``argon2``.

.. py:data:: SECURITY_PASSWORD_SCHEMES

    List of supported password hash algorithms. ``SECURITY_PASSWORD_HASH``
    must be from this list. Passwords encrypted with any of these schemes will be honored.
    This is passed directly to `passlib's CryptoContext`_.

.. py:data:: SECURITY_DEPRECATED_PASSWORD_SCHEMES

    List of password hash algorithms that are considered weak and
    will be accepted, however on first use, will be re-hashed to the current
    setting of ``SECURITY_PASSWORD_HASH``.
    This is passed directly to `passlib's CryptoContext`_.

    Default: ``["auto"]`` which means any password found that wasn't
    hashed using ``SECURITY_PASSWORD_HASH`` will be re-hashed.

.. py:data:: SECURITY_PASSWORD_SALT

    Specifies the HMAC salt. This is required for all schemes that
    are configured for double hashing. A good salt can be generated using:
    ``secrets.SystemRandom().getrandbits(128)``.

    Default: ``None``.

.. py:data:: SECURITY_PASSWORD_SINGLE_HASH

    A list of schemes that should not be hashed twice. By default, passwords are
    hashed twice, first with :py:data:`SECURITY_PASSWORD_SALT`, and then with a random salt.

    Default: a list of known schemes not working with double hashing (`django_{digest}`, `plaintext`).

.. py:data:: SECURITY_HASHING_SCHEMES

    List of algorithms used for encrypting/hashing sensitive data within a token
    (Such as is sent with confirmation or reset password).
    This is passed directly to `passlib's CryptoContext`_.

    Default: ``["sha256_crypt", "hex_md5"]``.
.. py:data:: SECURITY_DEPRECATED_HASHING_SCHEMES

    List of deprecated algorithms used for creating and validating tokens.
    This is passed directly to `passlib's CryptoContext`_.

    Default: ``["auto"]``.

.. versionchanged:: 5.5.0
        Default changed from ``hex_md5`` to ``auto``.

.. py:data:: SECURITY_PASSWORD_HASH_OPTIONS

    Specifies additional options to be passed to the hashing method. This is deprecated as of passlib 1.7.

    .. deprecated:: 3.4.0 see: :py:data:`SECURITY_PASSWORD_HASH_PASSLIB_OPTIONS`

.. py:data:: SECURITY_PASSWORD_HASH_PASSLIB_OPTIONS

    Pass additional options through ``passlib`` to the various hashing methods.
    This is a dict of the form ``{<scheme>__<option>: <value>, ..}``
    e.g. {"argon2__time_cost": 3}.

    Default: ``{}``

    .. versionadded:: 3.3.1

.. py:data:: SECURITY_PASSWORD_LENGTH_MIN

    Minimum required length for passwords.

    Default: ``8``

    .. versionadded:: 3.4.0
.. py:data:: SECURITY_PASSWORD_COMPLEXITY_CHECKER

    Set to complexity checker to use (Only ``zxcvbn`` supported).

    Default: ``None``

    .. versionadded:: 3.4.0
.. py:data:: SECURITY_ZXCVBN_MINIMUM_SCORE

    Required ``zxcvbn`` password complexity score (0-4).
    Refer to https://github.com/dropbox/zxcvbn#usage for exact meanings of
    different score values.

    Default: ``3`` (Good or Strong)

    .. versionadded:: 5.0.0
.. py:data:: SECURITY_PASSWORD_CHECK_BREACHED

    If not ``None`` new/changed passwords will be checked against the
    database of breached passwords at https://api.pwnedpasswords.com.
    If set to ``strict`` then if the site can't be reached, validation will fail.
    If set to ``best-effort`` failure to reach the site will continue
    with the rest of password validation.

    Default: ``None``

    .. versionadded:: 3.4.0
.. py:data:: SECURITY_PASSWORD_BREACHED_COUNT

    Passwords with counts greater than or equal to this value are considered breached.

    Default: 1  - which might be to burdensome for some applications.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_PASSWORD_NORMALIZE_FORM

    Passwords are normalized prior to changing or comparing. This satisfies
    the NIST requirement: `5.1.1.2 Memorized Secret Verifiers`_.
    Normalization is performed using the Python unicodedata.normalize() method.

    Default: ``"NFKD"``

    .. versionadded:: 4.0.0

.. _5.1.1.2 Memorized Secret Verifiers: https://pages.nist.gov/800-63-3/sp800-63b.html#sec5

.. py:data:: SECURITY_PASSWORD_REQUIRED

    If set to ``False`` then a user can register with an empty password.
    This requires :py:data:`SECURITY_UNIFIED_SIGNIN` to be enabled. By
    default, the user will be able to authenticate using an email link.
    Please note: this does not mean a user can sign in with an empty
    password - it means that they must have some OTHER means of authenticating.

    Default: ``True``

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_PASSWORD_CONFIRM_REQUIRED

    If set to ``True`` then during registration a 'password confirmation' field is presented.
    N.B. this just applies to the new(er) RegisterFormV2 (see :py:data:`SECURITY_USE_REGISTER_V2`)

    Default: ``True``

    .. versionadded:: 5.6.0

Core - Multi-factor
-------------------
These are used by the Two-Factor and Unified Signin features.

.. py:data:: SECURITY_TOTP_SECRETS

    Secret used to encrypt the totp_password both into DB and into the session cookie.
    Best practice is to set this to:

    .. code-block:: python

        from passlib import totp
        "{1: <result of totp.generate_secret()>}"

    See: `Totp`_ for details.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_TOTP_ISSUER

    Specifies the name of the service or application that the user is authenticating to.
    This will be the name displayed by most authenticator apps.

    Default: ``None``.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_SMS_SERVICE

    Specifies the name of the sms service provider. Out of the box
    "Twilio" is supported. For other sms service providers you will need
    to subclass :class:`.SmsSenderBaseClass` and register it:

    .. code-block:: python

        SmsSenderFactory.senders[<service-name>] = <service-class>

    Default: ``Dummy`` which does nothing.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_SMS_SERVICE_CONFIG

    Specifies a dictionary of basic configurations needed for use of a sms service.
    For "Twilio" the following keys are required (fill in from your Twilio dashboard):

    Default: ``{'ACCOUNT_SID': NONE, 'AUTH_TOKEN': NONE, 'PHONE_NUMBER': NONE}``

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_PHONE_REGION_DEFAULT

    Assigns a default 'region' for phone numbers used for two-factor or
    unified sign in. All other phone numbers will require a region prefix to
    be accepted.

    Default: ``"US"``

    .. versionadded:: 3.4.0

Core - Compatibility
---------------------
These are flags that change various backwards compatability functionality.

.. py:data:: SECURITY_ANONYMOUS_USER_DISABLED

    If set to `True` then :data:`flask_security.current_user` will be `None` for unauthenticated
    users instead of pointing to an AnonymousUser object. Note that Flask-Login intends
    to deprecate the entire AnonymousUser concept.

    Default: ``False``.

    .. versionadded:: 5.4.0

.. py:data:: SECURITY_BACKWARDS_COMPAT_UNAUTHN

    If set to ``True`` then the default behavior for authentication
    failures from one of Flask-Security's decorators will be restored to
    be compatible with releases prior to 3.3.0 (return 401 and some static html).

    Default: ``False``.

.. py:data:: SECURITY_BACKWARDS_COMPAT_AUTH_TOKEN

    If set to ``True`` then an Authentication-Token will be returned
    on every successful call to login, reset-password, change-password
    as part of the JSON response. This was the default prior to release 3.3.0
    - however sending Authentication-Tokens (which by default don't expire)
    to session based UIs is a bad security practice.

    Default: ``False``.

Core - rarely need changing
----------------------------

.. py:data:: SECURITY_DATETIME_FACTORY

    Specifies the default datetime factory. The default is naive-UTC which
    corresponds to many DB's DateTime type.

    Default:``flask_security.naive_utcnow``.

.. py:data:: SECURITY_CONFIRM_SALT

    Specifies the salt value when generating confirmation links/tokens.

    Default: ``"confirm-salt"``.

.. py:data:: SECURITY_RESET_SALT

    Specifies the salt value when generating password reset links/tokens.

    Default: ``"reset-salt"``.

.. py:data:: SECURITY_LOGIN_SALT

    Specifies the salt value when generating login links/tokens.

    Default: ``"login-salt"``.

.. py:data:: SECURITY_REMEMBER_SALT

    Specifies the salt value when generating remember tokens.
    Remember tokens are used instead of user ID's as it is more secure.

    Default: ``"remember-salt"``.
.. py:data:: SECURITY_TWO_FACTOR_VALIDITY_SALT

    Specifies the salt value when generating two-factor validity tokens.

    Default: ``"tf-validity-salt"``.
.. py:data:: SECURITY_US_SETUP_SALT

    Default: ``"us-setup-salt"``

.. py:data:: SECURITY_WAN_SALT

    Default: ``"wan-salt"``
.. py:data:: SECURITY_TWO_FACTOR_SETUP_SALT

    Default: ``"tf-setup-salt"``
.. py:data:: SECURITY_EMAIL_CHANGE_SALT

    Specifies the salt value when generating change email confirmation links/tokens.

    Default: ``"change-email-salt"``.

.. py:data:: SECURITY_EMAIL_PLAINTEXT

    Sends email as plaintext using ``*.txt`` template.

    Default: ``True``.

.. py:data:: SECURITY_EMAIL_HTML

    Sends email as HTML using ``*.html`` template.

    Default: ``True``.

.. py:data:: SECURITY_CLI_USERS_NAME

    Specifies the name for the command managing users. Disable by setting ``False``.

    Default: ``"users"``.

.. py:data:: SECURITY_CLI_ROLES_NAME

    Specifies the name for the command managing roles. Disable by setting ``False``.

    Default: ``"roles"``.

.. py:data:: SECURITY_JOIN_USER_ROLES

    Specifies whether to set the ``UserModel.roles`` loading relationship to ``joined`` when a ``roles`` attribute
    is present for a SQLAlchemy Datastore. Setting this to ``False`` restores pre 3.3.0 behavior and is required if the ``roles`` attribute
    is not a joinable attribute on the ``UserModel``. The default setting improves performance by only requiring a single
    DB call.

    Default: ``True``.

    .. versionadded:: 3.4.0

.. _Totp: https://passlib.readthedocs.io/en/stable/narr/totp-tutorial.html#totp-encryption-setup
.. _set_cookie: https://flask.palletsprojects.com/en/1.1.x/api/?highlight=set_cookie#flask.Response.set_cookie
.. _axios: https://github.com/axios/axios
.. _bcrypt: https://pypi.org/project/bcrypt/
.. _argon2: https://pypi.org/project/argon2-cffi/

Login/Logout
------------
.. py:data:: SECURITY_LOGIN_URL

    Specifies the login URL.

    Default: ``"/login"``.

.. py:data:: SECURITY_LOGOUT_URL

    Specifies the logout URL.

    Default:``"/logout"``.


.. py:data:: SECURITY_LOGOUT_METHODS

    Specifies the HTTP request methods that the logout URL accepts. Specify ``None`` to disable the logout URL (and implement your own).
    Configuring with just ``["POST"]`` is slightly more secure. The default includes ``"GET"`` for backwards compatibility.

    Default: ``["GET", "POST"]``.


.. py:data:: SECURITY_POST_LOGIN_VIEW

    Specifies the default view to redirect to after a user logs in. This value can be set to a URL
    or an endpoint name. Defaults to the Flask config ``APPLICATION_ROOT`` value which itself defaults to ``"/"``.
    Note that if the request URL or form has a ``next`` parameter, that will take precedence.

    Default: ``APPLICATION_ROOT``.

.. py:data:: SECURITY_POST_LOGOUT_VIEW

    Specifies the default view to redirect to after a user logs out. This value can be set to a URL
    or an endpoint name. Defaults to the Flask config ``APPLICATION_ROOT`` value which itself defaults to ``"/"``.
    Note that if the request URL or form has a ``next`` parameter, that will take precedence.

    Default: ``APPLICATION_ROOT``.


.. py:data:: SECURITY_UNAUTHORIZED_VIEW

    Specifies the view to redirect to if a user attempts to access a URL/endpoint that they do
    not have permission to access. This can be a callable (which returns a URL or ``None``) or an endpoint or a URL.
    If this value is ``None`` or the configured callable returns ``None`` or empty, the user is presented with a default HTTP 403 response.

    Default: ``None``.

.. py:data:: SECURITY_LOGIN_USER_TEMPLATE

    Specifies the path to the template for the user login page.

    Default: ``"security/login_user.html"``.

.. py:data:: SECURITY_VERIFY_URL

    Specifies the reauthenticate URL. If :py:data:`SECURITY_FRESHNESS` evaluates to < 0; this
    endpoint won't be registered.

    Default: ``"/verify"``

    .. versionadded:: 3.4.0


.. py:data:: SECURITY_VERIFY_TEMPLATE

    Specifies the path to the template for the verify password page.

    Default: ``"security/verify.html"``.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_POST_VERIFY_URL

    Specifies the default view to redirect to after a user successfully reauthenticates either via
    the :py:data:`SECURITY_VERIFY_URL` or the :py:data:`SECURITY_US_VERIFY_URL`.
    Normally this won't need to be set and after the verification/reauthentication, the referring
    view (held in the ``next`` parameter) will be redirected to.

    Default: ``None``.

    .. versionadded:: 3.4.0

Registerable
------------
.. py:data:: SECURITY_REGISTERABLE

    Specifies if Flask-Security should create a user registration endpoint.

    Default: ``False``

.. py:data:: SECURITY_SEND_REGISTER_EMAIL

    Specifies whether registration email is sent.

    Default: ``True``.
.. py:data:: SECURITY_EMAIL_SUBJECT_REGISTER

    Sets the subject for the confirmation email.

    Default: ``_("Welcome")``.
.. py:data:: SECURITY_REGISTER_USER_TEMPLATE

    Specifies the path to the template for the user registration page.

    Default: ``"security/register_user.html"``.
.. py:data:: SECURITY_POST_REGISTER_VIEW

    Specifies the view to redirect to after a user successfully registers.
    This value can be set to a URL or an endpoint name. If this value is
    ``None``, the user is redirected to the value of :data:`SECURITY_POST_LOGIN_VIEW`.
    Note that if the request URL or form has a ``next`` parameter, that will take precedence.

    Default: ``None``.
.. py:data:: SECURITY_REGISTER_URL

    Specifies the register URL.

    Default: ``"/register"``.

.. py:data:: SECURITY_USERNAME_ENABLE

    If set to True, the default registration form and template, and
    login form and template will have
    a username field added. This requires that your user model contain the
    field ``username``. It MUST be set as 'unique' and if you don't want
    to require a username, it should be set as 'nullable'.
    The form validators will call :meth:`.UsernameUtil.validate`.

    In addition, :data:`SECURITY_USER_IDENTITY_ATTRIBUTES` will be updated to include::

        {"username": {"mapper": uia_username_mapper}, "case_insensitive": True}

    See :meth:`flask_security.uia_username_mapper` for details.

    If you already have added a username field to your forms, don't set this
    option - the system will throw an exception at init_app time.

    Validation and normalization is encapsulated in :class:`.UsernameUtil`.
    Note that the default validation restricts username input to be unicode
    letters and numbers. It also uses ``bleach`` to scrub any risky input. Be
    sure your application requirements includes `bleach`_.

    Default: ``False``

    .. versionadded:: 4.1.0

.. py:data:: SECURITY_USERNAME_REQUIRED

    If username is enabled, is it required as part of registration?

    Default: ``False``

    .. versionadded:: 4.1.0


.. py:data:: SECURITY_USERNAME_MIN_LENGTH

    Minimum length of a username.

    Default: ``4``

    .. versionadded:: 4.1.0

.. py:data:: SECURITY_USERNAME_MAX_LENGTH

    Maximum length of a username.

    Default: ``32``

    .. versionadded:: 4.1.0

.. py:data:: SECURITY_USERNAME_NORMALIZE_FORM

    Usernames, by default, are normalized using the Python unicodedata.normalize() method.

    Default: ``"NFKD"``

    .. versionadded:: 4.1.0

.. py:data:: SECURITY_USE_REGISTER_V2

    The :py:class:`flask_security.RegisterFormV2` is a single form used for registration. This is replacing the
    RegisterForm and ConfirmRegisterForm (over a few releases). Setting this option
    to ``True`` will set both registration forms to RegisterFormV2. Note that this
    option is ignored if the application has sub-classed the registration form.

    Default: ``False``

    .. versionadded:: 5.6.0



Confirmable
-----------

.. py:data:: SECURITY_CONFIRMABLE

    Specifies if users are required to confirm their email address when
    registering a new account. If this value is `True`, Flask-Security creates an endpoint to handle
    confirmations and requests to resend confirmation instructions.

    Default: ``False``.
.. py:data:: SECURITY_CONFIRM_EMAIL_WITHIN

    Specifies the amount of time a user has before their confirmation
    link expires. Always pluralize the time unit for this value.

    Default: ``"5 days"``.
.. py:data:: SECURITY_CONFIRM_URL

    Specifies the email confirmation URL.

    Default: ``"/confirm"``.
.. py:data:: SECURITY_SEND_CONFIRMATION_TEMPLATE

    Specifies the path to the template for the resend confirmation instructions page.

    Default: ``"security/send_confirmation.html"``.
.. py:data:: SECURITY_EMAIL_SUBJECT_CONFIRM

    Sets the subject for the email confirmation message.

    Default: ``_("Please confirm your email")``.
.. py:data:: SECURITY_CONFIRM_ERROR_VIEW

    Specifies the view to redirect to if a confirmation error occurs.
    This value can be set to a URL or an endpoint name.
    If this value is ``None``, the user is presented the default view
    to resend a confirmation link. In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``
    query params in the redirect will contain the error.

    Default: ``None``.
.. py:data:: SECURITY_POST_CONFIRM_VIEW

    Specifies the view to redirect to after a user successfully confirms their email.
    This value can be set to a URL or an endpoint name. If this value is ``None``, the user is redirected to the
    value of :data:`SECURITY_POST_LOGIN_VIEW`.

    Default: ``None``.
.. py:data:: SECURITY_AUTO_LOGIN_AFTER_CONFIRM

    If ``True``, then the user corresponding to the confirmation token will be automatically signed in.
    If ``False`` (the default) then the user will be required to authenticate using the usual mechanism(s).
    Note that the confirmation token is single-use. This is not recommended by OWASP
    however an application that is by invite only (no self-registration) might find this useful.

    Default: ``False``.

.. py:data:: SECURITY_LOGIN_WITHOUT_CONFIRMATION

    Specifies if a user may login before confirming their email when
    the value of :data:`SECURITY_CONFIRMABLE` is set to ``True``.

    Default: ``False``.
.. py:data:: SECURITY_REQUIRES_CONFIRMATION_ERROR_VIEW

    Specifies a redirect page if the users tries to login, reset password or us-signin with an unconfirmed account.
    If an URL endpoint is specified, flashes an error messages and redirects.
    Default behavior is to reload the form with an error message without redirecting to an other page.

    Default: ``None``.

Changeable
----------

.. py:data:: SECURITY_CHANGEABLE

    Specifies if Flask-Security should enable the change password endpoint.

    Default: ``False``.
.. py:data:: SECURITY_CHANGE_URL

    Specifies the password change URL.

    Default: ``"/change"``.
.. py:data:: SECURITY_POST_CHANGE_VIEW

    Specifies the view to redirect to after a user successfully changes their password.
    This value can be set to a URL or an endpoint name.
    If this value is ``None``, the user is redirected  to the
    value of :data:`SECURITY_POST_LOGIN_VIEW`.

    Default: ``None``.
.. py:data:: SECURITY_CHANGE_PASSWORD_TEMPLATE

    Specifies the path to the template for the change password page.

    Default: ``"security/change_password.html"``.

.. py:data:: SECURITY_SEND_PASSWORD_CHANGE_EMAIL

    Specifies whether password change email is sent.

    Default: ``True``.

.. py:data:: SECURITY_EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE

    Sets the subject for the password change notice.

    Default: ``_("Your password has been changed")``.

Recoverable
-----------

.. py:data:: SECURITY_RECOVERABLE

    Specifies if Flask-Security should create a password reset/recover endpoint.

    Default: ``False``.

.. py:data:: SECURITY_RESET_URL

    Specifies the password reset URL.

    Default: ``"/reset"``.

.. py:data:: SECURITY_RESET_PASSWORD_TEMPLATE

    Specifies the path to the template for the reset password page.

    Default: ``"security/reset_password.html"``.

.. py:data:: SECURITY_FORGOT_PASSWORD_TEMPLATE

    Specifies the path to the template for the forgot password page.

    Default: ``"security/forgot_password.html"``.

.. py:data:: SECURITY_POST_RESET_VIEW

    Specifies the view to redirect to after a user successfully resets their password.
    This value can be set to a URL or an endpoint name. If this
    value is ``None``, the user is redirected to the value of ``.login`` if
    :py:data:`SECURITY_AUTO_LOGIN_AFTER_RESET` is ``False`` or :py:data:`SECURITY_POST_LOGIN_VIEW`
    if ``True``

    Default: ``None``.

.. py:data:: SECURITY_RESET_VIEW

    Specifies the view/URL to redirect to after a GET reset-password link.
    This is only valid if :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``.
    Query params in the redirect will contain the ``token``.

    Default: ``None``.

.. py:data:: SECURITY_AUTO_LOGIN_AFTER_RESET

    If ``False`` then on successful reset the user will be required to signin again.
    Note that the reset token is not valid after being used once.
    If ``True``, then the user corresponding to the
    reset token will be automatically signed in. Note: auto-login is contrary
    to OWASP best security practices. This option is for backwards compatibility
    and is deprecated.

    Default: ``False``.

    .. versionadded:: 5.3.0
    .. deprecated:: 5.3.0

.. py:data:: SECURITY_RESET_ERROR_VIEW

    Specifies the view/URL to redirect to after a GET reset-password link when there is an error.
    This is only valid if :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``spa``.
    Query params in the redirect will contain the error.

    Default: ``None``.

.. py:data:: SECURITY_RESET_PASSWORD_WITHIN

    Specifies the amount of time a user has before their password reset link expires.
    Always pluralize the time unit for this value.

    Default: ``"1 days"``.

.. py:data:: SECURITY_SEND_PASSWORD_RESET_EMAIL

    Specifies whether password reset email is sent. These are instructions
    including a link that can be clicked on.

    Default: ``True``.

.. py:data:: SECURITY_SEND_PASSWORD_RESET_NOTICE_EMAIL

    Specifies whether password reset notice email is sent. This is sent once
    a user's password was successfully reset.

    Default: ``True``.

.. py:data:: SECURITY_EMAIL_SUBJECT_PASSWORD_RESET

    Sets the subject for the password reset email.

    Default: ``_("Password reset instructions")``.

.. py:data:: SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE

    Sets subject for the password notice.

    Default: ``_("Your password has been reset")``.

Change-Email
------------
.. versionadded:: 5.5.0

.. py:data:: SECURITY_CHANGE_EMAIL

    It ``True`` an endpoint is created that allows a user to change their email address.

    Default: ``False``
.. py:data:: SECURITY_CHANGE_EMAIL_SUBJECT

    Sets the subject for the change email confirmation email.

    Default: ``_("Confirm your new email address")``.
.. py:data:: SECURITY_CHANGE_EMAIL_TEMPLATE

    Specifies the path to the template for the change email page.

    Default: ``"security/change_email.html"``.
.. py:data:: SECURITY_CHANGE_EMAIL_WITHIN

    Specifies the amount of time a user has before their change email
    token expires. Always pluralize the time unit for this value.

    Default: ``"2 hours"``
.. py:data:: SECURITY_POST_CHANGE_EMAIL_VIEW

    Specifies the view to redirect to after a user successfully confirms their new email address.
    This value can be set to a URL or an endpoint name. If this value is
    ``None``, the user is redirected to the value of :py:data:`SECURITY_POST_LOGIN_VIEW`.
    Note that if the request URL or form has a ``next`` parameter, that will take precedence.
    In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"`` this value must be set.

    Default: ``None``.
.. py:data:: SECURITY_CHANGE_EMAIL_ERROR_VIEW

    Specifies the view to redirect to if a change email confirmation error occurs.
    This value can be set to a URL or an endpoint name.
    If this value is ``None``, the user is redirected back to the change_email page.
    In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``
    this value must be set, and the query params in the redirect will contain the error.

    Default: ``None``.
.. py:data:: SECURITY_CHANGE_EMAIL_URL

    Specifies the change-email endpoint URL.

    Default: ``"/change-email"``.
.. py:data:: SECURITY_CHANGE_EMAIL_CONFIRM_URL

    Specifies the change-email confirmation endpoint URL. This is a GET
    only endpoint (accessed via a link in an email).

    Default: ``"/change-email-confirm"``.

Additional relevant configuration variables:

    - :py:data:`SECURITY_FRESHNESS` - Used to protect /change-email.
    - :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /change-email.

Two-Factor
-----------
Configuration related to the two-factor authentication feature.

.. versionadded:: 3.2.0

.. py:data:: SECURITY_TWO_FACTOR

    Specifies if Flask-Security should enable the two-factor login feature.
    If set to ``True``, in addition to their passwords, users will be required to
    enter a code that is sent to them. Note that unless
    :data:`SECURITY_TWO_FACTOR_REQUIRED` is set - this is opt-in.

    Default: ``False``.
.. py:data:: SECURITY_TWO_FACTOR_REQUIRED

    If set to ``True`` then all users will be required to setup and use two-factor authorization.

    Default: ``False``.
.. py:data:: SECURITY_TWO_FACTOR_ENABLED_METHODS

    Specifies the default enabled methods for two-factor authentication.

    Default: ``['email', 'authenticator', 'sms']`` which are the only currently supported methods.
.. py:data:: SECURITY_TWO_FACTOR_AUTHENTICATOR_VALIDITY

    Specifies the number of seconds access token is valid.

    Default: ``120``.
.. py:data:: SECURITY_TWO_FACTOR_MAIL_VALIDITY

    Specifies the number of seconds access token is valid.

    Default: ``300``.
.. py:data:: SECURITY_TWO_FACTOR_SMS_VALIDITY

    Specifies the number of seconds access token is valid.

    Default: ``120``.
.. py:data:: SECURITY_TWO_FACTOR_SETUP_WITHIN

    Specifies the amount of time a user has before their two-factor setup
    token expires. Always pluralize the time unit for this value.

    Default: ``"30 minutes"``

    .. versionadded:: 5.5.0
.. py:data:: SECURITY_TWO_FACTOR_RESCUE_MAIL

    Specifies the email address users send mail to when they can't complete the
    two-factor authentication login.

    Default: ``"no-reply@localhost"``.

.. py:data:: SECURITY_EMAIL_SUBJECT_TWO_FACTOR

    Sets the subject for the two-factor feature.

    Default: ``_("Two-Factor Login")``
.. py:data:: SECURITY_EMAIL_SUBJECT_TWO_FACTOR_RESCUE

    Sets the subject for the two-factor help function.

    Default: ``_("Two-Factor Rescue")``
.. py:data:: SECURITY_TWO_FACTOR_VERIFY_CODE_TEMPLATE

    Specifies the path to the template for the verify code page for the two-factor authentication process.

    Default: ``"security/two_factor_verify_code.html"``.
.. py:data:: SECURITY_TWO_FACTOR_SETUP_TEMPLATE

    Specifies the path to the template for the setup page for the two-factor authentication process.

    Default: ``"security/two_factor_setup.html"``.

.. py:data:: SECURITY_TWO_FACTOR_SETUP_URL

    Specifies the two-factor setup URL.

    Default: ``"/tf-setup"``.
.. py:data:: SECURITY_TWO_FACTOR_TOKEN_VALIDATION_URL

    Specifies the two-factor token validation URL.

    Default: ``"/tf-validate"``.

.. py:data:: SECURITY_TWO_FACTOR_RESCUE_URL

    Specifies the two-factor rescue URL.

    Default: ``"/tf-rescue"``.

.. py:data:: SECURITY_TWO_FACTOR_SELECT_URL

    Specifies the two-factor select URL. This is used when the user has
    setup more than one second factor.

    Default: ``"/tf-select"``.

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_TWO_FACTOR_ERROR_VIEW

    Specifies a URL or endpoint to redirect to if the system detects that
    a two-factor endpoint is being accessed without the proper state. For example
    if ``tf-validate`` is accessed but the caller hasn't yet successfully passed the
    primary authentication.

    Default: ``".login"``

    .. versionadded:: 5.1.0

.. py:data:: SECURITY_TWO_FACTOR_POST_SETUP_VIEW

    Specifies the view to redirect to after a user successfully setups a two-factor method (non-json).
    This value can be set to a URL or an endpoint name.

    Default: ``".two_factor_setup"``

    .. versionadded:: 5.1.0

.. py:data:: SECURITY_TWO_FACTOR_SELECT_TEMPLATE

    Specifies the path to the template for the select method page for the two-factor authentication process.
    This is used when more than one two-factor method has been setup (e.g. SMS and Webauthn).

    Default: ``"security/two_factor_select.html"``.

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_TWO_FACTOR_ALWAYS_VALIDATE

    Specifies whether the application should require a two-factor code upon every login.
    If set to ``False`` then the 2 values below are used to determine when
    a code is required. Note that this is cookie based - so a new browser
    session will always require a fresh two-factor code.

    Default: ``True``.
.. py:data:: SECURITY_TWO_FACTOR_LOGIN_VALIDITY

    Specifies the expiration of the two-factor validity cookie and verification of the token.

    Default: ``"30 Days"``.


.. py:data:: SECURITY_TWO_FACTOR_VALIDITY_COOKIE

    A dictionary containing the parameters of the two-factor validity cookie.
    The complete set of parameters is described in Flask's `set_cookie`_ documentation.

    Default: ``{'httponly': True, 'secure': False, 'samesite': None}``.

.. py:data:: SECURITY_TWO_FACTOR_IMPLEMENTATIONS

    A dictionary of supported second factor implementations. All of these must
    implement the TfPluginBase interface.

    Default: ``{"code": "flask_security.twofactor.CodeTfPlugin", "webauthn": "flask_security.webauthn.WebAuthnTfPlugin",}``

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_TWO_FACTOR_RESCUE_EMAIL

    If True, then the 'email' option for two-factor rescue is enabled - allowing a user to
    recover a missing/inoperable second factor device by requesting a one time code sent to their email.
    While this is very convenient is has the downside that if a user's email is hacked, their second factor
    is useless to protect their account.

    Default: ``True``

    .. versionadded:: 5.0.0

Unified Signin
--------------

    Unified sign in provides a generalized sign in endpoint that takes an `identity`
    and a `passcode`.

    .. versionadded:: 3.4.0

.. py:data:: SECURITY_UNIFIED_SIGNIN

    To enable this feature - set this to ``True``.

    Default: ``False``

.. py:data:: SECURITY_US_SIGNIN_URL

    Sign in a user with an identity and a passcode.

    Default: ``"/us-signin"``

.. py:data:: SECURITY_US_SIGNIN_SEND_CODE_URL

    Endpoint that given an identity, and a previously setup authentication method, will
    generate and return a one time code. This isn't necessary when using an authenticator
    app.

    Default: ``"/us-signin/send-code"``

.. py:data:: SECURITY_US_SETUP_URL

    Endpoint for setting up and validating SMS or an authenticator app for use in
    receiving one-time codes.

    Default: ``"/us-setup"``

.. py:data:: SECURITY_US_VERIFY_LINK_URL

    This endpoint handles the 'magic link' that is sent when the user requests a code
    via email. It is mostly just accessed via a ``GET`` from an email reader.

    Default: ``"/us-verify-link"``

.. py:data:: SECURITY_US_VERIFY_URL

    This endpoint handles reauthentication, the caller must be already authenticated
    and then enter in their primary credentials (password/passcode) again. This is
    used when an endpoint (such as ``/us-setup``) fails freshness checks.
    This endpoint won't be registered if :py:data:`SECURITY_FRESHNESS` evaluates to < 0.

    Default: ``"/us-verify"``

.. py:data:: SECURITY_US_VERIFY_SEND_CODE_URL

    As part of ``/us-verify``, this endpoint will send the appropriate code.
    This endpoint won't be registered if :py:data:`SECURITY_FRESHNESS` evaluates to < 0.

    Default: ``"/us-verify/send-code"``

.. py:data:: SECURITY_US_POST_SETUP_VIEW

    Specifies the view to redirect to after a user successfully setups an authentication method (non-json).
    This value can be set to a URL or an endpoint name.

    Default: ``".us-setup"``

.. py:data:: SECURITY_US_SIGNIN_TEMPLATE

    Default: ``"security/us_signin.html"``

.. py:data:: SECURITY_US_SETUP_TEMPLATE

    Default: ``"security/us_setup.html"``

.. py:data:: SECURITY_US_VERIFY_TEMPLATE

    Default: ``"security/us_verify.html"``

.. py:data:: SECURITY_US_ENABLED_METHODS

    Specifies the default enabled methods for unified signin authentication.
    Be aware that ``password`` only affects this :data:`SECURITY_US_SIGNIN_URL` endpoint.
    Removing it from here won't stop users from using the :data:`SECURITY_LOGIN_URL` endpoint
    (unless you replace the login endpoint using :py:data:`SECURITY_US_SIGNIN_REPLACES_LOGIN`).

    This config variable defines which methods can be used to provide ``passcode`` data.
    :py:data:`SECURITY_USER_IDENTITY_ATTRIBUTES` defines which user model fields can be used as ``identity``.

    Default: ``["password", "email", "authenticator", "sms"]`` - which are the only supported options.

.. py:data:: SECURITY_US_MFA_REQUIRED

    A list of :data:`SECURITY_US_ENABLED_METHODS` that will require two-factor
    authentication. This is of course dependent on the settings of :py:data:`SECURITY_TWO_FACTOR`
    and :py:data:`SECURITY_TWO_FACTOR_REQUIRED`. Note that even with REQUIRED, only
    methods listed here will trigger a two-factor cycle.

    Default: ``["password", "email"]``.

.. py:data:: SECURITY_US_TOKEN_VALIDITY

    Specifies the number of seconds access token/code is valid.

    Default: ``120``

.. py:data:: SECURITY_US_EMAIL_SUBJECT

    Sets the email subject when sending the verification code via email.

    Default: ``_("Verification Code")``

.. py:data:: SECURITY_US_SETUP_WITHIN

    Specifies the amount of time a user has before their setup
    token expires. Always pluralize the time unit for this value.

    Default: ``"30 minutes"``

.. py:data:: SECURITY_US_SIGNIN_REPLACES_LOGIN

    If set, then the :py:data:`SECURITY_LOGIN_URL` will be registered to the ``us-signin`` endpoint.
    Doing this will mean that logout will properly redirect to the us-signin endpoint.

    Default: ``False``


Additional relevant configuration variables:

    * :py:data:`SECURITY_USER_IDENTITY_ATTRIBUTES` - Defines the order and methods for parsing and validating identity.
    * :py:data:`SECURITY_PASSWORD_REQUIRED` - Can a user register w/o a password?
    * :py:data:`SECURITY_DEFAULT_REMEMBER_ME`
    * :py:data:`SECURITY_SMS_SERVICE` - When SMS is enabled in :py:data:`SECURITY_US_ENABLED_METHODS`.
    * :py:data:`SECURITY_SMS_SERVICE_CONFIG`
    * :py:data:`SECURITY_TOTP_SECRETS`
    * :py:data:`SECURITY_TOTP_ISSUER`
    * :py:data:`SECURITY_PHONE_REGION_DEFAULT`
    * :py:data:`SECURITY_LOGIN_ERROR_VIEW` - The user is redirected here if
      :py:data:`SECURITY_US_VERIFY_LINK_URL` has an error and the request is json and
      :py:data:`SECURITY_REDIRECT_BEHAVIOR` equals ``"spa"``.
    * :py:data:`SECURITY_FRESHNESS` - Used to protect /us-setup.
    * :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /us-setup.

Username-Recovery
-----------------

    .. versionadded:: 5.6.0

.. py:data:: SECURITY_USERNAME_RECOVERY

   Specifies whether username recovery is enabled. If set to ``True`` the UserModel
   must contain a column ``"username"``. Note that this feature is independent
   of the :py:data:`SECURITY_USERNAME_ENABLE` feature.

   Default: ``False``.

.. py:data:: SECURITY_USERNAME_RECOVERY_URL

   Specifies the username recovery URL.

   Default: ``"/recover-username"``.

.. py:data:: SECURITY_EMAIL_SUBJECT_USERNAME_RECOVERY

   Sets subject for the username recovery email.

   Default: ``_("Your requested username")``.

.. py:data:: SECURITY_USERNAME_RECOVERY_TEMPLATE

   Specifies the path to the template for the username recovery page.

   Default: ``"security/recover_username.html"``.

Change Username
-----------------

    .. versionadded:: 5.6.0

.. py:data:: SECURITY_CHANGE_USERNAME

   Specifies whether change username feature is enabled.
   This feature should be used in conjunction with
   the :py:data:`SECURITY_USERNAME_ENABLE` feature.

   Default: ``False``.

.. py:data:: SECURITY_CHANGE_USERNAME_URL

   Specifies the change username URL.

   Default: ``"/change-username"``.

.. py:data:: SECURITY_POST_CHANGE_USERNAME_VIEW

    Specifies the view to redirect to after a user successfully changes their username.
    This value can be set to a URL or an endpoint name.
    If this value is ``None``, the user is redirected  to the
    value of :data:`SECURITY_POST_LOGIN_VIEW`.

    Default: ``None``.

.. py:data:: SECURITY_SEND_USERNAME_CHANGE_EMAIL

   If ``True`` then an email will be sent to the registered user upon
   successful change of their username.

   Default: ``True``.

.. py:data:: SECURITY_EMAIL_SUBJECT_USERNAME_CHANGE_NOTICE

   Sets subject for the change username email.

   Default: ``_(""Your username has been changed"")``.

.. py:data:: SECURITY_CHANGE_USERNAME_TEMPLATE

   Specifies the path to the template for the change username page.

   Default: ``"security/change_username.html"``.

Additional relevant configuration variables:

    * :py:data:`SECURITY_FRESHNESS` - Used to protect /change-username.
    * :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /change-username.


Passwordless
-------------

This feature is DEPRECATED as of 5.0.0. Please use unified signin feature instead.

.. py:data:: SECURITY_PASSWORDLESS

    Specifies if Flask-Security should enable the passwordless login feature.
    If set to ``True``, users are not required to enter a password to login but are
    sent an email with a login link.
    **This feature is being replaced with a more generalized passwordless feature
    that includes using SMS or authenticator applications for generating codes.**

    Default: ``False``.

.. py:data:: SECURITY_SEND_LOGIN_TEMPLATE

    Specifies the path to the template for the send login instructions page for
    passwordless logins.

    Default:``"security/send_login.html"``.

.. py:data:: SECURITY_EMAIL_SUBJECT_PASSWORDLESS

    Sets the subject for the passwordless feature.

    Default: ``_("Login instructions")``.

.. py:data:: SECURITY_LOGIN_WITHIN

    Specifies the amount of time a user has before a login link expires.
    Always pluralize the time unit for this value.

    Default: ``"1 days"``.

.. py:data:: SECURITY_LOGIN_ERROR_VIEW

    Specifies the view/URL to redirect to after the following login/authentication errors:

    * GET passwordless link where the link is expired/incorrect
    * GET unified sign in magic link when there is an error.
    * GET on oauthresponse where there was an OAuth protocol error.
    * GET on oauthresponse where the returned identity isn't registered.

    This is only valid if :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``.
    Query params in the redirect will contain the error.

    Default: ``None``.

Trackable
----------
.. py:data:: SECURITY_TRACKABLE

    Specifies if Flask-Security should track basic user login statistics. If set to ``True``, ensure your
    models have the required fields/attributes and make sure to commit changes after calling
    ``login_user``. Be sure to use `ProxyFix <http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#proxy-setups>`_ if you are using a proxy.

    Default: ``False``

WebAuthn
--------------

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_WEBAUTHN

    To enable this feature - set this to ``True``. Please see :ref:`models_topic` for
    required additions to your database models.

    Default: ``False``

.. py:data:: SECURITY_WAN_REGISTER_URL

    Endpoint for registering WebAuthn credentials.

    Default: ``"/wan-register"``

.. py:data:: SECURITY_WAN_SIGNIN_URL

    Endpoint for signing in using a WebAuthn credential.

    Default: ``"/wan-signin"``

.. py:data:: SECURITY_WAN_DELETE_URL

    Endpoint for removing a WebAuthn credential.

    Default: ``"/wan-delete"``

.. py:data:: SECURITY_WAN_VERIFY_URL

    Endpoint for reauthenticating using a WebAuthn credential.

    Default: ``"/wan-verify"``

.. py:data:: SECURITY_WAN_POST_REGISTER_VIEW

    Specifies the view to redirect to after a user successfully registers a new WebAuthn key (non-json).
    This value can be set to a URL or an endpoint name.

    Default: ``".wan-register"``

.. py:data:: SECURITY_WAN_REGISTER_TEMPLATE

    Default: ``"security/wan_register.html"``

.. py:data:: SECURITY_WAN_SIGNIN_TEMPLATE

    Default: ``"security/wan_signin.html"``

.. py:data:: SECURITY_WAN_VERIFY_TEMPLATE

    Default: ``"security/wan_verify.html"``


.. py:data:: SECURITY_WAN_RP_NAME

    The Relying Party (that's us!) name passed as part of credential
    creation. Defined in the `spec <https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictionary-pkcredentialentity>`_.

    Default: ``"My Flask App"``

.. py:data:: SECURITY_WAN_REGISTER_WITHIN

    Specifies the amount of time a user has before their register
    token expires. Always pluralize the time unit for this value.

    Default: ``"30 minutes"``

.. py:data:: SECURITY_WAN_REGISTER_TIMEOUT

    Specifies the timeout that is passed as part of PublicKeyCredentialCreationOptions.
    In milliseconds.

    Default: ``60000``

.. py:data:: SECURITY_WAN_SIGNIN_WITHIN

    Specifies the amount of time a user has before their signin
    token expires. Always pluralize the time unit for this value.

    Default: ``"1 minutes"``

.. py:data:: SECURITY_WAN_SIGNIN_TIMEOUT

    Specifies the timeout that is passed as part of PublicKeyCredentialRequestOptions.
    In milliseconds.

    Default: ``60000``

.. py:data:: SECURITY_WAN_ALLOW_AS_FIRST_FACTOR

    If True then a WebAuthn credential/key may be registered for use as the first (or only)
    authentication factor. This will set the default ``AuthenticatorSelectionCriteria``
    to require a cross-platform key.

    Default: ``True``

.. py:data:: SECURITY_WAN_ALLOW_AS_MULTI_FACTOR

    If True then a WebAuthn credential/key can be used
    as both a primary and a secondary factor. This requires that the key
    supports 'UserVerification'.

    Default: ``True``

.. py:data:: SECURITY_WAN_ALLOW_USER_HINTS

    If True then an unauthenticated user can request a list of registered
    WebAuthn credentials/keys. This allows the use of non-resident (non-discoverable)
    keys, but has the possible security concern that it allows 'user discovery'.
    Look at https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-username-enumeration
    for a good writeup.

    If this is ``False`` and :py:data:`SECURITY_WAN_ALLOW_AS_FIRST_FACTOR` is ``True``
    (the default) then by default, ``AuthenticatorSelectionCriteria`` will be set
    to require a Resident key.

    Default: ``True``

.. py:data:: SECURITY_WAN_ALLOW_AS_VERIFY

    Sets which type of WebAuthn security credential, if any, may be used for
    reauthentication/verify events. This is a list with possible values:

        - ``"first"`` - just keys registered as "first" usage are allowed
        - ``"secondary"`` - just keys registered as "secondary" are allowed

    If list is empty or ``None`` WebAuthn keys aren't allowed. This also means that the
    :py:data:`SECURITY_WAN_VERIFY_URL` endpoint won't be registered.

    Default: ``["first", "secondary"]``


Additional relevant configuration variables:

    * :py:data:`SECURITY_FRESHNESS` - Used to protect /wan-register and /wan-delete.
    * :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /wan-register and /wan-delete.

Recovery Codes
--------------

    .. versionadded:: 5.0.0

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODES

    To enable this feature - set this to ``True``. Please see :ref:`models_topic` for
    required additions to your database models. This enables a user to generate and
    use a recovery code for two-factor authentication. This works for all two-factor
    mechanisms - including WebAuthn. Note that these code are single use and
    the user should be advised to write them down and store in a safe place.

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODES_N

    How many recovery codes to generate.

    Default:: ``5``

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODES_URL

    Endpoint for displaying and generating recovery codes.

    Default: ``"/mf-recovery-codes"``

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODES_TEMPLATE

    Default: ``"security/mf_recovery_codes.html"``

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_URL

    Endpoint for entering a recovery code.

    Default: ``"/mf-recovery"``

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_TEMPLATE

    Default: ``"security/mf_recovery.html"``

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODES_KEYS

    A list of keys used to encrypt the recovery codes at rest (i.e. in the database).
    The default implementation uses cryptography.fernet (https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet)
    - so the keys should be generated by::

        from cryptography.fernet import Fernet
        key = Fernet.generate_key()

    Multiple keys can be configured allowing for key rotation.

    Default: ``None`` - recovery codes will NOT be encrypted on disk

    .. versionadded:: 5.1.0

.. py:data:: SECURITY_MULTI_FACTOR_RECOVERY_CODE_TTL

    An integer passed to decrypt specifying the maximum age of the code.

    Default: ``None`` - no TTL will be enforced.

    .. versionadded:: 5.1.0

Additional relevant configuration variables:

    * :py:data:`SECURITY_FRESHNESS` - Used to protect /mf-recovery-codes.
    * :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /mf-recovery-codes.
    * :py:data:`SECURITY_TOTP_SECRETS` - TOTP/passlib is used to generate the codes.
    * :py:data:`SECURITY_TOTP_ISSUER`

Social Oauth
-------------
    .. versionadded:: 5.1.0

.. py:data:: SECURITY_OAUTH_ENABLE

    To enable using external Oauth providers - set this to ``True``.

.. py:data:: SECURITY_OAUTH_BUILTIN_PROVIDERS

    A list of built-in providers to register.

    Default: ``["google", "github"]``

.. py:data:: SECURITY_OAUTH_START_URL

    Endpoint for starting an Oauth authentication operation.

    Default: ``"/login/oauthstart"``

.. py:data:: SECURITY_OAUTH_RESPONSE_URL

    Endpoint used as Oauth redirect.

    Default: ``"/login/oauthresponse"``

.. py:data:: SECURITY_POST_OAUTH_LOGIN_VIEW

    Specifies the view/URL to redirect to after a successful authentication (login)
    using social oauth.
    This is only valid if :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``.
    Query params in the redirect will contain `identity` and `email`.

    Default: ``None``.

    .. versionadded:: 5.4.0



Feature Flags
-------------
All feature flags. By default all are ``False``/not enabled.

* :py:data:`SECURITY_CHANGE_EMAIL`
* :py:data:`SECURITY_CHANGE_USERNAME`
* :py:data:`SECURITY_CONFIRMABLE`
* :py:data:`SECURITY_REGISTERABLE`
* :py:data:`SECURITY_RECOVERABLE`
* :py:data:`SECURITY_TRACKABLE`
* :py:data:`SECURITY_PASSWORDLESS`
* :py:data:`SECURITY_CHANGEABLE`
* :py:data:`SECURITY_TWO_FACTOR`
* :py:data:`SECURITY_UNIFIED_SIGNIN`
* :py:data:`SECURITY_USERNAME_RECOVERY`
* :py:data:`SECURITY_WEBAUTHN`
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_CODES`
* :py:data:`SECURITY_OAUTH_ENABLE`

URLs and Views
--------------
A list of all URLs and Views:

* :py:data:`SECURITY_LOGIN_URL` ``"/login"``
* :py:data:`SECURITY_LOGOUT_URL` ``"/logout"``
* :py:data:`SECURITY_VERIFY_URL` ``"/verify"``
* :py:data:`SECURITY_REGISTER_URL` ``"/register"``
* :py:data:`SECURITY_CHANGE_EMAIL_URL` ``"change-email"``
* :py:data:`SECURITY_CHANGE_EMAIL_CONFIRM_URL` ``"/change-email-confirm"``
* :py:data:`SECURITY_CHANGE_USERNAME_URL` ``"change-username"``
* :py:data:`SECURITY_RESET_URL` ``"/reset"``
* :py:data:`SECURITY_CHANGE_URL` ``"/change"``
* :py:data:`SECURITY_CONFIRM_URL` ``"/confirm"``
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_CODES_URL` ``"/mf-recovery-codes"``
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_URL` ``"/mf-recovery"``
* :py:data:`SECURITY_OAUTH_START_URL` ``"/login/oauthstart"``
* :py:data:`SECURITY_OAUTH_RESPONSE_URL` ``"/login/oauthresponse"``
* :py:data:`SECURITY_TWO_FACTOR_SELECT_URL` ``"/tf-select"``
* :py:data:`SECURITY_TWO_FACTOR_SETUP_URL` ``"/tf-setup"``
* :py:data:`SECURITY_TWO_FACTOR_TOKEN_VALIDATION_URL` ``"/tf-validate"``
* :py:data:`SECURITY_TWO_FACTOR_RESCUE_URL` ``"/tf-rescue"``
* :py:data:`SECURITY_TWO_FACTOR_ERROR_VIEW`
* :py:data:`SECURITY_TWO_FACTOR_POST_SETUP_VIEW`
* :py:data:`SECURITY_POST_LOGIN_VIEW`
* :py:data:`SECURITY_POST_LOGOUT_VIEW`
* :py:data:`SECURITY_CONFIRM_ERROR_VIEW`
* :py:data:`SECURITY_POST_REGISTER_VIEW`
* :py:data:`SECURITY_POST_CONFIRM_VIEW`
* :py:data:`SECURITY_POST_RESET_VIEW`
* :py:data:`SECURITY_POST_CHANGE_VIEW`
* :py:data:`SECURITY_POST_OAUTH_LOGIN_VIEW`
* :py:data:`SECURITY_UNAUTHORIZED_VIEW`
* :py:data:`SECURITY_RESET_VIEW`
* :py:data:`SECURITY_RESET_ERROR_VIEW`
* :py:data:`SECURITY_LOGIN_ERROR_VIEW`
* :py:data:`SECURITY_USERNAME_RECOVERY_URL`
* :py:data:`SECURITY_US_SIGNIN_URL`
* :py:data:`SECURITY_US_SETUP_URL`
* :py:data:`SECURITY_US_SIGNIN_SEND_CODE_URL`
* :py:data:`SECURITY_US_VERIFY_LINK_URL`
* :py:data:`SECURITY_US_VERIFY_URL`
* :py:data:`SECURITY_US_VERIFY_SEND_CODE_URL`
* :py:data:`SECURITY_US_POST_SETUP_VIEW`
* :py:data:`SECURITY_WAN_REGISTER_URL`
* :py:data:`SECURITY_WAN_SIGNIN_URL`
* :py:data:`SECURITY_WAN_DELETE_URL`
* :py:data:`SECURITY_WAN_VERIFY_URL`
* :py:data:`SECURITY_WAN_POST_REGISTER_VIEW`

Template Paths
--------------
A list of all templates:

* :py:data:`SECURITY_FORGOT_PASSWORD_TEMPLATE`
* :py:data:`SECURITY_LOGIN_USER_TEMPLATE`
* :py:data:`SECURITY_VERIFY_TEMPLATE`
* :py:data:`SECURITY_REGISTER_USER_TEMPLATE`
* :py:data:`SECURITY_RESET_PASSWORD_TEMPLATE`
* :py:data:`SECURITY_CHANGE_PASSWORD_TEMPLATE`
* :py:data:`SECURITY_CHANGE_EMAIL_TEMPLATE`
* :py:data:`SECURITY_CHANGE_USERNAME_TEMPLATE`
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_TEMPLATE`
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_CODES_TEMPLATE`
* :py:data:`SECURITY_SEND_CONFIRMATION_TEMPLATE`
* :py:data:`SECURITY_SEND_LOGIN_TEMPLATE`
* :py:data:`SECURITY_TWO_FACTOR_VERIFY_CODE_TEMPLATE`
* :py:data:`SECURITY_TWO_FACTOR_SELECT_TEMPLATE`
* :py:data:`SECURITY_TWO_FACTOR_SETUP_TEMPLATE`
* :py:data:`SECURITY_USERNAME_RECOVERY_TEMPLATE`
* :py:data:`SECURITY_US_SIGNIN_TEMPLATE`
* :py:data:`SECURITY_US_SETUP_TEMPLATE`
* :py:data:`SECURITY_US_VERIFY_TEMPLATE`
* :py:data:`SECURITY_WAN_REGISTER_TEMPLATE`
* :py:data:`SECURITY_WAN_SIGNIN_TEMPLATE`
* :py:data:`SECURITY_WAN_VERIFY_TEMPLATE`

Messages
-------------

The following are the messages Flask-Security uses.  They are tuples; the first
element is the message and the second element is the error level.

The default messages and error levels can be found in ``core.py``.

* ``SECURITY_MSG_ALREADY_CONFIRMED``
* ``SECURITY_MSG_API_ERROR``
* ``SECURITY_MSG_ANONYMOUS_USER_REQUIRED``
* ``SECURITY_MSG_CHANGE_EMAIL_EXPIRED``
* ``SECURITY_MSG_CHANGE_EMAIL_CONFIRMED``
* ``SECURITY_MSG_CHANGE_EMAIL_SENT``
* ``SECURITY_MSG_CODE_HAS_BEEN_SENT``
* ``SECURITY_MSG_CONFIRMATION_EXPIRED``
* ``SECURITY_MSG_CONFIRMATION_REQUEST``
* ``SECURITY_MSG_CONFIRMATION_REQUIRED``
* ``SECURITY_MSG_CONFIRM_REGISTRATION``
* ``SECURITY_MSG_DISABLED_ACCOUNT``
* ``SECURITY_MSG_EMAIL_ALREADY_ASSOCIATED``
* ``SECURITY_MSG_EMAIL_CONFIRMED``
* ``SECURITY_MSG_EMAIL_NOT_PROVIDED``
* ``SECURITY_MSG_FAILED_TO_SEND_CODE``
* ``SECURITY_MSG_FORGOT_PASSWORD``
* ``SECURITY_MSG_GENERIC_AUTHN_FAILED``
* ``SECURITY_MSG_GENERIC_RECOVERY``
* ``SECURITY_MSG_GENERIC_US_SIGNIN``
* ``SECURITY_MSG_IDENTITY_ALREADY_ASSOCIATED``
* ``SECURITY_MSG_IDENTITY_NOT_REGISTERED``
* ``SECURITY_MSG_INVALID_CODE``
* ``SECURITY_MSG_INVALID_CONFIRMATION_TOKEN``
* ``SECURITY_MSG_INVALID_EMAIL_ADDRESS``
* ``SECURITY_MSG_INVALID_LOGIN_TOKEN``
* ``SECURITY_MSG_INVALID_PASSWORD``
* ``SECURITY_MSG_INVALID_PASSWORD_CODE``
* ``SECURITY_MSG_INVALID_RECOVERY_CODE``
* ``SECURITY_MSG_INVALID_REDIRECT``
* ``SECURITY_MSG_INVALID_RESET_PASSWORD_TOKEN``
* ``SECURITY_MSG_LOGIN``
* ``SECURITY_MSG_LOGIN_EMAIL_SENT``
* ``SECURITY_MSG_LOGIN_EXPIRED``
* ``SECURITY_MSG_NO_RECOVERY_CODES_SETUP``
* ``SECURITY_MSG_OAUTH_HANDSHAKE_ERROR``
* ``SECURITY_MSG_PASSWORDLESS_LOGIN_SUCCESSFUL``
* ``SECURITY_MSG_PASSWORD_BREACHED``
* ``SECURITY_MSG_PASSWORD_BREACHED_SITE_ERROR``
* ``SECURITY_MSG_PASSWORD_CHANGE``
* ``SECURITY_MSG_PASSWORD_INVALID_LENGTH``
* ``SECURITY_MSG_PASSWORD_IS_THE_SAME``
* ``SECURITY_MSG_PASSWORD_MISMATCH``
* ``SECURITY_MSG_PASSWORD_NOT_PROVIDED``
* ``SECURITY_MSG_PASSWORD_REQUIRED``
* ``SECURITY_MSG_PASSWORD_RESET``
* ``SECURITY_MSG_PASSWORD_RESET_EXPIRED``
* ``SECURITY_MSG_PASSWORD_RESET_NO_LOGIN``
* ``SECURITY_MSG_PASSWORD_RESET_REQUEST``
* ``SECURITY_MSG_PASSWORD_TOO_SIMPLE``
* ``SECURITY_MSG_PHONE_INVALID``
* ``SECURITY_MSG_REAUTHENTICATION_REQUIRED``
* ``SECURITY_MSG_REAUTHENTICATION_SUCCESSFUL``
* ``SECURITY_MSG_REFRESH``
* ``SECURITY_MSG_RETYPE_PASSWORD_MISMATCH``
* ``SECURITY_MSG_TWO_FACTOR_INVALID_TOKEN``
* ``SECURITY_MSG_TWO_FACTOR_LOGIN_SUCCESSFUL``
* ``SECURITY_MSG_TWO_FACTOR_CHANGE_METHOD_SUCCESSFUL``
* ``SECURITY_MSG_TWO_FACTOR_PERMISSION_DENIED``
* ``SECURITY_MSG_TWO_FACTOR_METHOD_NOT_AVAILABLE``
* ``SECURITY_MSG_TWO_FACTOR_SETUP_EXPIRED``
* ``SECURITY_MSG_TWO_FACTOR_DISABLED``
* ``SECURITY_MSG_UNAUTHORIZED``
* ``SECURITY_MSG_UNAUTHENTICATED``
* ``SECURITY_MSG_US_METHOD_NOT_AVAILABLE``
* ``SECURITY_MSG_US_SETUP_EXPIRED``
* ``SECURITY_MSG_US_SETUP_SUCCESSFUL``
* ``SECURITY_MSG_US_SPECIFY_IDENTITY``
* ``SECURITY_MSG_USE_CODE``
* ``SECURITY_MSG_USER_DOES_NOT_EXIST``
* ``SECURITY_MSG_USERNAME_CHANGE``
* ``SECURITY_MSG_USERNAME_INVALID_LENGTH``
* ``SECURITY_MSG_USERNAME_ILLEGAL_CHARACTERS``
* ``SECURITY_MSG_USERNAME_DISALLOWED_CHARACTERS``
* ``SECURITY_MSG_USERNAME_NOT_PROVIDED``
* ``SECURITY_MSG_USERNAME_ALREADY_ASSOCIATED``
* ``SECURITY_MSG_USERNAME_RECOVERY_REQUEST``
* ``SECURITY_MSG_WEBAUTHN_EXPIRED``
* ``SECURITY_MSG_WEBAUTHN_NAME_REQUIRED``
* ``SECURITY_MSG_WEBAUTHN_NAME_INUSE``
* ``SECURITY_MSG_WEBAUTHN_NAME_NOT_FOUND``
* ``SECURITY_MSG_WEBAUTHN_CREDENTIAL_DELETED``
* ``SECURITY_MSG_WEBAUTHN_REGISTER_SUCCESSFUL``
* ``SECURITY_MSG_WEBAUTHN_CREDENTIAL_ID_INUSE``
* ``SECURITY_MSG_WEBAUTHN_UNKNOWN_CREDENTIAL_ID``
* ``SECURITY_MSG_WEBAUTHN_ORPHAN_CREDENTIAL_ID``
* ``SECURITY_MSG_WEBAUTHN_NO_VERIFY``
* ``SECURITY_MSG_WEBAUTHN_CREDENTIAL_WRONG_USAGE``
* ``SECURITY_MSG_WEBAUTHN_MISMATCH_USER_HANDLE``

.. _passlib's CryptoContext: https://passlib.readthedocs.io/en/stable/lib/passlib.context.html