@faable/auth-sdk 2.5.69 → 2.5.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/spec/openapi.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "info": {
4
4
  "title": "@faablecloud/auth",
5
5
  "description": "Auth Platform made by Faable. Manage Users and Roles",
6
- "version": "2.1.1",
6
+ "version": "2.2.1",
7
7
  "license": {
8
8
  "name": "private",
9
9
  "url": "https://faable.com/docs/platform/privacy-policy"
@@ -175,6 +175,97 @@
175
175
  ],
176
176
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
177
177
  },
178
+ "login_methods": {
179
+ "type": "object",
180
+ "properties": {
181
+ "order": {
182
+ "type": "array",
183
+ "items": {
184
+ "type": "string"
185
+ },
186
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
187
+ },
188
+ "passkey_login_enabled": {
189
+ "type": "boolean",
190
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
191
+ },
192
+ "identifier_first": {
193
+ "type": "boolean",
194
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
195
+ },
196
+ "remember_last_method": {
197
+ "type": "boolean",
198
+ "description": "Surface the method the returning user chose last time. Defaults to false."
199
+ }
200
+ },
201
+ "additionalProperties": false,
202
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
203
+ },
204
+ "mfa_policy": {
205
+ "type": "object",
206
+ "properties": {
207
+ "mode": {
208
+ "anyOf": [
209
+ {
210
+ "anyOf": [
211
+ {
212
+ "type": "string",
213
+ "enum": [
214
+ "off"
215
+ ]
216
+ },
217
+ {
218
+ "type": "string",
219
+ "enum": [
220
+ "optional"
221
+ ]
222
+ },
223
+ {
224
+ "type": "string",
225
+ "enum": [
226
+ "required"
227
+ ]
228
+ }
229
+ ]
230
+ }
231
+ ],
232
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
233
+ },
234
+ "allowed_factors": {
235
+ "type": "array",
236
+ "items": {
237
+ "anyOf": [
238
+ {
239
+ "type": "string",
240
+ "enum": [
241
+ "totp"
242
+ ]
243
+ },
244
+ {
245
+ "type": "string",
246
+ "enum": [
247
+ "webauthn"
248
+ ]
249
+ }
250
+ ]
251
+ },
252
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
253
+ },
254
+ "remember_device_days": {
255
+ "type": "integer",
256
+ "minimum": 0,
257
+ "maximum": 365,
258
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
259
+ }
260
+ },
261
+ "additionalProperties": false,
262
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
263
+ },
264
+ "webauthn_rp_id": {
265
+ "type": "string",
266
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
267
+ "nullable": true
268
+ },
178
269
  "createdAt": {
179
270
  "type": "string",
180
271
  "description": "AuthAccount creation date"
@@ -832,6 +923,114 @@
832
923
  "description": "Presentation metadata for one connection type. Contains no endpoint URLs and no credentials.",
833
924
  "additionalProperties": false
834
925
  },
