[{"data":1,"prerenderedAt":1668},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fauth-h3client":64,"navigation":217,"navLinks_footer":829,"\u002Fdocs\u002Fauth-h3client\u002Fmfa_page":842,"\u002Fdocs\u002Fauth-h3client\u002Fmfa_surround":1330,"\u002Fdocs\u002Fauth-h3client\u002Fmfa":1333},{"id":4,"extension":5,"links":6,"meta":61,"stem":62,"__hash__":63},"navigationMenu\u002Fnavigation.json","json",[7,52,57],{"nested":8,"label":9,"icon":10,"to":11,"children":12},true,"Docs","i-lucide-book-open","\u002Fdocs\u002Fgetting-started",[13,19,26,32,39,45],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},"Getting Started","i-lucide-rocket","An introduction to help you understand the core components.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fdocshub","Start Here",{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},"Auth H3 Client","i-lucide-key-round","\u002Fdocs\u002Fauth-h3client","Seamlessly enforce OAuth 2.0 authentication and session management integrated directly as the client of the IAM module.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth-h3client","Core",{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},"IAM","i-lucide-shield-check","\u002Fdocs\u002Fiam","Identity and Access Management featuring granular roles, permissions, and security policies.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth",{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},"Bot Detection","i-lucide-cpu","\u002Fdocs\u002Fbot-detection","Advanced behavioral analysis and request fingerprinting to stop malicious automated traffic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fbot-detector","Security",{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},"Shield Base","i-lucide-database-zap","\u002Fdocs\u002Fshield-base","CLI and programmatic toolkit for compiling offline-ready IP intelligence databases from BGP, GeoIP, Tor, FireHOL, and other public threat feeds.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fshield-base-cli",{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},"Utils","i-lucide-wrench","\u002Fdocs\u002Futils","A standard library of highly optimized helpers for formatting, validation, and core logic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Futils","Library",{"nested":53,"label":54,"icon":55,"to":56},false,"Blog","i-lucide-pen-line","\u002Fblog",{"nested":53,"label":58,"icon":59,"to":60},"Website","lucide:app-window-mac","https:\u002F\u002Friavzon.com",{},"navigation","gkaQ0xRGxSLrLyM3kttLe0oBwkrR1EBjlepF8LSbwF8",[65],{"title":9,"path":66,"stem":67,"children":68,"page":53},"\u002Fdocs","docs",[69],{"title":20,"path":22,"stem":70,"children":71},"docs\u002Fauth-h3client\u002Findex",[72,73,82,119,145,167,170,191,195],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":76},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[77,78],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":83,"path":84,"stem":85,"children":86},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[87,88,92,96,100,104,108,111,115],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":93,"path":94,"stem":95},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":97,"path":98,"stem":99},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":101,"path":102,"stem":103},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":105,"path":106,"stem":107},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":109,"stem":110},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":112,"path":113,"stem":114},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":116,"path":117,"stem":118},"Logging","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":120,"path":121,"stem":122,"children":123},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[124,125,129,133,137,141],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":130,"path":131,"stem":132},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":134,"path":135,"stem":136},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":138,"path":139,"stem":140},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":142,"path":143,"stem":144},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":146,"path":147,"stem":148,"children":149},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[150,151,155,159,163],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":156,"path":157,"stem":158},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":160,"path":161,"stem":162},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":164,"path":165,"stem":166},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":168,"stem":169},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":171,"path":172,"stem":173,"children":174,"page":53},"Guides","\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[175,179,183,187],{"title":176,"path":177,"stem":178},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":180,"path":181,"stem":182},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":184,"path":185,"stem":186},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":188,"path":189,"stem":190},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":192,"path":193,"stem":194},"Configuration","\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":196,"path":197,"stem":198,"children":199},"API Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[200,201,205,209,213],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":206,"path":207,"stem":208},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":210,"path":211,"stem":212},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":214,"path":215,"stem":216},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",[218],{"title":9,"path":66,"stem":67,"children":219,"page":53},[220,268,386,391,569,636],{"title":20,"path":22,"stem":70,"children":221},[222,223,227,238,246,253,254,260,261],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":224},[225,226],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},{"title":83,"path":84,"stem":85,"children":228},[229,230,231,232,233,234,235,236,237],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},{"title":93,"path":94,"stem":95},{"title":97,"path":98,"stem":99},{"title":101,"path":102,"stem":103},{"title":105,"path":106,"stem":107},{"title":33,"path":109,"stem":110},{"title":112,"path":113,"stem":114},{"title":116,"path":117,"stem":118},{"title":120,"path":121,"stem":122,"children":239},[240,241,242,243,244,245],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},{"title":130,"path":131,"stem":132},{"title":134,"path":135,"stem":136},{"title":138,"path":139,"stem":140},{"title":142,"path":143,"stem":144},{"title":146,"path":147,"stem":148,"children":247},[248,249,250,251,252],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},{"title":156,"path":157,"stem":158},{"title":160,"path":161,"stem":162},{"title":164,"path":165,"stem":166},{"title":38,"path":168,"stem":169},{"title":171,"path":172,"stem":173,"children":255,"page":53},[256,257,258,259],{"title":176,"path":177,"stem":178},{"title":180,"path":181,"stem":182},{"title":184,"path":185,"stem":186},{"title":188,"path":189,"stem":190},{"title":192,"path":193,"stem":194},{"title":196,"path":197,"stem":198,"children":262},[263,264,265,266,267],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},{"title":206,"path":207,"stem":208},{"title":210,"path":211,"stem":212},{"title":214,"path":215,"stem":216},{"title":269,"path":35,"stem":270,"children":271},"Bot Detector","docs\u002Fbot-detection\u002Findex",[272,273,276,280,284,303,377,380,383],{"title":269,"path":35,"stem":270},{"title":14,"path":274,"stem":275},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":277,"path":278,"stem":279},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":281,"path":282,"stem":283},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":171,"path":285,"stem":286,"children":287,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[288,292,296,299],{"title":289,"path":290,"stem":291},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":293,"path":294,"stem":295},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":116,"path":297,"stem":298},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":300,"path":301,"stem":302},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":304,"path":305,"stem":306,"children":307},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[308,309,313,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373],{"title":304,"path":305,"stem":306},{"title":310,"path":311,"stem":312},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":314,"path":315,"stem":316},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":318,"path":319,"stem":320},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":322,"path":323,"stem":324},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":326,"path":327,"stem":328},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":330,"path":331,"stem":332},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":334,"path":335,"stem":336},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":338,"path":339,"stem":340},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":342,"path":343,"stem":344},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":346,"path":347,"stem":348},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":350,"path":351,"stem":352},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":354,"path":355,"stem":356},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":358,"path":359,"stem":360},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":362,"path":363,"stem":364},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":366,"path":367,"stem":368},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":370,"path":371,"stem":372},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":374,"path":375,"stem":376},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":378,"stem":379},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":196,"path":381,"stem":382},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":192,"path":384,"stem":385},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":387,"path":11,"stem":388,"children":389},"Introduction","docs\u002Fgetting-started\u002Findex",[390],{"title":387,"path":11,"stem":388},{"title":27,"path":29,"stem":392,"children":393},"docs\u002Fiam\u002Findex",[394,395,398,533,536,552,555],{"title":27,"path":29,"stem":392},{"title":14,"path":396,"stem":397},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":83,"path":399,"stem":400,"children":401},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[402,403,407,411,415,419,423,427,431,435,439,443,446,450,454,458,462,465,469,473,476,480,483],{"title":83,"path":399,"stem":400},{"title":404,"path":405,"stem":406},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":408,"path":409,"stem":410},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":412,"path":413,"stem":414},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":416,"path":417,"stem":418},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":420,"path":421,"stem":422},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":424,"path":425,"stem":426},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":428,"path":429,"stem":430},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":432,"path":433,"stem":434},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":436,"path":437,"stem":438},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":440,"path":441,"stem":442},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":120,"path":444,"stem":445},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":447,"path":448,"stem":449},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":451,"path":452,"stem":453},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":455,"path":456,"stem":457},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":459,"path":460,"stem":461},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":116,"path":463,"stem":464},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":466,"path":467,"stem":468},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":470,"path":471,"stem":472},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":112,"path":474,"stem":475},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":477,"path":478,"stem":479},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":130,"path":481,"stem":482},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":484,"path":485,"stem":486,"children":487},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[488,489,493,497,527,530],{"title":484,"path":485,"stem":486},{"title":490,"path":491,"stem":492},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":494,"path":495,"stem":496},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":498,"path":499,"stem":500,"children":501},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[502,503,507,511,515,519,523],{"title":498,"path":499,"stem":500},{"title":504,"path":505,"stem":506},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":508,"path":509,"stem":510},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":512,"path":513,"stem":514},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":516,"path":517,"stem":518},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":520,"path":521,"stem":522},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":524,"path":525,"stem":526},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":466,"path":528,"stem":529},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":531,"stem":532},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":534,"stem":535},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":171,"path":537,"stem":538,"children":539,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[540,544,548],{"title":541,"path":542,"stem":543},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":545,"path":546,"stem":547},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":549,"path":550,"stem":551},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":192,"path":553,"stem":554},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":556,"path":557,"stem":558,"children":559,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[560,563,566],{"title":196,"path":561,"stem":562},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":206,"path":564,"stem":565},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":202,"path":567,"stem":568},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":570,"children":571},"docs\u002Fshield-base\u002Findex",[572,573,576,580,621,625,629,633],{"title":40,"path":42,"stem":570},{"title":14,"path":574,"stem":575},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":577,"path":578,"stem":579},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":281,"path":581,"stem":582,"children":583},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[584,585,589,593,597,601,605,609,613,617],{"title":281,"path":581,"stem":582},{"title":586,"path":587,"stem":588},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":590,"path":591,"stem":592},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":594,"path":595,"stem":596},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":598,"path":599,"stem":600},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":602,"path":603,"stem":604},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":606,"path":607,"stem":608},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":610,"path":611,"stem":612},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":614,"path":615,"stem":616},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":618,"path":619,"stem":620},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":622,"path":623,"stem":624},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":626,"path":627,"stem":628},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":630,"path":631,"stem":632},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":196,"path":634,"stem":635},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":214,"path":48,"stem":637,"children":638},"docs\u002Futils\u002Findex",[639,640,657,690,787],{"title":214,"path":48,"stem":637},{"title":641,"path":642,"stem":643,"children":644,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[645,649,653],{"title":646,"path":647,"stem":648},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":650,"path":651,"stem":652},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":654,"path":655,"stem":656},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":658,"path":659,"stem":660,"children":661,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[662,666,670,674,678,682,686],{"title":663,"path":664,"stem":665},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":667,"path":668,"stem":669},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":671,"path":672,"stem":673},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":675,"path":676,"stem":677},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":679,"path":680,"stem":681},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":683,"path":684,"stem":685},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":687,"path":688,"stem":689},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":691,"path":692,"stem":693,"children":694,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[695,699,703,707,711,715,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783],{"title":696,"path":697,"stem":698},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":700,"path":701,"stem":702},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":704,"path":705,"stem":706},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":708,"path":709,"stem":710},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":712,"path":713,"stem":714},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":716,"path":717,"stem":718},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":720,"path":721,"stem":722},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":724,"path":725,"stem":726},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":728,"path":729,"stem":730},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":732,"path":733,"stem":734},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":736,"path":737,"stem":738},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":740,"path":741,"stem":742},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":744,"path":745,"stem":746},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":748,"path":749,"stem":750},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":752,"path":753,"stem":754},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":756,"path":757,"stem":758},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":760,"path":761,"stem":762},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":764,"path":765,"stem":766},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":768,"path":769,"stem":770},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":772,"path":773,"stem":774},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":776,"path":777,"stem":778},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":780,"path":781,"stem":782},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":784,"path":785,"stem":786},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":788,"path":789,"stem":790,"children":791},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[792,793,797,801,805,809,813,817,821,825],{"title":788,"path":789,"stem":790},{"title":794,"path":795,"stem":796},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":798,"path":799,"stem":800},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":802,"path":803,"stem":804},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":806,"path":807,"stem":808},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":810,"path":811,"stem":812},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":814,"path":815,"stem":816},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":818,"path":819,"stem":820},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":822,"path":823,"stem":824},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":826,"path":827,"stem":828},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":830,"meta":841,"stem":62,"__hash__":63},[831,839,840],{"nested":8,"label":9,"icon":10,"to":11,"children":832},[833,834,835,836,837,838],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},{"nested":53,"label":54,"icon":55,"to":56},{"nested":53,"label":58,"icon":59,"to":60},{},{"id":843,"title":120,"body":844,"description":1323,"extension":1324,"icon":28,"meta":1325,"module":1326,"navigation":8,"path":121,"rawbody":1327,"seo":1328,"stem":122,"__hash__":1329},"docs\u002Fdocs\u002Fauth-h3client\u002F02.mfa\u002Findex.md",{"type":845,"value":846,"toc":1311},"minimark",[847,861,864,892,895,900,926,929,988,997,1009,1011,1015,1018,1051,1053,1057,1060,1079,1092,1094,1098,1101,1146,1149,1151,1155,1166,1168,1172,1179,1232,1236,1239,1289,1295,1299],[848,849,850,851,855,856,860],"p",{},"The module supports email-based Multi-Factor Authentication as a secondary verification layer. MFA is not something you enable in the gateway: the ",[852,853,854],"a",{"href":417},"IAM service"," decides when a session requires additional proof based on anomaly detection. The gateway detects the ",[857,858,859],"code",{},"202"," response, surfaces it to your frontend, and provides the handlers and composables needed to complete the verification.",[848,862,863],{},"Two paradigms are available:",[865,866,867,874],"ol",{},[868,869,870,873],"li",{},[871,872,126],"strong",{},": triggered automatically by the IAM service during token rotation when it detects anomalies such as a new device, idle session, IP range change, or elevated risk score. The user receives an email with a magic link and a 7-digit code. The gateway ships ready-to-use routes that verify the link and code without any custom server code.",[868,875,876,879,880,883,884,887,888,891],{},[871,877,878],{},"Custom MFA",": initiated by your application code for sensitive actions like password changes, email updates, or account deletion. You call ",[857,881,882],{},"askForMfaFlow"," with a reason and a cryptographic buffer, the IAM service sends the verification email, and you wrap your action handler with ",[857,885,886],{},"defineMfaCodeVerifierHandler"," or ",[857,889,890],{},"defineVerifiedMagicLinkGetHandler",".",[893,894],"hr",{},[896,897,899],"h2",{"id":898},"how-mfa-is-triggered","How MFA is triggered",[848,901,902,903,907,908,914,915,918,919,921,922,925],{},"During ",[852,904,906],{"href":905},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession#token-rotation","token rotation",", the gateway calls the IAM ",[852,909,911],{"href":910},"\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens#token-rotation",[857,912,913],{},"\u002Fauth\u002Fuser\u002Frefresh-session"," endpoint. When the IAM service runs its ",[852,916,917],{"href":417},"anomaly detection"," checks and determines the session needs verification, it returns HTTP ",[857,920,859],{}," with ",[857,923,924],{},"{ mfa: true, message: \"...\" }"," instead of rotating the tokens.",[848,927,928],{},"The gateway propagates this response through three layers:",[930,931,932,945],"table",{},[933,934,935],"thead",{},[936,937,938,942],"tr",{},[939,940,941],"th",{},"Detection point",[939,943,944],{},"What happens",[946,947,948,963,975],"tbody",{},[936,949,950,956],{},[951,952,953],"td",{},[857,954,955],{},"ensureValidCredentials",[951,957,958,959,962],{},"Returns ",[857,960,961],{},"{ text: 'MFA required', message }"," with status 202",[936,964,965,970],{},[951,966,967],{},[857,968,969],{},"getCachedUserData",[951,971,958,972],{},[857,973,974],{},"{ type: 'ERROR', reason: 'MFA', status: 202 }",[936,976,977,982],{},[951,978,979],{},[857,980,981],{},"defineAuthenticatedEventHandler",[951,983,958,984,987],{},[857,985,986],{},"{ mfaRequired: 'MFA required' }"," to the client",[848,989,990,991,993,994,996],{},"On the client side, you should implement a method to detect that ",[857,992,859],{}," status or ",[857,995,986],{}," response, and render a proper ui for the user.",[848,998,999,1000,1004,1005,1008],{},"If you use the Nuxt module ",[852,1001,1002],{"href":153},[857,1003,152],{}," handles that for you, and sets ",[857,1006,1007],{},"mfaRequired: true"," on the reactive auth state. Your frontend should checks this field and redirects to the verification page.",[893,1010],{},[896,1012,1014],{"id":1013},"verification-flow","Verification flow",[848,1016,1017],{},"Regardless of whether MFA was triggered by the built-in flow or a custom flow, verification follows the same pattern:",[865,1019,1020,1023,1041,1048],{},[868,1021,1022],{},"The user receives an email containing a magic link and a 7-digit numeric code.",[868,1024,1025,1026,1029,1030,1029,1033,1036,1037,1040],{},"The magic link points to a bounce URL on the gateway, which redirects to your frontend verification page with ",[857,1027,1028],{},"token",", ",[857,1031,1032],{},"random",[857,1034,1035],{},"reason",", and ",[857,1038,1039],{},"visitor"," query parameters.",[868,1042,1043,1044,1047],{},"The frontend calls ",[857,1045,1046],{},"useMagicLink()"," or the appropriate path to validate the link parameters against the server.",[868,1049,1050],{},"The user enters the 7-digit code in your UI and submits it. The server verifies the code with the IAM service, rotates both tokens, and returns success.",[893,1052],{},[896,1054,1056],{"id":1055},"token-rotation-on-success","Token rotation on success",[848,1058,1059],{},"Successful MFA verification always triggers a full token rotation. The IAM service:",[1061,1062,1063,1066,1069,1076],"ul",{},[868,1064,1065],{},"Marks the old refresh token as consumed",[868,1067,1068],{},"Generates a new access token and refresh token pair",[868,1070,1071,1072,1075],{},"Updates ",[857,1073,1074],{},"users.last_mfa_at"," to record when MFA was last completed",[868,1077,1078],{},"Returns the new tokens in the response",[848,1080,1081,1082,1029,1085,1036,1088,1091],{},"The gateway applies the rotation result by setting the ",[857,1083,1084],{},"__Secure-a",[857,1086,1087],{},"a-iat",[857,1089,1090],{},"session"," cookies on the response. This invalidates the pre-MFA session and ensures subsequent requests use fresh credentials.",[893,1093],{},[896,1095,1097],{"id":1096},"session-binding","Session binding",[848,1099,1100],{},"MFA verification is bound to the existing session through three cookies:",[930,1102,1103,1113],{},[933,1104,1105],{},[936,1106,1107,1110],{},[939,1108,1109],{},"Cookie",[939,1111,1112],{},"Role",[946,1114,1115,1128,1137],{},[936,1116,1117,1122],{},[951,1118,1119],{},[857,1120,1121],{},"canary_id",[951,1123,1124,1125],{},"Ties the verification to the device fingerprint tracked by the ",[852,1126,1127],{"href":35},"bot detector",[936,1129,1130,1134],{},[951,1131,1132],{},[857,1133,1090],{},[951,1135,1136],{},"Identifies the refresh token that initiated the flow",[936,1138,1139,1143],{},[951,1140,1141],{},[857,1142,1084],{},[951,1144,1145],{},"Provides the access token for the signed request to the IAM service",[848,1147,1148],{},"If any of these cookies are missing, the gateway rejects the verification request with HTTP 401.",[893,1150],{},[896,1152,1154],{"id":1153},"rate-limiting","Rate limiting",[848,1156,1157,1158,1161,1162,1165],{},"The IAM service applies rate limits at multiple levels during MFA flows: per IP, per user ID, per session, and per JTI. When the limit is exceeded, the gateway receives HTTP 429 and forwards the ",[857,1159,1160],{},"Retry-After"," header to the client. See ",[852,1163,1164],{"href":467},"IAM Rate Limiting"," for the specific limits.",[893,1167],{},[896,1169,1171],{"id":1170},"built-in-flows","Built-in flows",[848,1173,1174,1175,1178],{},"The module ships ready-to-use server routes for the three standard verification flows. Each flow registers its own GET and POST handlers through ",[857,1176,1177],{},"magicLinksRouter",":",[930,1180,1181,1194],{},[933,1182,1183],{},[936,1184,1185,1188,1191],{},[939,1186,1187],{},"Flow",[939,1189,1190],{},"Trigger",[939,1192,1193],{},"Pages",[946,1195,1196,1208,1220],{},[936,1197,1198,1202,1205],{},[951,1199,1200],{},[852,1201,126],{"href":127},[951,1203,1204],{},"Anomaly detection during token rotation",[951,1206,1207],{},"Verify magic link, submit code",[936,1209,1210,1214,1217],{},[951,1211,1212],{},[852,1213,130],{"href":131},[951,1215,1216],{},"User requests password reset",[951,1218,1219],{},"Initiate, verify link, submit new password",[936,1221,1222,1226,1229],{},[951,1223,1224],{},[852,1225,134],{"href":135},[951,1227,1228],{},"User requests email change",[951,1230,1231],{},"Initiate, verify link, submit new email",[896,1233,1235],{"id":1234},"custom-flows","Custom flows",[848,1237,1238],{},"For sensitive actions beyond the built-in flows, you create your own endpoints using the MFA utilities:",[930,1240,1241,1251],{},[933,1242,1243],{},[936,1244,1245,1248],{},[939,1246,1247],{},"Utility",[939,1249,1250],{},"Purpose",[946,1252,1253,1265,1277],{},[936,1254,1255,1262],{},[951,1256,1257],{},[852,1258,1260],{"href":1259},"\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#initiating-the-flow",[857,1261,882],{},[951,1263,1264],{},"Sends verification email for a custom reason",[936,1266,1267,1274],{},[951,1268,1269],{},[852,1270,1272],{"href":1271},"\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#magic-link-verification",[857,1273,890],{},[951,1275,1276],{},"Wraps a GET handler with magic link verification",[936,1278,1279,1286],{},[951,1280,1281],{},[852,1282,1284],{"href":1283},"\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#code-verification",[857,1285,886],{},[951,1287,1288],{},"Wraps a POST handler with code verification and token rotation",[848,1290,1291,1292,1294],{},"See ",[852,1293,138],{"href":139}," for the full implementation guide.",[896,1296,1298],{"id":1297},"client-side-integration","Client-side integration",[848,1300,1301,1302,1304,1305,1307,1308,1310],{},"The ",[857,1303,156],{}," composable handles the frontend verification page. It parses the URL query parameters, routes to the correct server endpoint based on the ",[857,1306,1035],{}," field, and returns the verified data for your UI to render the appropriate form. See ",[852,1309,142],{"href":143}," for usage details.",{"title":1312,"searchDepth":1313,"depth":1313,"links":1314},"",2,[1315,1316,1317,1318,1319,1320,1321,1322],{"id":898,"depth":1313,"text":899},{"id":1013,"depth":1313,"text":1014},{"id":1055,"depth":1313,"text":1056},{"id":1096,"depth":1313,"text":1097},{"id":1153,"depth":1313,"text":1154},{"id":1170,"depth":1313,"text":1171},{"id":1234,"depth":1313,"text":1235},{"id":1297,"depth":1313,"text":1298},"How the module detects MFA challenges from the IAM service, verifies magic links and codes, rotates tokens on success, and supports custom step-up flows for sensitive actions.","md",{},null,"---\ntitle: MFA\ndescription: How the module detects MFA challenges from the IAM service, verifies magic links and codes, rotates tokens on success, and supports custom step-up flows for sensitive actions.\nicon: i-lucide-shield-check\n---\n\nThe module supports email-based Multi-Factor Authentication as a secondary verification layer. MFA is not something you enable in the gateway: the [IAM service](\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies) decides when a session requires additional proof based on anomaly detection. The gateway detects the `202` response, surfaces it to your frontend, and provides the handlers and composables needed to complete the verification.\n\nTwo paradigms are available:\n\n1. **Built-in MFA**: triggered automatically by the IAM service during token rotation when it detects anomalies such as a new device, idle session, IP range change, or elevated risk score. The user receives an email with a magic link and a 7-digit code. The gateway ships ready-to-use routes that verify the link and code without any custom server code.\n\n2. **Custom MFA**: initiated by your application code for sensitive actions like password changes, email updates, or account deletion. You call `askForMfaFlow` with a reason and a cryptographic buffer, the IAM service sends the verification email, and you wrap your action handler with `defineMfaCodeVerifierHandler` or `defineVerifiedMagicLinkGetHandler`.\n\n---\n\n## How MFA is triggered\n\nDuring [token rotation](\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession#token-rotation), the gateway calls the IAM [`\u002Fauth\u002Fuser\u002Frefresh-session`](\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens#token-rotation) endpoint. When the IAM service runs its [anomaly detection](\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies) checks and determines the session needs verification, it returns HTTP `202` with `{ mfa: true, message: \"...\" }` instead of rotating the tokens.\n\nThe gateway propagates this response through three layers:\n\n| Detection point | What happens |\n|---|---|\n| `ensureValidCredentials` | Returns `{ text: 'MFA required', message }` with status 202 |\n| `getCachedUserData` | Returns `{ type: 'ERROR', reason: 'MFA', status: 202 }` |\n| `defineAuthenticatedEventHandler` | Returns `{ mfaRequired: 'MFA required' }` to the client |\n\nOn the client side, you should implement a method to detect that `202` status or `{ mfaRequired: 'MFA required' }` response, and render a proper ui for the user.\n\nIf you use the Nuxt module [`useAuthData`](\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data) handles that for you, and sets `mfaRequired: true` on the reactive auth state. Your frontend should checks this field and redirects to the verification page.\n\n---\n\n## Verification flow\n\nRegardless of whether MFA was triggered by the built-in flow or a custom flow, verification follows the same pattern:\n\n1. The user receives an email containing a magic link and a 7-digit numeric code.\n2. The magic link points to a bounce URL on the gateway, which redirects to your frontend verification page with `token`, `random`, `reason`, and `visitor` query parameters.\n3. The frontend calls `useMagicLink()` or the appropriate path to validate the link parameters against the server.\n4. The user enters the 7-digit code in your UI and submits it. The server verifies the code with the IAM service, rotates both tokens, and returns success.\n\n---\n\n## Token rotation on success\n\nSuccessful MFA verification always triggers a full token rotation. The IAM service:\n\n- Marks the old refresh token as consumed\n- Generates a new access token and refresh token pair\n- Updates `users.last_mfa_at` to record when MFA was last completed\n- Returns the new tokens in the response\n\nThe gateway applies the rotation result by setting the `__Secure-a`, `a-iat`, and `session` cookies on the response. This invalidates the pre-MFA session and ensures subsequent requests use fresh credentials.\n\n---\n\n## Session binding\n\nMFA verification is bound to the existing session through three cookies:\n\n| Cookie | Role |\n|---|---|\n| `canary_id` | Ties the verification to the device fingerprint tracked by the [bot detector](\u002Fdocs\u002Fbot-detection) |\n| `session` | Identifies the refresh token that initiated the flow |\n| `__Secure-a` | Provides the access token for the signed request to the IAM service |\n\nIf any of these cookies are missing, the gateway rejects the verification request with HTTP 401.\n\n---\n\n## Rate limiting\n\nThe IAM service applies rate limits at multiple levels during MFA flows: per IP, per user ID, per session, and per JTI. When the limit is exceeded, the gateway receives HTTP 429 and forwards the `Retry-After` header to the client. See [IAM Rate Limiting](\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting) for the specific limits.\n\n---\n\n## Built-in flows\n\nThe module ships ready-to-use server routes for the three standard verification flows. Each flow registers its own GET and POST handlers through `magicLinksRouter`:\n\n| Flow | Trigger | Pages |\n|---|---|---|\n| [Built-in MFA](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow) | Anomaly detection during token rotation | Verify magic link, submit code |\n| [Password Reset](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset) | User requests password reset | Initiate, verify link, submit new password |\n| [Email Change](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change) | User requests email change | Initiate, verify link, submit new email |\n\n## Custom flows\n\nFor sensitive actions beyond the built-in flows, you create your own endpoints using the MFA utilities:\n\n| Utility | Purpose |\n|---|---|\n| [`askForMfaFlow`](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#initiating-the-flow) | Sends verification email for a custom reason |\n| [`defineVerifiedMagicLinkGetHandler`](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#magic-link-verification) | Wraps a GET handler with magic link verification |\n| [`defineMfaCodeVerifierHandler`](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow#code-verification) | Wraps a POST handler with code verification and token rotation |\n\nSee [Custom MFA Flow](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow) for the full implementation guide.\n\n## Client-side integration\n\nThe `useMagicLink` composable handles the frontend verification page. It parses the URL query parameters, routes to the correct server endpoint based on the `reason` field, and returns the verified data for your UI to render the appropriate form. See [Client-Side MFA](\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side) for usage details.\n",{"title":120,"description":1323},"TK7YbFrmQ6AgijEADHfQkhmB_KbjWyF15NNmdgdhMb8",[1331,1332],{"title":116,"path":117,"stem":118,"children":-1},{"title":126,"path":127,"stem":128,"children":-1},{"id":843,"title":120,"body":1334,"description":1323,"extension":1324,"icon":28,"meta":1666,"module":1326,"navigation":8,"path":121,"rawbody":1327,"seo":1667,"stem":122,"__hash__":1329},{"type":845,"value":1335,"toc":1656},[1336,1342,1344,1360,1362,1364,1378,1380,1422,1428,1436,1438,1440,1442,1462,1464,1466,1468,1480,1488,1490,1492,1494,1532,1534,1536,1538,1544,1546,1548,1552,1596,1598,1600,1642,1646,1648],[848,1337,850,1338,855,1340,860],{},[852,1339,854],{"href":417},[857,1341,859],{},[848,1343,863],{},[865,1345,1346,1350],{},[868,1347,1348,873],{},[871,1349,126],{},[868,1351,1352,879,1354,883,1356,887,1358,891],{},[871,1353,878],{},[857,1355,882],{},[857,1357,886],{},[857,1359,890],{},[893,1361],{},[896,1363,899],{"id":898},[848,1365,902,1366,907,1368,914,1372,918,1374,921,1376,925],{},[852,1367,906],{"href":905},[852,1369,1370],{"href":910},[857,1371,913],{},[852,1373,917],{"href":417},[857,1375,859],{},[857,1377,924],{},[848,1379,928],{},[930,1381,1382,1390],{},[933,1383,1384],{},[936,1385,1386,1388],{},[939,1387,941],{},[939,1389,944],{},[946,1391,1392,1402,1412],{},[936,1393,1394,1398],{},[951,1395,1396],{},[857,1397,955],{},[951,1399,958,1400,962],{},[857,1401,961],{},[936,1403,1404,1408],{},[951,1405,1406],{},[857,1407,969],{},[951,1409,958,1410],{},[857,1411,974],{},[936,1413,1414,1418],{},[951,1415,1416],{},[857,1417,981],{},[951,1419,958,1420,987],{},[857,1421,986],{},[848,1423,990,1424,993,1426,996],{},[857,1425,859],{},[857,1427,986],{},[848,1429,999,1430,1004,1434,1008],{},[852,1431,1432],{"href":153},[857,1433,152],{},[857,1435,1007],{},[893,1437],{},[896,1439,1014],{"id":1013},[848,1441,1017],{},[865,1443,1444,1446,1456,1460],{},[868,1445,1022],{},[868,1447,1025,1448,1029,1450,1029,1452,1036,1454,1040],{},[857,1449,1028],{},[857,1451,1032],{},[857,1453,1035],{},[857,1455,1039],{},[868,1457,1043,1458,1047],{},[857,1459,1046],{},[868,1461,1050],{},[893,1463],{},[896,1465,1056],{"id":1055},[848,1467,1059],{},[1061,1469,1470,1472,1474,1478],{},[868,1471,1065],{},[868,1473,1068],{},[868,1475,1071,1476,1075],{},[857,1477,1074],{},[868,1479,1078],{},[848,1481,1081,1482,1029,1484,1036,1486,1091],{},[857,1483,1084],{},[857,1485,1087],{},[857,1487,1090],{},[893,1489],{},[896,1491,1097],{"id":1096},[848,1493,1100],{},[930,1495,1496,1504],{},[933,1497,1498],{},[936,1499,1500,1502],{},[939,1501,1109],{},[939,1503,1112],{},[946,1505,1506,1516,1524],{},[936,1507,1508,1512],{},[951,1509,1510],{},[857,1511,1121],{},[951,1513,1124,1514],{},[852,1515,1127],{"href":35},[936,1517,1518,1522],{},[951,1519,1520],{},[857,1521,1090],{},[951,1523,1136],{},[936,1525,1526,1530],{},[951,1527,1528],{},[857,1529,1084],{},[951,1531,1145],{},[848,1533,1148],{},[893,1535],{},[896,1537,1154],{"id":1153},[848,1539,1157,1540,1161,1542,1165],{},[857,1541,1160],{},[852,1543,1164],{"href":467},[893,1545],{},[896,1547,1171],{"id":1170},[848,1549,1174,1550,1178],{},[857,1551,1177],{},[930,1553,1554,1564],{},[933,1555,1556],{},[936,1557,1558,1560,1562],{},[939,1559,1187],{},[939,1561,1190],{},[939,1563,1193],{},[946,1565,1566,1576,1586],{},[936,1567,1568,1572,1574],{},[951,1569,1570],{},[852,1571,126],{"href":127},[951,1573,1204],{},[951,1575,1207],{},[936,1577,1578,1582,1584],{},[951,1579,1580],{},[852,1581,130],{"href":131},[951,1583,1216],{},[951,1585,1219],{},[936,1587,1588,1592,1594],{},[951,1589,1590],{},[852,1591,134],{"href":135},[951,1593,1228],{},[951,1595,1231],{},[896,1597,1235],{"id":1234},[848,1599,1238],{},[930,1601,1602,1610],{},[933,1603,1604],{},[936,1605,1606,1608],{},[939,1607,1247],{},[939,1609,1250],{},[946,1611,1612,1622,1632],{},[936,1613,1614,1620],{},[951,1615,1616],{},[852,1617,1618],{"href":1259},[857,1619,882],{},[951,1621,1264],{},[936,1623,1624,1630],{},[951,1625,1626],{},[852,1627,1628],{"href":1271},[857,1629,890],{},[951,1631,1276],{},[936,1633,1634,1640],{},[951,1635,1636],{},[852,1637,1638],{"href":1283},[857,1639,886],{},[951,1641,1288],{},[848,1643,1291,1644,1294],{},[852,1645,138],{"href":139},[896,1647,1298],{"id":1297},[848,1649,1301,1650,1304,1652,1307,1654,1310],{},[857,1651,156],{},[857,1653,1035],{},[852,1655,142],{"href":143},{"title":1312,"searchDepth":1313,"depth":1313,"links":1657},[1658,1659,1660,1661,1662,1663,1664,1665],{"id":898,"depth":1313,"text":899},{"id":1013,"depth":1313,"text":1014},{"id":1055,"depth":1313,"text":1056},{"id":1096,"depth":1313,"text":1097},{"id":1153,"depth":1313,"text":1154},{"id":1170,"depth":1313,"text":1171},{"id":1234,"depth":1313,"text":1235},{"id":1297,"depth":1313,"text":1298},{},{"title":120,"description":1323},1780436291736]