926
+ "LoginOptionMethod": {
927
+ "anyOf": [
928
+ {
929
+ "type": "object",
930
+ "required": [
931
+ "kind"
932
+ ],
933
+ "properties": {
934
+ "kind": {
935
+ "type": "string",
936
+ "enum": [
937
+ "passkey"
938
+ ]
939
+ }
940
+ },
941
+ "additionalProperties": false
942
+ },
943
+ {
944
+ "type": "object",
945
+ "required": [
946
+ "kind",
947
+ "id",
948
+ "connection_type",
949
+ "connection_name",
950
+ "password_policy"
951
+ ],
952
+ "properties": {
953
+ "kind": {
954
+ "type": "string",
955
+ "enum": [
956
+ "connection"
957
+ ]
958
+ },
959
+ "id": {
960
+ "type": "string"
961
+ },
962
+ "connection_type": {
963
+ "type": "string"
964
+ },
965
+ "connection_name": {
966
+ "type": "string"
967
+ },
968
+ "password_policy": {
969
+ "type": "object",
970
+ "required": [
971
+ "level"
972
+ ],
973
+ "properties": {
974
+ "level": {
975
+ "anyOf": [
976
+ {
977
+ "type": "string",
978
+ "enum": [
979
+ "none"
980
+ ]
981
+ },
982
+ {
983
+ "type": "string",
984
+ "enum": [
985
+ "low"
986
+ ]
987
+ },
988
+ {
989
+ "type": "string",
990
+ "enum": [
991
+ "fair"
992
+ ]
993
+ },
994
+ {
995
+ "type": "string",
996
+ "enum": [
997
+ "good"
998
+ ]
999
+ },
1000
+ {
1001
+ "type": "string",
1002
+ "enum": [
1003
+ "excellent"
1004
+ ]
1005
+ }
1006
+ ]
1007
+ },
1008
+ "min_length": {
1009
+ "type": "integer",
1010
+ "minimum": 1,
1011
+ "maximum": 128
1012
+ },
1013
+ "require_lowercase": {
1014
+ "type": "boolean"
1015
+ },
1016
+ "require_uppercase": {
1017
+ "type": "boolean"
1018
+ },
1019
+ "require_number": {
1020
+ "type": "boolean"
1021
+ },
1022
+ "require_special": {
1023
+ "type": "boolean"
1024
+ }
1025
+ },
1026
+ "description": "Password policy enforced when writing a password through this database connection (password reset and admin set-password). `level` is an Auth0-style preset (none/low/fair/good/excellent); the dashboard expands it into the explicit rule fields when saving. The rule fields override the preset baseline. When unset on the connection, the server applies the `good` default. Does not affect login."
1027
+ }
1028
+ },
1029
+ "additionalProperties": false
1030
+ }
1031
+ ],
1032
+ "description": "One method the login screen should offer. Discriminated by `kind`. Connection methods carry only what a login screen needs — never credentials, endpoints or the rest of the Connection document."
1033
+ },
835
1034
  "Client": {
836
1035
  "type": "object",
837
1036
  "required": [
@@ -970,6 +1169,92 @@
970
1169
  "frontchannel_logout_session_required": {
971
1170
  "type": "boolean"
972
1171
  },
1172
+ "login_methods": {
1173
+ "type": "object",
1174
+ "properties": {
1175
+ "order": {
1176
+ "type": "array",
1177
+ "items": {
1178
+ "type": "string"
1179
+ },
1180
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
1181
+ },
1182
+ "passkey_login_enabled": {
1183
+ "type": "boolean",
1184
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
1185
+ },
1186
+ "identifier_first": {
1187
+ "type": "boolean",
1188
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
1189
+ },
1190
+ "remember_last_method": {
1191
+ "type": "boolean",
1192
+ "description": "Surface the method the returning user chose last time. Defaults to false."
1193
+ }
1194
+ },
1195
+ "additionalProperties": false,
1196
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
1197
+ },
1198
+ "mfa_policy": {
1199
+ "type": "object",
1200
+ "properties": {
1201
+ "mode": {
1202
+ "anyOf": [
1203
+ {
1204
+ "anyOf": [
1205
+ {
1206
+ "type": "string",
1207
+ "enum": [
1208
+ "off"
1209
+ ]
1210
+ },
1211
+ {
1212
+ "type": "string",
1213
+ "enum": [
1214
+ "optional"
1215
+ ]
1216
+ },
1217
+ {
1218
+ "type": "string",
1219
+ "enum": [
1220
+ "required"
1221
+ ]
1222
+ }
1223
+ ]
1224
+ }
1225
+ ],
1226
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
1227
+ },
1228
+ "allowed_factors": {
1229
+ "type": "array",
1230
+ "items": {
1231
+ "anyOf": [
1232
+ {
1233
+ "type": "string",
1234
+ "enum": [
1235
+ "totp"
1236
+ ]
1237
+ },
1238
+ {
1239
+ "type": "string",
1240
+ "enum": [
1241
+ "webauthn"
1242
+ ]
1243
+ }
1244
+ ]
1245
+ },
1246
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
1247
+ },
1248
+ "remember_device_days": {
1249
+ "type": "integer",
1250
+ "minimum": 0,
1251
+ "maximum": 365,
1252
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
1253
+ }
1254
+ },
1255
+ "additionalProperties": false,
1256
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
1257
+ },
973
1258
  "account": {
974
1259
  "type": "string",
975
1260
  "description": "Object is related with this account"
@@ -1164,42 +1449,142 @@
1164
1449
  "frontchannel_logout_session_required": {
1165
1450
  "type": "boolean"
1166
1451
  },
1167
- "metadata": {
1168
- "type": "object",
1169
- "properties": {},
1170
- "additionalProperties": true,
1171
- "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1172
- "default": {}
1173
- }
1174
- },
1175
- "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
1176
- "additionalProperties": false
1177
- },
1178
- "ClientUpdateMetadata": {
1179
- "type": "object",
1180
- "properties": {},
1181
- "additionalProperties": true,
1182
- "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1183
- "default": {}
1184
- },
1185
- "User": {
1186
- "type": "object",
1187
- "required": [
1188
- "id",
1189
- "email_verified",
1190
- "phone_verified",
1191
- "logins_count",
1192
- "user_metadata",
1193
- "app_metadata",
1194
- "account",
1195
- "createdAt"
1196
- ],
1197
- "properties": {
1198
- "id": {
1199
- "type": "string",
1200
- "description": "User ID"
1201
- },
1202
- "name": {
1452
+ "login_methods": {
1453
+ "anyOf": [
1454
+ {
1455
+ "type": "object",
1456
+ "properties": {
1457
+ "order": {
1458
+ "type": "array",
1459
+ "items": {
1460
+ "type": "string"
1461
+ },
1462
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
1463
+ },
1464
+ "passkey_login_enabled": {
1465
+ "type": "boolean",
1466
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
1467
+ },
1468
+ "identifier_first": {
1469
+ "type": "boolean",
1470
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
1471
+ },
1472
+ "remember_last_method": {
1473
+ "type": "boolean",
1474
+ "description": "Surface the method the returning user chose last time. Defaults to false."
1475
+ }
1476
+ },
1477
+ "additionalProperties": false,
1478
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
1479
+ },
1480
+ {
1481
+ "type": "null"
1482
+ }
1483
+ ]
1484
+ },
1485
+ "mfa_policy": {
1486
+ "anyOf": [
1487
+ {
1488
+ "type": "object",
1489
+ "properties": {
1490
+ "mode": {
1491
+ "anyOf": [
1492
+ {
1493
+ "anyOf": [
1494
+ {
1495
+ "type": "string",
1496
+ "enum": [
1497
+ "off"
1498
+ ]
1499
+ },
1500
+ {
1501
+ "type": "string",
1502
+ "enum": [
1503
+ "optional"
1504
+ ]
1505
+ },
1506
+ {
1507
+ "type": "string",
1508
+ "enum": [
1509
+ "required"
1510
+ ]
1511
+ }
1512
+ ]
1513
+ }
1514
+ ],
1515
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
1516
+ },
1517
+ "allowed_factors": {
1518
+ "type": "array",
1519
+ "items": {
1520
+ "anyOf": [
1521
+ {
1522
+ "type": "string",
1523
+ "enum": [
1524
+ "totp"
1525
+ ]
1526
+ },
1527
+ {
1528
+ "type": "string",
1529
+ "enum": [
1530
+ "webauthn"
1531
+ ]
1532
+ }
1533
+ ]
1534
+ },
1535
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
1536
+ },
1537
+ "remember_device_days": {
1538
+ "type": "integer",
1539
+ "minimum": 0,
1540
+ "maximum": 365,
1541
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
1542
+ }
1543
+ },
1544
+ "additionalProperties": false,
1545
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
1546
+ },
1547
+ {
1548
+ "type": "null"
1549
+ }
1550
+ ]
1551
+ },
1552
+ "metadata": {
1553
+ "type": "object",
1554
+ "properties": {},
1555
+ "additionalProperties": true,
1556
+ "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1557
+ "default": {}
1558
+ }
1559
+ },
1560
+ "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
1561
+ "additionalProperties": false
1562
+ },
1563
+ "ClientUpdateMetadata": {
1564
+ "type": "object",
1565
+ "properties": {},
1566
+ "additionalProperties": true,
1567
+ "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
1568
+ "default": {}
1569
+ },
1570
+ "User": {
1571
+ "type": "object",
1572
+ "required": [
1573
+ "id",
1574
+ "email_verified",
1575
+ "phone_verified",
1576
+ "logins_count",
1577
+ "user_metadata",
1578
+ "app_metadata",
1579
+ "account",
1580
+ "createdAt"
1581
+ ],
1582
+ "properties": {
1583
+ "id": {
1584
+ "type": "string",
1585
+ "description": "User ID"
1586
+ },
1587
+ "name": {
1203
1588
  "type": "string",
1204
1589
  "description": "User name",
1205
1590
  "nullable": true
@@ -1710,6 +2095,33 @@
1710
2095
  "additionalProperties": true,
1711
2096
  "description": "App defined metadata"
1712
2097
  },
2098
+ "AdminFactor": {
2099
+ "type": "object",
2100
+ "required": [
2101
+ "id",
2102
+ "type"
2103
+ ],
2104
+ "properties": {
2105
+ "id": {
2106
+ "type": "string"
2107
+ },
2108
+ "type": {
2109
+ "type": "string"
2110
+ },
2111
+ "name": {
2112
+ "type": "string"
2113
+ },
2114
+ "confirmed_at": {
2115
+ "type": "string"
2116
+ },
2117
+ "last_used_at": {
2118
+ "type": "string"
2119
+ },
2120
+ "remaining": {
2121
+ "type": "integer"
2122
+ }
2123
+ }
2124
+ },
1713
2125
  "Identity": {
1714
2126
  "type": "object",
1715
2127
  "required": [
@@ -4186,11 +4598,142 @@
4186
4598
  "default": false
4187
4599
  }
4188
4600
  }
4601
+ },
4602
+ "login_methods": {
4603
+ "anyOf": [
4604
+ {
4605
+ "type": "object",
4606
+ "properties": {
4607
+ "order": {
4608
+ "type": "array",
4609
+ "items": {
4610
+ "type": "string"
4611
+ },
4612
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
4613
+ },
4614
+ "passkey_login_enabled": {
4615
+ "type": "boolean",
4616
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
4617
+ },
4618
+ "identifier_first": {
4619
+ "type": "boolean",
4620
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
4621
+ },
4622
+ "remember_last_method": {
4623
+ "type": "boolean",
4624
+ "description": "Surface the method the returning user chose last time. Defaults to false."
4625
+ }
4626
+ },
4627
+ "additionalProperties": false,
4628
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
4629
+ },
4630
+ {
4631
+ "type": "null"
4632
+ }
4633
+ ]
4634
+ },
4635
+ "mfa_policy": {
4636
+ "anyOf": [
4637
+ {
4638
+ "type": "object",
4639
+ "properties": {
4640
+ "mode": {
4641
+ "anyOf": [
4642
+ {
4643
+ "anyOf": [
4644
+ {
4645
+ "type": "string",
4646
+ "enum": [
4647
+ "off"
4648
+ ]
4649
+ },
4650
+ {
4651
+ "type": "string",
4652
+ "enum": [
4653
+ "optional"
4654
+ ]
4655
+ },
4656
+ {
4657
+ "type": "string",
4658
+ "enum": [
4659
+ "required"
4660
+ ]
4661
+ }
4662
+ ]
4663
+ }
4664
+ ],
4665
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
4666
+ },
4667
+ "allowed_factors": {
4668
+ "type": "array",
4669
+ "items": {
4670
+ "anyOf": [
4671
+ {
4672
+ "type": "string",
4673
+ "enum": [
4674
+ "totp"
4675
+ ]
4676
+ },
4677
+ {
4678
+ "type": "string",
4679
+ "enum": [
4680
+ "webauthn"
4681
+ ]
4682
+ }
4683
+ ]
4684
+ },
4685
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
4686
+ },
4687
+ "remember_device_days": {
4688
+ "type": "integer",
4689
+ "minimum": 0,
4690
+ "maximum": 365,
4691
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
4692
+ }
4693
+ },
4694
+ "additionalProperties": false,
4695
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
4696
+ },
4697
+ {
4698
+ "type": "null"
4699
+ }
4700
+ ]
4701
+ },
4702
+ "webauthn_rp_id": {
4703
+ "type": "string",
4704
+ "nullable": true
4189
4705
  }
4190
4706
  },
4191
4707
  "description": "AuthAccountUpdate",
4192
4708
  "additionalProperties": false
4193
4709
  },
4710
+ "FactorSummary": {
4711
+ "type": "object",
4712
+ "required": [
4713
+ "id",
4714
+ "type"
4715
+ ],
4716
+ "properties": {
4717
+ "id": {
4718
+ "type": "string"
4719
+ },
4720
+ "type": {
4721
+ "type": "string"
4722
+ },
4723
+ "name": {
4724
+ "type": "string"
4725
+ },
4726
+ "confirmed_at": {
4727
+ "type": "string"
4728
+ },
4729
+ "last_used_at": {
4730
+ "type": "string"
4731
+ },
4732
+ "remaining": {
4733
+ "type": "integer"
4734
+ }
4735
+ }
4736
+ },
4194
4737
  "OAuthTokenParams": {
4195
4738
  "type": "object",
4196
4739
  "properties": {
@@ -4220,6 +4763,18 @@
4220
4763
  "password"
4221
4764
  ]
4222
4765
  },
4766
+ {
4767
+ "type": "string",
4768
+ "enum": [
4769
+ "http://auth0.com/oauth/grant-type/mfa-otp"
4770
+ ]
4771
+ },
4772
+ {
4773
+ "type": "string",
4774
+ "enum": [
4775
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
4776
+ ]
4777
+ },
4223
4778
  {
4224
4779
  "type": "string",
4225
4780
  "enum": [
@@ -4265,6 +4820,14 @@
4265
4820
  "refresh_token": {
4266
4821
  "type": "string"
4267
4822
  },
4823
+ "mfa_token": {
4824
+ "type": "string",
4825
+ "description": "Opaque token returned with a `403 mfa_required` response. Present it here with `grant_type=http://auth0.com/oauth/grant-type/mfa-otp` (or `…/mfa-recovery-code`) and the code, to finish a grant a second-factor policy interrupted."
4826
+ },
4827
+ "recovery_code": {
4828
+ "type": "string",
4829
+ "description": "One of the user's one-time recovery codes, for `grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code`."
4830
+ },
4268
4831
  "subject_token": {
4269
4832
  "type": "string"
4270
4833
  },
@@ -4315,23 +4878,35 @@
4315
4878
  {
4316
4879
  "type": "string",
4317
4880
  "enum": [
4318
- "http://auth0.com/oauth/grant-type/passwordless/otp"
4881
+ "http://auth0.com/oauth/grant-type/mfa-otp"
4319
4882
  ]
4320
4883
  },
4321
4884
  {
4322
4885
  "type": "string",
4323
4886
  "enum": [
4324
- "urn:ietf:params:oauth:grant-type:token-exchange"
4887
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
4325
4888
  ]
4326
4889
  },
4327
4890
  {
4328
4891
  "type": "string",
4329
4892
  "enum": [
4330
- "urn:ietf:params:oauth:grant-type:device_code"
4893
+ "http://auth0.com/oauth/grant-type/passwordless/otp"
4331
4894
  ]
4332
- }
4333
- ],
4334
- "description": "Grant Type. https://oauth.net/2/grant-types/"
4895
+ },
4896
+ {
4897
+ "type": "string",
4898
+ "enum": [
4899
+ "urn:ietf:params:oauth:grant-type:token-exchange"
4900
+ ]
4901
+ },
4902
+ {
4903
+ "type": "string",
4904
+ "enum": [
4905
+ "urn:ietf:params:oauth:grant-type:device_code"
4906
+ ]
4907
+ }
4908
+ ],
4909
+ "description": "Grant Type. https://oauth.net/2/grant-types/"
4335
4910
  },
4336
4911
  "UsernamepasswordLoginBody": {
4337
4912
  "type": "object",
@@ -4606,6 +5181,97 @@
4606
5181
  ],
4607
5182
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
4608
5183
  },
5184
+ "login_methods": {
5185
+ "type": "object",
5186
+ "properties": {
5187
+ "order": {
5188
+ "type": "array",
5189
+ "items": {
5190
+ "type": "string"
5191
+ },
5192
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
5193
+ },
5194
+ "passkey_login_enabled": {
5195
+ "type": "boolean",
5196
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
5197
+ },
5198
+ "identifier_first": {
5199
+ "type": "boolean",
5200
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
5201
+ },
5202
+ "remember_last_method": {
5203
+ "type": "boolean",
5204
+ "description": "Surface the method the returning user chose last time. Defaults to false."
5205
+ }
5206
+ },
5207
+ "additionalProperties": false,
5208
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
5209
+ },
5210
+ "mfa_policy": {
5211
+ "type": "object",
5212
+ "properties": {
5213
+ "mode": {
5214
+ "anyOf": [
5215
+ {
5216
+ "anyOf": [
5217
+ {
5218
+ "type": "string",
5219
+ "enum": [
5220
+ "off"
5221
+ ]
5222
+ },
5223
+ {
5224
+ "type": "string",
5225
+ "enum": [
5226
+ "optional"
5227
+ ]
5228
+ },
5229
+ {
5230
+ "type": "string",
5231
+ "enum": [
5232
+ "required"
5233
+ ]
5234
+ }
5235
+ ]
5236
+ }
5237
+ ],
5238
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
5239
+ },
5240
+ "allowed_factors": {
5241
+ "type": "array",
5242
+ "items": {
5243
+ "anyOf": [
5244
+ {
5245
+ "type": "string",
5246
+ "enum": [
5247
+ "totp"
5248
+ ]
5249
+ },
5250
+ {
5251
+ "type": "string",
5252
+ "enum": [
5253
+ "webauthn"
5254
+ ]
5255
+ }
5256
+ ]
5257
+ },
5258
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
5259
+ },
5260
+ "remember_device_days": {
5261
+ "type": "integer",
5262
+ "minimum": 0,
5263
+ "maximum": 365,
5264
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
5265
+ }
5266
+ },
5267
+ "additionalProperties": false,
5268
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
5269
+ },
5270
+ "webauthn_rp_id": {
5271
+ "type": "string",
5272
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
5273
+ "nullable": true
5274
+ },
4609
5275
  "createdAt": {
4610
5276
  "type": "string",
4611
5277
  "description": "AuthAccount creation date"
@@ -4836,6 +5502,97 @@
4836
5502
  ],
4837
5503
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
4838
5504
  },
5505
+ "login_methods": {
5506
+ "type": "object",
5507
+ "properties": {
5508
+ "order": {
5509
+ "type": "array",
5510
+ "items": {
5511
+ "type": "string"
5512
+ },
5513
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
5514
+ },
5515
+ "passkey_login_enabled": {
5516
+ "type": "boolean",
5517
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
5518
+ },
5519
+ "identifier_first": {
5520
+ "type": "boolean",
5521
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
5522
+ },
5523
+ "remember_last_method": {
5524
+ "type": "boolean",
5525
+ "description": "Surface the method the returning user chose last time. Defaults to false."
5526
+ }
5527
+ },
5528
+ "additionalProperties": false,
5529
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
5530
+ },
5531
+ "mfa_policy": {
5532
+ "type": "object",
5533
+ "properties": {
5534
+ "mode": {
5535
+ "anyOf": [
5536
+ {
5537
+ "anyOf": [
5538
+ {
5539
+ "type": "string",
5540
+ "enum": [
5541
+ "off"
5542
+ ]
5543
+ },
5544
+ {
5545
+ "type": "string",
5546
+ "enum": [
5547
+ "optional"
5548
+ ]
5549
+ },
5550
+ {
5551
+ "type": "string",
5552
+ "enum": [
5553
+ "required"
5554
+ ]
5555
+ }
5556
+ ]
5557
+ }
5558
+ ],
5559
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
5560
+ },
5561
+ "allowed_factors": {
5562
+ "type": "array",
5563
+ "items": {
5564
+ "anyOf": [
5565
+ {
5566
+ "type": "string",
5567
+ "enum": [
5568
+ "totp"
5569
+ ]
5570
+ },
5571
+ {
5572
+ "type": "string",
5573
+ "enum": [
5574
+ "webauthn"
5575
+ ]
5576
+ }
5577
+ ]
5578
+ },
5579
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
5580
+ },
5581
+ "remember_device_days": {
5582
+ "type": "integer",
5583
+ "minimum": 0,
5584
+ "maximum": 365,
5585
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
5586
+ }
5587
+ },
5588
+ "additionalProperties": false,
5589
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
5590
+ },
5591
+ "webauthn_rp_id": {
5592
+ "type": "string",
5593
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
5594
+ "nullable": true
5595
+ },
4839
5596
  "createdAt": {
4840
5597
  "type": "string",
4841
5598
  "description": "AuthAccount creation date"
@@ -5120,6 +5877,97 @@
5120
5877
  ],
5121
5878
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
5122
5879
  },
5880
+ "login_methods": {
5881
+ "type": "object",
5882
+ "properties": {
5883
+ "order": {
5884
+ "type": "array",
5885
+ "items": {
5886
+ "type": "string"
5887
+ },
5888
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
5889
+ },
5890
+ "passkey_login_enabled": {
5891
+ "type": "boolean",
5892
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
5893
+ },
5894
+ "identifier_first": {
5895
+ "type": "boolean",
5896
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
5897
+ },
5898
+ "remember_last_method": {
5899
+ "type": "boolean",
5900
+ "description": "Surface the method the returning user chose last time. Defaults to false."
5901
+ }
5902
+ },
5903
+ "additionalProperties": false,
5904
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
5905
+ },
5906
+ "mfa_policy": {
5907
+ "type": "object",
5908
+ "properties": {
5909
+ "mode": {
5910
+ "anyOf": [
5911
+ {
5912
+ "anyOf": [
5913
+ {
5914
+ "type": "string",
5915
+ "enum": [
5916
+ "off"
5917
+ ]
5918
+ },
5919
+ {
5920
+ "type": "string",
5921
+ "enum": [
5922
+ "optional"
5923
+ ]
5924
+ },
5925
+ {
5926
+ "type": "string",
5927
+ "enum": [
5928
+ "required"
5929
+ ]
5930
+ }
5931
+ ]
5932
+ }
5933
+ ],
5934
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
5935
+ },
5936
+ "allowed_factors": {
5937
+ "type": "array",
5938
+ "items": {
5939
+ "anyOf": [
5940
+ {
5941
+ "type": "string",
5942
+ "enum": [
5943
+ "totp"
5944
+ ]
5945
+ },
5946
+ {
5947
+ "type": "string",
5948
+ "enum": [
5949
+ "webauthn"
5950
+ ]
5951
+ }
5952
+ ]
5953
+ },
5954
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
5955
+ },
5956
+ "remember_device_days": {
5957
+ "type": "integer",
5958
+ "minimum": 0,
5959
+ "maximum": 365,
5960
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
5961
+ }
5962
+ },
5963
+ "additionalProperties": false,
5964
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
5965
+ },
5966
+ "webauthn_rp_id": {
5967
+ "type": "string",
5968
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
5969
+ "nullable": true
5970
+ },
5123
5971
  "createdAt": {
5124
5972
  "type": "string",
5125
5973
  "description": "AuthAccount creation date"
@@ -5201,6 +6049,110 @@
5201
6049
  "default": false
5202
6050
  }
5203
6051
  }
6052
+ },
6053
+ "login_methods": {
6054
+ "anyOf": [
6055
+ {
6056
+ "type": "object",
6057
+ "properties": {
6058
+ "order": {
6059
+ "type": "array",
6060
+ "items": {
6061
+ "type": "string"
6062
+ },
6063
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
6064
+ },
6065
+ "passkey_login_enabled": {
6066
+ "type": "boolean",
6067
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
6068
+ },
6069
+ "identifier_first": {
6070
+ "type": "boolean",
6071
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
6072
+ },
6073
+ "remember_last_method": {
6074
+ "type": "boolean",
6075
+ "description": "Surface the method the returning user chose last time. Defaults to false."
6076
+ }
6077
+ },
6078
+ "additionalProperties": false,
6079
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
6080
+ },
6081
+ {
6082
+ "type": "null"
6083
+ }
6084
+ ]
6085
+ },
6086
+ "mfa_policy": {
6087
+ "anyOf": [
6088
+ {
6089
+ "type": "object",
6090
+ "properties": {
6091
+ "mode": {
6092
+ "anyOf": [
6093
+ {
6094
+ "anyOf": [
6095
+ {
6096
+ "type": "string",
6097
+ "enum": [
6098
+ "off"
6099
+ ]
6100
+ },
6101
+ {
6102
+ "type": "string",
6103
+ "enum": [
6104
+ "optional"
6105
+ ]
6106
+ },
6107
+ {
6108
+ "type": "string",
6109
+ "enum": [
6110
+ "required"
6111
+ ]
6112
+ }
6113
+ ]
6114
+ }
6115
+ ],
6116
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
6117
+ },
6118
+ "allowed_factors": {
6119
+ "type": "array",
6120
+ "items": {
6121
+ "anyOf": [
6122
+ {
6123
+ "type": "string",
6124
+ "enum": [
6125
+ "totp"
6126
+ ]
6127
+ },
6128
+ {
6129
+ "type": "string",
6130
+ "enum": [
6131
+ "webauthn"
6132
+ ]
6133
+ }
6134
+ ]
6135
+ },
6136
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
6137
+ },
6138
+ "remember_device_days": {
6139
+ "type": "integer",
6140
+ "minimum": 0,
6141
+ "maximum": 365,
6142
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
6143
+ }
6144
+ },
6145
+ "additionalProperties": false,
6146
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
6147
+ },
6148
+ {
6149
+ "type": "null"
6150
+ }
6151
+ ]
6152
+ },
6153
+ "webauthn_rp_id": {
6154
+ "type": "string",
6155
+ "nullable": true
5204
6156
  }
5205
6157
  },
5206
6158
  "description": "AuthAccountUpdate",
@@ -5369,6 +6321,97 @@
5369
6321
  ],
5370
6322
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
5371
6323
  },
6324
+ "login_methods": {
6325
+ "type": "object",
6326
+ "properties": {
6327
+ "order": {
6328
+ "type": "array",
6329
+ "items": {
6330
+ "type": "string"
6331
+ },
6332
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
6333
+ },
6334
+ "passkey_login_enabled": {
6335
+ "type": "boolean",
6336
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
6337
+ },
6338
+ "identifier_first": {
6339
+ "type": "boolean",
6340
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
6341
+ },
6342
+ "remember_last_method": {
6343
+ "type": "boolean",
6344
+ "description": "Surface the method the returning user chose last time. Defaults to false."
6345
+ }
6346
+ },
6347
+ "additionalProperties": false,
6348
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
6349
+ },
6350
+ "mfa_policy": {
6351
+ "type": "object",
6352
+ "properties": {
6353
+ "mode": {
6354
+ "anyOf": [
6355
+ {
6356
+ "anyOf": [
6357
+ {
6358
+ "type": "string",
6359
+ "enum": [
6360
+ "off"
6361
+ ]
6362
+ },
6363
+ {
6364
+ "type": "string",
6365
+ "enum": [
6366
+ "optional"
6367
+ ]
6368
+ },
6369
+ {
6370
+ "type": "string",
6371
+ "enum": [
6372
+ "required"
6373
+ ]
6374
+ }
6375
+ ]
6376
+ }
6377
+ ],
6378
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
6379
+ },
6380
+ "allowed_factors": {
6381
+ "type": "array",
6382
+ "items": {
6383
+ "anyOf": [
6384
+ {
6385
+ "type": "string",
6386
+ "enum": [
6387
+ "totp"
6388
+ ]
6389
+ },
6390
+ {
6391
+ "type": "string",
6392
+ "enum": [
6393
+ "webauthn"
6394
+ ]
6395
+ }
6396
+ ]
6397
+ },
6398
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
6399
+ },
6400
+ "remember_device_days": {
6401
+ "type": "integer",
6402
+ "minimum": 0,
6403
+ "maximum": 365,
6404
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
6405
+ }
6406
+ },
6407
+ "additionalProperties": false,
6408
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
6409
+ },
6410
+ "webauthn_rp_id": {
6411
+ "type": "string",
6412
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
6413
+ "nullable": true
6414
+ },
5372
6415
  "createdAt": {
5373
6416
  "type": "string",
5374
6417
  "description": "AuthAccount creation date"
@@ -5572,8 +6615,99 @@
5572
6615
  ],
5573
6616
  "description": "Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).\n\n- `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.\n- `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.)."
5574
6617
  },
5575
- "createdAt": {
5576
- "type": "string",
6618
+ "login_methods": {
6619
+ "type": "object",
6620
+ "properties": {
6621
+ "order": {
6622
+ "type": "array",
6623
+ "items": {
6624
+ "type": "string"
6625
+ },
6626
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
6627
+ },
6628
+ "passkey_login_enabled": {
6629
+ "type": "boolean",
6630
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
6631
+ },
6632
+ "identifier_first": {
6633
+ "type": "boolean",
6634
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
6635
+ },
6636
+ "remember_last_method": {
6637
+ "type": "boolean",
6638
+ "description": "Surface the method the returning user chose last time. Defaults to false."
6639
+ }
6640
+ },
6641
+ "additionalProperties": false,
6642
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
6643
+ },
6644
+ "mfa_policy": {
6645
+ "type": "object",
6646
+ "properties": {
6647
+ "mode": {
6648
+ "anyOf": [
6649
+ {
6650
+ "anyOf": [
6651
+ {
6652
+ "type": "string",
6653
+ "enum": [
6654
+ "off"
6655
+ ]
6656
+ },
6657
+ {
6658
+ "type": "string",
6659
+ "enum": [
6660
+ "optional"
6661
+ ]
6662
+ },
6663
+ {
6664
+ "type": "string",
6665
+ "enum": [
6666
+ "required"
6667
+ ]
6668
+ }
6669
+ ]
6670
+ }
6671
+ ],
6672
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
6673
+ },
6674
+ "allowed_factors": {
6675
+ "type": "array",
6676
+ "items": {
6677
+ "anyOf": [
6678
+ {
6679
+ "type": "string",
6680
+ "enum": [
6681
+ "totp"
6682
+ ]
6683
+ },
6684
+ {
6685
+ "type": "string",
6686
+ "enum": [
6687
+ "webauthn"
6688
+ ]
6689
+ }
6690
+ ]
6691
+ },
6692
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
6693
+ },
6694
+ "remember_device_days": {
6695
+ "type": "integer",
6696
+ "minimum": 0,
6697
+ "maximum": 365,
6698
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
6699
+ }
6700
+ },
6701
+ "additionalProperties": false,
6702
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
6703
+ },
6704
+ "webauthn_rp_id": {
6705
+ "type": "string",
6706
+ "description": "WebAuthn Relying Party ID for this tenant's passkeys. Defaults to the account domain. Set it to a registrable suffix you own (e.g. `acme.com`) when the login screen is served from more than one host — the RP ID is frozen into every credential at registration, so changing it afterwards invalidates every passkey already enrolled.",
6707
+ "nullable": true
6708
+ },
6709
+ "createdAt": {
6710
+ "type": "string",
5577
6711
  "description": "AuthAccount creation date"
5578
6712
  },
5579
6713
  "updatedAt": {
@@ -7036,6 +8170,125 @@
7036
8170
  }
7037
8171
  }
7038
8172
  },
8173
+ "/login-options": {
8174
+ "get": {
8175
+ "operationId": "connection/loginOptions",
8176
+ "summary": "Resolve the login methods for a client",
8177
+ "tags": [
8178
+ "connection"
8179
+ ],
8180
+ "description": "Returns the ordered list of login methods the hosted login screen should offer for this client, already filtered by `connection.enabled` and `connection.enabled_clients`. `client_id` is the OAuth client_id; when omitted it falls back to the account's single client if it has exactly one, otherwise no client context is assumed and only unrestricted connections are returned.",
8181
+ "parameters": [
8182
+ {
8183
+ "schema": {
8184
+ "type": "string"
8185
+ },
8186
+ "in": "query",
8187
+ "name": "client_id",
8188
+ "required": false
8189
+ }
8190
+ ],
8191
+ "responses": {
8192
+ "200": {
8193
+ "description": "Default Response",
8194
+ "content": {
8195
+ "application/json": {
8196
+ "schema": {
8197
+ "type": "object",
8198
+ "required": [
8199
+ "account",
8200
+ "client",
8201
+ "identifier_first",
8202
+ "remember_last_method",
8203
+ "methods"
8204
+ ],
8205
+ "properties": {
8206
+ "account": {
8207
+ "type": "object",
8208
+ "required": [
8209
+ "id",
8210
+ "name",
8211
+ "logo_src",
8212
+ "icon_src"
8213
+ ],
8214
+ "properties": {
8215
+ "id": {
8216
+ "type": "string"
8217
+ },
8218
+ "name": {
8219
+ "type": "string"
8220
+ },
8221
+ "logo_src": {
8222
+ "anyOf": [
8223
+ {
8224
+ "type": "string"
8225
+ },
8226
+ {
8227
+ "type": "null"
8228
+ }
8229
+ ]
8230
+ },
8231
+ "icon_src": {
8232
+ "anyOf": [
8233
+ {
8234
+ "type": "string"
8235
+ },
8236
+ {
8237
+ "type": "null"
8238
+ }
8239
+ ]
8240
+ }
8241
+ }
8242
+ },
8243
+ "client": {
8244
+ "anyOf": [
8245
+ {
8246
+ "type": "object",
8247
+ "required": [
8248
+ "id",
8249
+ "client_id",
8250
+ "name"
8251
+ ],
8252
+ "properties": {
8253
+ "id": {
8254
+ "type": "string"
8255
+ },
8256
+ "client_id": {
8257
+ "type": "string"
8258
+ },
8259
+ "name": {
8260
+ "type": "string"
8261
+ }
8262
+ }
8263
+ },
8264
+ {
8265
+ "type": "null"
8266
+ }
8267
+ ],
8268
+ "description": "The client the methods were resolved for, or `null` when none could be determined (no `client_id` given and the account has zero or several clients)."
8269
+ },
8270
+ "identifier_first": {
8271
+ "type": "boolean"
8272
+ },
8273
+ "remember_last_method": {
8274
+ "type": "boolean"
8275
+ },
8276
+ "methods": {
8277
+ "type": "array",
8278
+ "items": {
8279
+ "$ref": "#/components/schemas/LoginOptionMethod"
8280
+ },
8281
+ "description": "Already filtered and ordered. Render them in this order; do not re-sort or re-filter client-side."
8282
+ }
8283
+ },
8284
+ "additionalProperties": false
8285
+ }
8286
+ }
8287
+ }
8288
+ }
8289
+ }
8290
+ }
8291
+ },
7039
8292
  "/client": {
7040
8293
  "get": {
7041
8294
  "operationId": "client/list",
@@ -7339,6 +8592,92 @@
7339
8592
  "frontchannel_logout_session_required": {
7340
8593
  "type": "boolean"
7341
8594
  },
8595
+ "login_methods": {
8596
+ "type": "object",
8597
+ "properties": {
8598
+ "order": {
8599
+ "type": "array",
8600
+ "items": {
8601
+ "type": "string"
8602
+ },
8603
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
8604
+ },
8605
+ "passkey_login_enabled": {
8606
+ "type": "boolean",
8607
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
8608
+ },
8609
+ "identifier_first": {
8610
+ "type": "boolean",
8611
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
8612
+ },
8613
+ "remember_last_method": {
8614
+ "type": "boolean",
8615
+ "description": "Surface the method the returning user chose last time. Defaults to false."
8616
+ }
8617
+ },
8618
+ "additionalProperties": false,
8619
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
8620
+ },
8621
+ "mfa_policy": {
8622
+ "type": "object",
8623
+ "properties": {
8624
+ "mode": {
8625
+ "anyOf": [
8626
+ {
8627
+ "anyOf": [
8628
+ {
8629
+ "type": "string",
8630
+ "enum": [
8631
+ "off"
8632
+ ]
8633
+ },
8634
+ {
8635
+ "type": "string",
8636
+ "enum": [
8637
+ "optional"
8638
+ ]
8639
+ },
8640
+ {
8641
+ "type": "string",
8642
+ "enum": [
8643
+ "required"
8644
+ ]
8645
+ }
8646
+ ]
8647
+ }
8648
+ ],
8649
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
8650
+ },
8651
+ "allowed_factors": {
8652
+ "type": "array",
8653
+ "items": {
8654
+ "anyOf": [
8655
+ {
8656
+ "type": "string",
8657
+ "enum": [
8658
+ "totp"
8659
+ ]
8660
+ },
8661
+ {
8662
+ "type": "string",
8663
+ "enum": [
8664
+ "webauthn"
8665
+ ]
8666
+ }
8667
+ ]
8668
+ },
8669
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
8670
+ },
8671
+ "remember_device_days": {
8672
+ "type": "integer",
8673
+ "minimum": 0,
8674
+ "maximum": 365,
8675
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
8676
+ }
8677
+ },
8678
+ "additionalProperties": false,
8679
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
8680
+ },
7342
8681
  "account": {
7343
8682
  "type": "string",
7344
8683
  "description": "Object is related with this account"
@@ -7533,6 +8872,92 @@
7533
8872
  "frontchannel_logout_session_required": {
7534
8873
  "type": "boolean"
7535
8874
  },
8875
+ "login_methods": {
8876
+ "type": "object",
8877
+ "properties": {
8878
+ "order": {
8879
+ "type": "array",
8880
+ "items": {
8881
+ "type": "string"
8882
+ },
8883
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
8884
+ },
8885
+ "passkey_login_enabled": {
8886
+ "type": "boolean",
8887
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
8888
+ },
8889
+ "identifier_first": {
8890
+ "type": "boolean",
8891
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
8892
+ },
8893
+ "remember_last_method": {
8894
+ "type": "boolean",
8895
+ "description": "Surface the method the returning user chose last time. Defaults to false."
8896
+ }
8897
+ },
8898
+ "additionalProperties": false,
8899
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
8900
+ },
8901
+ "mfa_policy": {
8902
+ "type": "object",
8903
+ "properties": {
8904
+ "mode": {
8905
+ "anyOf": [
8906
+ {
8907
+ "anyOf": [
8908
+ {
8909
+ "type": "string",
8910
+ "enum": [
8911
+ "off"
8912
+ ]
8913
+ },
8914
+ {
8915
+ "type": "string",
8916
+ "enum": [
8917
+ "optional"
8918
+ ]
8919
+ },
8920
+ {
8921
+ "type": "string",
8922
+ "enum": [
8923
+ "required"
8924
+ ]
8925
+ }
8926
+ ]
8927
+ }
8928
+ ],
8929
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
8930
+ },
8931
+ "allowed_factors": {
8932
+ "type": "array",
8933
+ "items": {
8934
+ "anyOf": [
8935
+ {
8936
+ "type": "string",
8937
+ "enum": [
8938
+ "totp"
8939
+ ]
8940
+ },
8941
+ {
8942
+ "type": "string",
8943
+ "enum": [
8944
+ "webauthn"
8945
+ ]
8946
+ }
8947
+ ]
8948
+ },
8949
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
8950
+ },
8951
+ "remember_device_days": {
8952
+ "type": "integer",
8953
+ "minimum": 0,
8954
+ "maximum": 365,
8955
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
8956
+ }
8957
+ },
8958
+ "additionalProperties": false,
8959
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
8960
+ },
7536
8961
  "account": {
7537
8962
  "type": "string",
7538
8963
  "description": "Object is related with this account"
@@ -7690,30 +9115,130 @@
7690
9115
  "frontchannel_logout_session_required": {
7691
9116
  "type": "boolean"
7692
9117
  },
7693
- "metadata": {
7694
- "type": "object",
7695
- "properties": {},
7696
- "additionalProperties": true,
7697
- "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
7698
- "default": {}
7699
- }
7700
- },
7701
- "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
7702
- "additionalProperties": false
7703
- }
7704
- }
7705
- },
7706
- "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added."
7707
- },
7708
- "parameters": [
7709
- {
7710
- "schema": {
7711
- "type": "string"
7712
- },
7713
- "in": "path",
7714
- "name": "client_id",
7715
- "required": true
7716
- }
9118
+ "login_methods": {
9119
+ "anyOf": [
9120
+ {
9121
+ "type": "object",
9122
+ "properties": {
9123
+ "order": {
9124
+ "type": "array",
9125
+ "items": {
9126
+ "type": "string"
9127
+ },
9128
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
9129
+ },
9130
+ "passkey_login_enabled": {
9131
+ "type": "boolean",
9132
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
9133
+ },
9134
+ "identifier_first": {
9135
+ "type": "boolean",
9136
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
9137
+ },
9138
+ "remember_last_method": {
9139
+ "type": "boolean",
9140
+ "description": "Surface the method the returning user chose last time. Defaults to false."
9141
+ }
9142
+ },
9143
+ "additionalProperties": false,
9144
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
9145
+ },
9146
+ {
9147
+ "type": "null"
9148
+ }
9149
+ ]
9150
+ },
9151
+ "mfa_policy": {
9152
+ "anyOf": [
9153
+ {
9154
+ "type": "object",
9155
+ "properties": {
9156
+ "mode": {
9157
+ "anyOf": [
9158
+ {
9159
+ "anyOf": [
9160
+ {
9161
+ "type": "string",
9162
+ "enum": [
9163
+ "off"
9164
+ ]
9165
+ },
9166
+ {
9167
+ "type": "string",
9168
+ "enum": [
9169
+ "optional"
9170
+ ]
9171
+ },
9172
+ {
9173
+ "type": "string",
9174
+ "enum": [
9175
+ "required"
9176
+ ]
9177
+ }
9178
+ ]
9179
+ }
9180
+ ],
9181
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
9182
+ },
9183
+ "allowed_factors": {
9184
+ "type": "array",
9185
+ "items": {
9186
+ "anyOf": [
9187
+ {
9188
+ "type": "string",
9189
+ "enum": [
9190
+ "totp"
9191
+ ]
9192
+ },
9193
+ {
9194
+ "type": "string",
9195
+ "enum": [
9196
+ "webauthn"
9197
+ ]
9198
+ }
9199
+ ]
9200
+ },
9201
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
9202
+ },
9203
+ "remember_device_days": {
9204
+ "type": "integer",
9205
+ "minimum": 0,
9206
+ "maximum": 365,
9207
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
9208
+ }
9209
+ },
9210
+ "additionalProperties": false,
9211
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
9212
+ },
9213
+ {
9214
+ "type": "null"
9215
+ }
9216
+ ]
9217
+ },
9218
+ "metadata": {
9219
+ "type": "object",
9220
+ "properties": {},
9221
+ "additionalProperties": true,
9222
+ "description": "Free-form client metadata. Replaces the whole object — send the full merged value, not a partial delta.",
9223
+ "default": {}
9224
+ }
9225
+ },
9226
+ "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added.",
9227
+ "additionalProperties": false
9228
+ }
9229
+ }
9230
+ },
9231
+ "description": "Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added."
9232
+ },
9233
+ "parameters": [
9234
+ {
9235
+ "schema": {
9236
+ "type": "string"
9237
+ },
9238
+ "in": "path",
9239
+ "name": "client_id",
9240
+ "required": true
9241
+ }
7717
9242
  ],
7718
9243
  "security": [
7719
9244
  {
@@ -7863,6 +9388,92 @@
7863
9388
  "frontchannel_logout_session_required": {
7864
9389
  "type": "boolean"
7865
9390
  },
9391
+ "login_methods": {
9392
+ "type": "object",
9393
+ "properties": {
9394
+ "order": {
9395
+ "type": "array",
9396
+ "items": {
9397
+ "type": "string"
9398
+ },
9399
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
9400
+ },
9401
+ "passkey_login_enabled": {
9402
+ "type": "boolean",
9403
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
9404
+ },
9405
+ "identifier_first": {
9406
+ "type": "boolean",
9407
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
9408
+ },
9409
+ "remember_last_method": {
9410
+ "type": "boolean",
9411
+ "description": "Surface the method the returning user chose last time. Defaults to false."
9412
+ }
9413
+ },
9414
+ "additionalProperties": false,
9415
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
9416
+ },
9417
+ "mfa_policy": {
9418
+ "type": "object",
9419
+ "properties": {
9420
+ "mode": {
9421
+ "anyOf": [
9422
+ {
9423
+ "anyOf": [
9424
+ {
9425
+ "type": "string",
9426
+ "enum": [
9427
+ "off"
9428
+ ]
9429
+ },
9430
+ {
9431
+ "type": "string",
9432
+ "enum": [
9433
+ "optional"
9434
+ ]
9435
+ },
9436
+ {
9437
+ "type": "string",
9438
+ "enum": [
9439
+ "required"
9440
+ ]
9441
+ }
9442
+ ]
9443
+ }
9444
+ ],
9445
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
9446
+ },
9447
+ "allowed_factors": {
9448
+ "type": "array",
9449
+ "items": {
9450
+ "anyOf": [
9451
+ {
9452
+ "type": "string",
9453
+ "enum": [
9454
+ "totp"
9455
+ ]
9456
+ },
9457
+ {
9458
+ "type": "string",
9459
+ "enum": [
9460
+ "webauthn"
9461
+ ]
9462
+ }
9463
+ ]
9464
+ },
9465
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
9466
+ },
9467
+ "remember_device_days": {
9468
+ "type": "integer",
9469
+ "minimum": 0,
9470
+ "maximum": 365,
9471
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
9472
+ }
9473
+ },
9474
+ "additionalProperties": false,
9475
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
9476
+ },
7866
9477
  "account": {
7867
9478
  "type": "string",
7868
9479
  "description": "Object is related with this account"
@@ -8055,6 +9666,92 @@
8055
9666
  "frontchannel_logout_session_required": {
8056
9667
  "type": "boolean"
8057
9668
  },
9669
+ "login_methods": {
9670
+ "type": "object",
9671
+ "properties": {
9672
+ "order": {
9673
+ "type": "array",
9674
+ "items": {
9675
+ "type": "string"
9676
+ },
9677
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
9678
+ },
9679
+ "passkey_login_enabled": {
9680
+ "type": "boolean",
9681
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
9682
+ },
9683
+ "identifier_first": {
9684
+ "type": "boolean",
9685
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
9686
+ },
9687
+ "remember_last_method": {
9688
+ "type": "boolean",
9689
+ "description": "Surface the method the returning user chose last time. Defaults to false."
9690
+ }
9691
+ },
9692
+ "additionalProperties": false,
9693
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
9694
+ },
9695
+ "mfa_policy": {
9696
+ "type": "object",
9697
+ "properties": {
9698
+ "mode": {
9699
+ "anyOf": [
9700
+ {
9701
+ "anyOf": [
9702
+ {
9703
+ "type": "string",
9704
+ "enum": [
9705
+ "off"
9706
+ ]
9707
+ },
9708
+ {
9709
+ "type": "string",
9710
+ "enum": [
9711
+ "optional"
9712
+ ]
9713
+ },
9714
+ {
9715
+ "type": "string",
9716
+ "enum": [
9717
+ "required"
9718
+ ]
9719
+ }
9720
+ ]
9721
+ }
9722
+ ],
9723
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
9724
+ },
9725
+ "allowed_factors": {
9726
+ "type": "array",
9727
+ "items": {
9728
+ "anyOf": [
9729
+ {
9730
+ "type": "string",
9731
+ "enum": [
9732
+ "totp"
9733
+ ]
9734
+ },
9735
+ {
9736
+ "type": "string",
9737
+ "enum": [
9738
+ "webauthn"
9739
+ ]
9740
+ }
9741
+ ]
9742
+ },
9743
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
9744
+ },
9745
+ "remember_device_days": {
9746
+ "type": "integer",
9747
+ "minimum": 0,
9748
+ "maximum": 365,
9749
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
9750
+ }
9751
+ },
9752
+ "additionalProperties": false,
9753
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
9754
+ },
8058
9755
  "account": {
8059
9756
  "type": "string",
8060
9757
  "description": "Object is related with this account"
@@ -8249,6 +9946,92 @@
8249
9946
  "frontchannel_logout_session_required": {
8250
9947
  "type": "boolean"
8251
9948
  },
9949
+ "login_methods": {
9950
+ "type": "object",
9951
+ "properties": {
9952
+ "order": {
9953
+ "type": "array",
9954
+ "items": {
9955
+ "type": "string"
9956
+ },
9957
+ "description": "Order in which the hosted login screen renders the available methods. Entries are Connection resource ids (`connection_xxx`) or the literal `passkey`. Methods not listed keep the built-in order (passwordless, database, social) after the listed ones; ids that no longer resolve are ignored. Listing an `oidc` connection here is also the only way to surface it on the login screen — see resolveLoginMethods()."
9958
+ },
9959
+ "passkey_login_enabled": {
9960
+ "type": "boolean",
9961
+ "description": "Offer passkey (WebAuthn) as a primary login method on the hosted login screen. Defaults to false."
9962
+ },
9963
+ "identifier_first": {
9964
+ "type": "boolean",
9965
+ "description": "Ask for the email first and only then reveal the methods that apply to it, instead of showing every method up front. Defaults to false."
9966
+ },
9967
+ "remember_last_method": {
9968
+ "type": "boolean",
9969
+ "description": "Surface the method the returning user chose last time. Defaults to false."
9970
+ }
9971
+ },
9972
+ "additionalProperties": false,
9973
+ "description": "Which login methods the hosted login screen offers and in what order. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so a client can flip one flag without restating the rest. Absent everywhere = built-in defaults."
9974
+ },
9975
+ "mfa_policy": {
9976
+ "type": "object",
9977
+ "properties": {
9978
+ "mode": {
9979
+ "anyOf": [
9980
+ {
9981
+ "anyOf": [
9982
+ {
9983
+ "type": "string",
9984
+ "enum": [
9985
+ "off"
9986
+ ]
9987
+ },
9988
+ {
9989
+ "type": "string",
9990
+ "enum": [
9991
+ "optional"
9992
+ ]
9993
+ },
9994
+ {
9995
+ "type": "string",
9996
+ "enum": [
9997
+ "required"
9998
+ ]
9999
+ }
10000
+ ]
10001
+ }
10002
+ ],
10003
+ "description": "`off` (default) never challenges. `optional` challenges a user who has enrolled a factor, and lets everyone else in. `required` challenges everyone and sends users with no factor through enrolment during login — it never locks anyone out in place."
10004
+ },
10005
+ "allowed_factors": {
10006
+ "type": "array",
10007
+ "items": {
10008
+ "anyOf": [
10009
+ {
10010
+ "type": "string",
10011
+ "enum": [
10012
+ "totp"
10013
+ ]
10014
+ },
10015
+ {
10016
+ "type": "string",
10017
+ "enum": [
10018
+ "webauthn"
10019
+ ]
10020
+ }
10021
+ ]
10022
+ },
10023
+ "description": "Which kinds of second factor satisfy the policy. Empty or unset means all of them. A user whose only factor is of a kind not listed here is treated as having none."
10024
+ },
10025
+ "remember_device_days": {
10026
+ "type": "integer",
10027
+ "minimum": 0,
10028
+ "maximum": 365,
10029
+ "description": "How long a browser that already passed a challenge may skip the next one. 0 (default) challenges every time."
10030
+ }
10031
+ },
10032
+ "additionalProperties": false,
10033
+ "description": "Second-factor policy. Set on the Account as the tenant default; the same object on a Client overrides it **field by field**, so one app can require MFA without changing the rest."
10034
+ },
8252
10035
  "account": {
8253
10036
  "type": "string",
8254
10037
  "description": "Object is related with this account"
@@ -10311,44 +12094,127 @@
10311
12094
  }
10312
12095
  }
10313
12096
  },
10314
- "/identity": {
12097
+ "/user/{user_id}/factors": {
10315
12098
  "get": {
10316
- "operationId": "identity/list",
10317
- "summary": "List Identitys",
12099
+ "operationId": "user/factors",
12100
+ "summary": "List a user's second factors",
10318
12101
  "tags": [
10319
- "identity"
12102
+ "user"
10320
12103
  ],
10321
- "description": "List Identitys",
12104
+ "description": "Management view of the security methods a user has enrolled. Carries no secret material — TOTP seeds and recovery-code hashes are redacted by the store, so this endpoint cannot be used to impersonate the user.",
10322
12105
  "parameters": [
10323
12106
  {
10324
12107
  "schema": {
10325
- "type": "number",
10326
- "minimum": 1,
10327
- "maximum": 200
12108
+ "type": "string"
10328
12109
  },
10329
- "in": "query",
10330
- "name": "pageSize",
10331
- "required": false,
10332
- "description": "Number of items per page (max 200)"
10333
- },
12110
+ "in": "path",
12111
+ "name": "user_id",
12112
+ "required": true
12113
+ }
12114
+ ],
12115
+ "responses": {
12116
+ "200": {
12117
+ "description": "Default Response",
12118
+ "content": {
12119
+ "application/json": {
12120
+ "schema": {
12121
+ "type": "array",
12122
+ "items": {
12123
+ "$ref": "#/components/schemas/AdminFactor"
12124
+ }
12125
+ }
12126
+ }
12127
+ }
12128
+ }
12129
+ }
12130
+ }
12131
+ },
12132
+ "/user/{user_id}/factors/{factor_id}": {
12133
+ "delete": {
12134
+ "operationId": "user/deleteFactor",
12135
+ "summary": "Remove one of a user's second factors",
12136
+ "tags": [
12137
+ "user"
12138
+ ],
12139
+ "description": "The support path out of a lockout: with the factor gone, a `required` policy sends the user through enrolment on their next login instead of refusing it.",
12140
+ "parameters": [
10334
12141
  {
10335
12142
  "schema": {
10336
12143
  "type": "string"
10337
12144
  },
10338
- "in": "query",
10339
- "name": "cursor",
10340
- "required": false,
10341
- "description": "Cursor for next page"
12145
+ "in": "path",
12146
+ "name": "user_id",
12147
+ "required": true
10342
12148
  },
10343
12149
  {
10344
12150
  "schema": {
10345
12151
  "type": "string"
10346
12152
  },
10347
- "in": "query",
10348
- "name": "next",
10349
- "required": false,
10350
- "description": "Cursor returned by the previous page"
10351
- },
12153
+ "in": "path",
12154
+ "name": "factor_id",
12155
+ "required": true
12156
+ }
12157
+ ],
12158
+ "responses": {
12159
+ "200": {
12160
+ "description": "Default Response",
12161
+ "content": {
12162
+ "application/json": {
12163
+ "schema": {
12164
+ "type": "object",
12165
+ "required": [
12166
+ "deleted"
12167
+ ],
12168
+ "properties": {
12169
+ "deleted": {
12170
+ "type": "boolean"
12171
+ }
12172
+ }
12173
+ }
12174
+ }
12175
+ }
12176
+ }
12177
+ }
12178
+ }
12179
+ },
12180
+ "/identity": {
12181
+ "get": {
12182
+ "operationId": "identity/list",
12183
+ "summary": "List Identitys",
12184
+ "tags": [
12185
+ "identity"
12186
+ ],
12187
+ "description": "List Identitys",
12188
+ "parameters": [
12189
+ {
12190
+ "schema": {
12191
+ "type": "number",
12192
+ "minimum": 1,
12193
+ "maximum": 200
12194
+ },
12195
+ "in": "query",
12196
+ "name": "pageSize",
12197
+ "required": false,
12198
+ "description": "Number of items per page (max 200)"
12199
+ },
12200
+ {
12201
+ "schema": {
12202
+ "type": "string"
12203
+ },
12204
+ "in": "query",
12205
+ "name": "cursor",
12206
+ "required": false,
12207
+ "description": "Cursor for next page"
12208
+ },
12209
+ {
12210
+ "schema": {
12211
+ "type": "string"
12212
+ },
12213
+ "in": "query",
12214
+ "name": "next",
12215
+ "required": false,
12216
+ "description": "Cursor returned by the previous page"
12217
+ },
10352
12218
  {
10353
12219
  "schema": {
10354
12220
  "type": "string"
@@ -18239,12 +20105,546 @@
18239
20105
  "type": "string",
18240
20106
  "description": "Customdomain creation date"
18241
20107
  },
18242
- "updatedAt": {
18243
- "type": "string",
18244
- "description": "Customdomain updated date"
20108
+ "updatedAt": {
20109
+ "type": "string",
20110
+ "description": "Customdomain updated date"
20111
+ }
20112
+ },
20113
+ "description": "Customdomain"
20114
+ }
20115
+ }
20116
+ }
20117
+ }
20118
+ }
20119
+ }
20120
+ },
20121
+ "/passwordless/verify_redirect": {
20122
+ "get": {
20123
+ "operationId": "passwordless/verify_redirect",
20124
+ "summary": "Receive a passwordless token via email link and convert it to a valid session",
20125
+ "tags": [
20126
+ "passwordless"
20127
+ ],
20128
+ "description": "Receive a passwordless token and convert it to a valid session",
20129
+ "parameters": [
20130
+ {
20131
+ "schema": {
20132
+ "type": "string"
20133
+ },
20134
+ "in": "query",
20135
+ "name": "token",
20136
+ "required": true
20137
+ }
20138
+ ],
20139
+ "responses": {
20140
+ "200": {
20141
+ "description": "Default Response"
20142
+ }
20143
+ }
20144
+ }
20145
+ },
20146
+ "/passwordless/verify_code": {
20147
+ "post": {
20148
+ "operationId": "passwordless/verifyCode",
20149
+ "summary": "Verify a passwordless code and establish a session",
20150
+ "tags": [
20151
+ "passwordless"
20152
+ ],
20153
+ "description": "Verifies an emailed passwordless code and establishes the browser `faable_sess` session, returning where to send the user next. Called by the first-party hosted login UI; SPAs on other origins use the `passwordless/otp` grant at `/oauth/token` instead, which returns tokens and no cookie.",
20154
+ "requestBody": {
20155
+ "required": true,
20156
+ "content": {
20157
+ "application/json": {
20158
+ "schema": {
20159
+ "type": "object",
20160
+ "required": [
20161
+ "client_id",
20162
+ "email",
20163
+ "otp"
20164
+ ],
20165
+ "properties": {
20166
+ "client_id": {
20167
+ "type": "string"
20168
+ },
20169
+ "email": {
20170
+ "type": "string"
20171
+ },
20172
+ "otp": {
20173
+ "type": "string"
20174
+ },
20175
+ "redirect_to": {
20176
+ "type": "string",
20177
+ "description": "Same-origin path to return the user to after authentication, instead of the OAuth client redirect. Used by first-party interactive flows (e.g. device-code confirm). Non same-origin values are ignored."
20178
+ }
20179
+ }
20180
+ }
20181
+ }
20182
+ }
20183
+ },
20184
+ "responses": {
20185
+ "200": {
20186
+ "description": "Default Response",
20187
+ "content": {
20188
+ "application/json": {
20189
+ "schema": {
20190
+ "type": "object",
20191
+ "required": [
20192
+ "redirect_url"
20193
+ ],
20194
+ "properties": {
20195
+ "redirect_url": {
20196
+ "type": "string"
20197
+ }
20198
+ }
20199
+ }
20200
+ }
20201
+ }
20202
+ }
20203
+ }
20204
+ }
20205
+ },
20206
+ "/passwordless/start": {
20207
+ "post": {
20208
+ "operationId": "passwordless/start",
20209
+ "summary": "Start Passwordless authentication flow",
20210
+ "tags": [
20211
+ "passwordless"
20212
+ ],
20213
+ "description": "Start Passwordless authentication flow",
20214
+ "requestBody": {
20215
+ "required": true,
20216
+ "content": {
20217
+ "application/json": {
20218
+ "schema": {
20219
+ "type": "object",
20220
+ "required": [
20221
+ "client_id",
20222
+ "email",
20223
+ "send"
20224
+ ],
20225
+ "properties": {
20226
+ "client_id": {
20227
+ "type": "string"
20228
+ },
20229
+ "email": {
20230
+ "type": "string"
20231
+ },
20232
+ "send": {
20233
+ "type": "string",
20234
+ "default": "link"
20235
+ },
20236
+ "connection_id": {
20237
+ "type": "string"
20238
+ },
20239
+ "auth_params": {
20240
+ "type": "object",
20241
+ "additionalProperties": {
20242
+ "type": "string"
20243
+ }
20244
+ }
20245
+ }
20246
+ }
20247
+ }
20248
+ }
20249
+ },
20250
+ "responses": {
20251
+ "200": {
20252
+ "description": "Default Response"
20253
+ }
20254
+ }
20255
+ }
20256
+ },
20257
+ "/mfa/verify": {
20258
+ "post": {
20259
+ "summary": "Answer an MFA challenge with a TOTP code",
20260
+ "tags": [
20261
+ "mfa"
20262
+ ],
20263
+ "description": "Verifies a time-based code against the factors enrolled by the user the challenge belongs to, and resumes the parked login. The state is consumed only on success, so a mistyped code does not destroy the flow.",
20264
+ "requestBody": {
20265
+ "required": true,
20266
+ "content": {
20267
+ "application/json": {
20268
+ "schema": {
20269
+ "type": "object",
20270
+ "required": [
20271
+ "state",
20272
+ "code"
20273
+ ],
20274
+ "properties": {
20275
+ "state": {
20276
+ "type": "string"
20277
+ },
20278
+ "code": {
20279
+ "type": "string"
20280
+ }
20281
+ }
20282
+ }
20283
+ }
20284
+ }
20285
+ },
20286
+ "responses": {
20287
+ "200": {
20288
+ "description": "Default Response",
20289
+ "content": {
20290
+ "application/json": {
20291
+ "schema": {
20292
+ "type": "object",
20293
+ "required": [
20294
+ "redirect_url"
20295
+ ],
20296
+ "properties": {
20297
+ "redirect_url": {
20298
+ "type": "string"
20299
+ }
20300
+ }
20301
+ }
20302
+ }
20303
+ }
20304
+ }
20305
+ }
20306
+ }
20307
+ },
20308
+ "/mfa/recovery": {
20309
+ "post": {
20310
+ "summary": "Answer an MFA challenge with a recovery code",
20311
+ "tags": [
20312
+ "mfa"
20313
+ ],
20314
+ "description": "Consumes one of the one-time recovery codes issued when the user enrolled their first factor.",
20315
+ "requestBody": {
20316
+ "required": true,
20317
+ "content": {
20318
+ "application/json": {
20319
+ "schema": {
20320
+ "type": "object",
20321
+ "required": [
20322
+ "state",
20323
+ "code"
20324
+ ],
20325
+ "properties": {
20326
+ "state": {
20327
+ "type": "string"
20328
+ },
20329
+ "code": {
20330
+ "type": "string"
20331
+ }
20332
+ }
20333
+ }
20334
+ }
20335
+ }
20336
+ },
20337
+ "responses": {
20338
+ "200": {
20339
+ "description": "Default Response",
20340
+ "content": {
20341
+ "application/json": {
20342
+ "schema": {
20343
+ "type": "object",
20344
+ "required": [
20345
+ "redirect_url"
20346
+ ],
20347
+ "properties": {
20348
+ "redirect_url": {
20349
+ "type": "string"
20350
+ }
20351
+ }
20352
+ }
20353
+ }
20354
+ }
20355
+ }
20356
+ }
20357
+ }
20358
+ },
20359
+ "/me/factors": {
20360
+ "get": {
20361
+ "summary": "List my second factors",
20362
+ "tags": [
20363
+ "mfa"
20364
+ ],
20365
+ "description": "The security methods enrolled by the current session's user. Never returns secret material: TOTP seeds and recovery-code hashes are redacted by the store.",
20366
+ "responses": {
20367
+ "200": {
20368
+ "description": "Default Response",
20369
+ "content": {
20370
+ "application/json": {
20371
+ "schema": {
20372
+ "type": "array",
20373
+ "items": {
20374
+ "$ref": "#/components/schemas/FactorSummary"
20375
+ }
20376
+ }
20377
+ }
20378
+ }
20379
+ }
20380
+ }
20381
+ }
20382
+ },
20383
+ "/me/factors/totp": {
20384
+ "post": {
20385
+ "summary": "Start enrolling an authenticator app",
20386
+ "tags": [
20387
+ "mfa"
20388
+ ],
20389
+ "description": "Creates an UNCONFIRMED TOTP factor and returns its `otpauth://` URI and secret — the only time either is ever readable. The factor does not satisfy any policy until `POST /me/factors/:id/verify` proves the user can produce a code from it.",
20390
+ "requestBody": {
20391
+ "required": true,
20392
+ "content": {
20393
+ "application/json": {
20394
+ "schema": {
20395
+ "type": "object",
20396
+ "properties": {
20397
+ "name": {
20398
+ "type": "string",
20399
+ "maxLength": 100
20400
+ },
20401
+ "state": {
20402
+ "type": "string"
20403
+ }
20404
+ }
20405
+ }
20406
+ }
20407
+ }
20408
+ },
20409
+ "responses": {
20410
+ "200": {
20411
+ "description": "Default Response",
20412
+ "content": {
20413
+ "application/json": {
20414
+ "schema": {
20415
+ "type": "object",
20416
+ "required": [
20417
+ "id",
20418
+ "secret",
20419
+ "otpauth_uri"
20420
+ ],
20421
+ "properties": {
20422
+ "id": {
20423
+ "type": "string"
20424
+ },
20425
+ "secret": {
20426
+ "type": "string"
20427
+ },
20428
+ "otpauth_uri": {
20429
+ "type": "string"
20430
+ }
20431
+ }
20432
+ }
20433
+ }
20434
+ }
20435
+ }
20436
+ }
20437
+ }
20438
+ },
20439
+ "/me/factors/{factor_id}/verify": {
20440
+ "post": {
20441
+ "summary": "Confirm an enrolment",
20442
+ "tags": [
20443
+ "mfa"
20444
+ ],
20445
+ "description": "Proves the user can produce a code from the seed, which is what makes the factor count. Confirming the first factor also mints the recovery codes — returned once and never again.",
20446
+ "requestBody": {
20447
+ "required": true,
20448
+ "content": {
20449
+ "application/json": {
20450
+ "schema": {
20451
+ "type": "object",
20452
+ "required": [
20453
+ "code"
20454
+ ],
20455
+ "properties": {
20456
+ "code": {
20457
+ "type": "string"
20458
+ },
20459
+ "state": {
20460
+ "type": "string"
20461
+ }
20462
+ }
20463
+ }
20464
+ }
20465
+ }
20466
+ },
20467
+ "parameters": [
20468
+ {
20469
+ "schema": {
20470
+ "type": "string"
20471
+ },
20472
+ "in": "path",
20473
+ "name": "factor_id",
20474
+ "required": true
20475
+ }
20476
+ ],
20477
+ "responses": {
20478
+ "200": {
20479
+ "description": "Default Response",
20480
+ "content": {
20481
+ "application/json": {
20482
+ "schema": {
20483
+ "type": "object",
20484
+ "required": [
20485
+ "id",
20486
+ "confirmed_at"
20487
+ ],
20488
+ "properties": {
20489
+ "id": {
20490
+ "type": "string"
20491
+ },
20492
+ "confirmed_at": {
20493
+ "type": "string"
20494
+ },
20495
+ "recovery_codes": {
20496
+ "type": "array",
20497
+ "items": {
20498
+ "type": "string"
20499
+ }
20500
+ },
20501
+ "redirect_url": {
20502
+ "type": "string"
20503
+ }
20504
+ }
20505
+ }
20506
+ }
20507
+ }
20508
+ }
20509
+ }
20510
+ }
20511
+ },
20512
+ "/me/factors/{factor_id}": {
20513
+ "delete": {
20514
+ "summary": "Remove one of my second factors",
20515
+ "tags": [
20516
+ "mfa"
20517
+ ],
20518
+ "parameters": [
20519
+ {
20520
+ "schema": {
20521
+ "type": "string"
20522
+ },
20523
+ "in": "path",
20524
+ "name": "factor_id",
20525
+ "required": true
20526
+ }
20527
+ ],
20528
+ "responses": {
20529
+ "200": {
20530
+ "description": "Default Response",
20531
+ "content": {
20532
+ "application/json": {
20533
+ "schema": {
20534
+ "type": "object",
20535
+ "required": [
20536
+ "deleted"
20537
+ ],
20538
+ "properties": {
20539
+ "deleted": {
20540
+ "type": "boolean"
20541
+ }
20542
+ }
20543
+ }
20544
+ }
20545
+ }
20546
+ }
20547
+ }
20548
+ }
20549
+ },
20550
+ "/me/passkeys/options": {
20551
+ "post": {
20552
+ "summary": "Start registering a passkey",
20553
+ "tags": [
20554
+ "mfa"
20555
+ ],
20556
+ "description": "Returns the WebAuthn creation options for `navigator.credentials.create()`. Existing credentials are excluded so the authenticator refuses to enrol the same key twice. Pass the `state` of a forced enrolment so the guard knows this is the way through, not a bypass.",
20557
+ "requestBody": {
20558
+ "required": true,
20559
+ "content": {
20560
+ "application/json": {
20561
+ "schema": {
20562
+ "type": "object",
20563
+ "properties": {
20564
+ "state": {
20565
+ "type": "string"
20566
+ }
20567
+ }
20568
+ }
20569
+ }
20570
+ }
20571
+ },
20572
+ "responses": {
20573
+ "200": {
20574
+ "description": "Default Response",
20575
+ "content": {
20576
+ "application/json": {
20577
+ "schema": {
20578
+ "type": "object",
20579
+ "required": [
20580
+ "ceremony_id",
20581
+ "options"
20582
+ ],
20583
+ "properties": {
20584
+ "ceremony_id": {
20585
+ "type": "string"
20586
+ },
20587
+ "options": {}
20588
+ }
20589
+ }
20590
+ }
20591
+ }
20592
+ }
20593
+ }
20594
+ }
20595
+ },
20596
+ "/me/passkeys": {
20597
+ "post": {
20598
+ "summary": "Finish registering a passkey",
20599
+ "tags": [
20600
+ "mfa"
20601
+ ],
20602
+ "description": "Verifies the attestation and stores the credential as a confirmed second factor. Pass the `state` of a pending challenge to also resume the login it parked.",
20603
+ "requestBody": {
20604
+ "required": true,
20605
+ "content": {
20606
+ "application/json": {
20607
+ "schema": {
20608
+ "type": "object",
20609
+ "required": [
20610
+ "ceremony_id",
20611
+ "credential"
20612
+ ],
20613
+ "properties": {
20614
+ "ceremony_id": {
20615
+ "type": "string"
20616
+ },
20617
+ "credential": {},
20618
+ "name": {
20619
+ "type": "string",
20620
+ "maxLength": 100
20621
+ },
20622
+ "state": {
20623
+ "type": "string"
20624
+ }
20625
+ }
20626
+ }
20627
+ }
20628
+ }
20629
+ },
20630
+ "responses": {
20631
+ "200": {
20632
+ "description": "Default Response",
20633
+ "content": {
20634
+ "application/json": {
20635
+ "schema": {
20636
+ "type": "object",
20637
+ "required": [
20638
+ "id"
20639
+ ],
20640
+ "properties": {
20641
+ "id": {
20642
+ "type": "string"
20643
+ },
20644
+ "redirect_url": {
20645
+ "type": "string"
18245
20646
  }
18246
- },
18247
- "description": "Customdomain"
20647
+ }
18248
20648
  }
18249
20649
  }
18250
20650
  }
@@ -18252,39 +20652,60 @@
18252
20652
  }
18253
20653
  }
18254
20654
  },
18255
- "/passwordless/verify_redirect": {
18256
- "get": {
18257
- "operationId": "passwordless/verify_redirect",
18258
- "summary": "Receive a passwordless token via email link and convert it to a valid session",
20655
+ "/mfa/webauthn/options": {
20656
+ "post": {
20657
+ "summary": "Start answering a challenge with a passkey",
18259
20658
  "tags": [
18260
- "passwordless"
20659
+ "mfa"
18261
20660
  ],
18262
- "description": "Receive a passwordless token and convert it to a valid session",
18263
- "parameters": [
18264
- {
18265
- "schema": {
18266
- "type": "string"
18267
- },
18268
- "in": "query",
18269
- "name": "token",
18270
- "required": true
20661
+ "requestBody": {
20662
+ "required": true,
20663
+ "content": {
20664
+ "application/json": {
20665
+ "schema": {
20666
+ "type": "object",
20667
+ "required": [
20668
+ "state"
20669
+ ],
20670
+ "properties": {
20671
+ "state": {
20672
+ "type": "string"
20673
+ }
20674
+ }
20675
+ }
20676
+ }
18271
20677
  }
18272
- ],
20678
+ },
18273
20679
  "responses": {
18274
20680
  "200": {
18275
- "description": "Default Response"
20681
+ "description": "Default Response",
20682
+ "content": {
20683
+ "application/json": {
20684
+ "schema": {
20685
+ "type": "object",
20686
+ "required": [
20687
+ "ceremony_id",
20688
+ "options"
20689
+ ],
20690
+ "properties": {
20691
+ "ceremony_id": {
20692
+ "type": "string"
20693
+ },
20694
+ "options": {}
20695
+ }
20696
+ }
20697
+ }
20698
+ }
18276
20699
  }
18277
20700
  }
18278
20701
  }
18279
20702
  },
18280
- "/passwordless/verify_code": {
20703
+ "/mfa/webauthn/verify": {
18281
20704
  "post": {
18282
- "operationId": "passwordless/verifyCode",
18283
- "summary": "Verify a passwordless code and establish a session",
20705
+ "summary": "Answer a challenge with a passkey",
18284
20706
  "tags": [
18285
- "passwordless"
20707
+ "mfa"
18286
20708
  ],
18287
- "description": "Verifies an emailed passwordless code and establishes the browser `faable_sess` session, returning where to send the user next. Called by the first-party hosted login UI; SPAs on other origins use the `passwordless/otp` grant at `/oauth/token` instead, which returns tokens and no cookie.",
18288
20709
  "requestBody": {
18289
20710
  "required": true,
18290
20711
  "content": {
@@ -18292,23 +20713,20 @@
18292
20713
  "schema": {
18293
20714
  "type": "object",
18294
20715
  "required": [
18295
- "client_id",
18296
- "email",
18297
- "otp"
20716
+ "ceremony_id",
20717
+ "credential"
18298
20718
  ],
18299
20719
  "properties": {
18300
- "client_id": {
20720
+ "ceremony_id": {
18301
20721
  "type": "string"
18302
20722
  },
18303
- "email": {
18304
- "type": "string"
20723
+ "credential": {},
20724
+ "name": {
20725
+ "type": "string",
20726
+ "maxLength": 100
18305
20727
  },
18306
- "otp": {
20728
+ "state": {
18307
20729
  "type": "string"
18308
- },
18309
- "redirect_to": {
18310
- "type": "string",
18311
- "description": "Same-origin path to return the user to after authentication, instead of the OAuth client redirect. Used by first-party interactive flows (e.g. device-code confirm). Non same-origin values are ignored."
18312
20730
  }
18313
20731
  }
18314
20732
  }
@@ -18337,14 +20755,13 @@
18337
20755
  }
18338
20756
  }
18339
20757
  },
18340
- "/passwordless/start": {
20758
+ "/passkey/login/options": {
18341
20759
  "post": {
18342
- "operationId": "passwordless/start",
18343
- "summary": "Start Passwordless authentication flow",
20760
+ "summary": "Start a passwordless passkey login",
18344
20761
  "tags": [
18345
- "passwordless"
20762
+ "mfa"
18346
20763
  ],
18347
- "description": "Start Passwordless authentication flow",
20764
+ "description": "Returns authentication options with an EMPTY allowCredentials, so the browser offers whichever discoverable passkey it holds for this Relying Party — the usernameless flow behind conditional autofill.",
18348
20765
  "requestBody": {
18349
20766
  "required": true,
18350
20767
  "content": {
@@ -18352,29 +20769,75 @@
18352
20769
  "schema": {
18353
20770
  "type": "object",
18354
20771
  "required": [
18355
- "client_id",
18356
- "email",
18357
- "send"
20772
+ "client_id"
18358
20773
  ],
18359
20774
  "properties": {
18360
20775
  "client_id": {
18361
20776
  "type": "string"
18362
20777
  },
18363
- "email": {
20778
+ "redirect_to": {
20779
+ "type": "string"
20780
+ }
20781
+ }
20782
+ }
20783
+ }
20784
+ }
20785
+ },
20786
+ "responses": {
20787
+ "200": {
20788
+ "description": "Default Response",
20789
+ "content": {
20790
+ "application/json": {
20791
+ "schema": {
20792
+ "type": "object",
20793
+ "required": [
20794
+ "ceremony_id",
20795
+ "options"
20796
+ ],
20797
+ "properties": {
20798
+ "ceremony_id": {
20799
+ "type": "string"
20800
+ },
20801
+ "options": {}
20802
+ }
20803
+ }
20804
+ }
20805
+ }
20806
+ }
20807
+ }
20808
+ }
20809
+ },
20810
+ "/passkey/login/verify": {
20811
+ "post": {
20812
+ "summary": "Finish a passwordless passkey login",
20813
+ "tags": [
20814
+ "mfa"
20815
+ ],
20816
+ "description": "Verifies the assertion, establishes the session and answers with where to send the browser. A passkey that verified the user (biometric or PIN) is already two factors, so no second-factor challenge follows.",
20817
+ "requestBody": {
20818
+ "required": true,
20819
+ "content": {
20820
+ "application/json": {
20821
+ "schema": {
20822
+ "type": "object",
20823
+ "required": [
20824
+ "ceremony_id",
20825
+ "credential",
20826
+ "client_id"
20827
+ ],
20828
+ "properties": {
20829
+ "ceremony_id": {
18364
20830
  "type": "string"
18365
20831
  },
18366
- "send": {
18367
- "type": "string",
18368
- "default": "link"
20832
+ "credential": {},
20833
+ "client_id": {
20834
+ "type": "string"
18369
20835
  },
18370
- "connection_id": {
20836
+ "redirect_to": {
18371
20837
  "type": "string"
18372
20838
  },
18373
- "auth_params": {
18374
- "type": "object",
18375
- "additionalProperties": {
18376
- "type": "string"
18377
- }
20839
+ "state": {
20840
+ "type": "string"
18378
20841
  }
18379
20842
  }
18380
20843
  }
@@ -18383,7 +20846,22 @@
18383
20846
  },
18384
20847
  "responses": {
18385
20848
  "200": {
18386
- "description": "Default Response"
20849
+ "description": "Default Response",
20850
+ "content": {
20851
+ "application/json": {
20852
+ "schema": {
20853
+ "type": "object",
20854
+ "required": [
20855
+ "redirect_url"
20856
+ ],
20857
+ "properties": {
20858
+ "redirect_url": {
20859
+ "type": "string"
20860
+ }
20861
+ }
20862
+ }
20863
+ }
20864
+ }
18387
20865
  }
18388
20866
  }
18389
20867
  }
@@ -19060,6 +21538,18 @@
19060
21538
  "password"
19061
21539
  ]
19062
21540
  },
21541
+ {
21542
+ "type": "string",
21543
+ "enum": [
21544
+ "http://auth0.com/oauth/grant-type/mfa-otp"
21545
+ ]
21546
+ },
21547
+ {
21548
+ "type": "string",
21549
+ "enum": [
21550
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
21551
+ ]
21552
+ },
19063
21553
  {
19064
21554
  "type": "string",
19065
21555
  "enum": [
@@ -19149,6 +21639,24 @@
19149
21639
  "name": "refresh_token",
19150
21640
  "required": false
19151
21641
  },
21642
+ {
21643
+ "schema": {
21644
+ "type": "string"
21645
+ },
21646
+ "in": "query",
21647
+ "name": "mfa_token",
21648
+ "required": false,
21649
+ "description": "Opaque token returned with a `403 mfa_required` response. Present it here with `grant_type=http://auth0.com/oauth/grant-type/mfa-otp` (or `…/mfa-recovery-code`) and the code, to finish a grant a second-factor policy interrupted."
21650
+ },
21651
+ {
21652
+ "schema": {
21653
+ "type": "string"
21654
+ },
21655
+ "in": "query",
21656
+ "name": "recovery_code",
21657
+ "required": false,
21658
+ "description": "One of the user's one-time recovery codes, for `grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code`."
21659
+ },
19152
21660
  {
19153
21661
  "schema": {
19154
21662
  "type": "string"
@@ -19271,6 +21779,18 @@
19271
21779
  "password"
19272
21780
  ]
19273
21781
  },
21782
+ {
21783
+ "type": "string",
21784
+ "enum": [
21785
+ "http://auth0.com/oauth/grant-type/mfa-otp"
21786
+ ]
21787
+ },
21788
+ {
21789
+ "type": "string",
21790
+ "enum": [
21791
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
21792
+ ]
21793
+ },
19274
21794
  {
19275
21795
  "type": "string",
19276
21796
  "enum": [
@@ -19316,6 +21836,14 @@
19316
21836
  "refresh_token": {
19317
21837
  "type": "string"
19318
21838
  },
21839
+ "mfa_token": {
21840
+ "type": "string",
21841
+ "description": "Opaque token returned with a `403 mfa_required` response. Present it here with `grant_type=http://auth0.com/oauth/grant-type/mfa-otp` (or `…/mfa-recovery-code`) and the code, to finish a grant a second-factor policy interrupted."
21842
+ },
21843
+ "recovery_code": {
21844
+ "type": "string",
21845
+ "description": "One of the user's one-time recovery codes, for `grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code`."
21846
+ },
19319
21847
  "subject_token": {
19320
21848
  "type": "string"
19321
21849
  },
@@ -19368,6 +21896,18 @@
19368
21896
  "password"
19369
21897
  ]
19370
21898
  },
21899
+ {
21900
+ "type": "string",
21901
+ "enum": [
21902
+ "http://auth0.com/oauth/grant-type/mfa-otp"
21903
+ ]
21904
+ },
21905
+ {
21906
+ "type": "string",
21907
+ "enum": [
21908
+ "http://auth0.com/oauth/grant-type/mfa-recovery-code"
21909
+ ]
21910
+ },
19371
21911
  {
19372
21912
  "type": "string",
19373
21913
  "enum": [
@@ -19457,6 +21997,24 @@
19457
21997
  "name": "refresh_token",
19458
21998
  "required": false
19459
21999
  },
22000
+ {
22001
+ "schema": {
22002
+ "type": "string"
22003
+ },
22004
+ "in": "query",
22005
+ "name": "mfa_token",
22006
+ "required": false,
22007
+ "description": "Opaque token returned with a `403 mfa_required` response. Present it here with `grant_type=http://auth0.com/oauth/grant-type/mfa-otp` (or `…/mfa-recovery-code`) and the code, to finish a grant a second-factor policy interrupted."
22008
+ },
22009
+ {
22010
+ "schema": {
22011
+ "type": "string"
22012
+ },
22013
+ "in": "query",
22014
+ "name": "recovery_code",
22015
+ "required": false,
22016
+ "description": "One of the user's one-time recovery codes, for `grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code`."
22017
+ },
19460
22018
  {
19461
22019
  "schema": {
19462
22020
  "type": "string"