Get Authenticator Assurance Level
Inspect AAL1 / AAL2 state from the current session JWT.
Decode the current session's access token and report the user's authenticator assurance level (AAL). Use it to gate sensitive UI behind AAL2 ("user has stepped up with MFA") or to detect when a user has enrolled a factor but hasn't yet challenged it (current_level == "aal1", next_level == "aal2").
This method does NOT raise when there's no session — it returns a Struct with nil levels and an empty methods array. That lets you call it on every page load without rescuing.
Signature
supabase.auth.mfa.get_authenticator_assurance_levelTakes no arguments.
Parameters
This method has no parameters.
Returns
A Struct with three fields:
:current_level—"aal1","aal2", ornil(no session). Pulled from theaalclaim in the active JWT.:next_level—"aal2"if the user has any verified factor enrolled (i.e. they could step up), otherwise the same ascurrent_level. Anext_levelhigher thancurrent_levelis your cue to prompt the user to challenge their factor.:current_authentication_methods— Array ofSupabase::Auth::Types::AMREntry, each with:method(e.g."password","otp","totp") and:timestamp. Sourced from theamrclaim in the JWT.
Example — gate a sensitive action behind AAL2
aal = supabase.auth.mfa.get_authenticator_assurance_level
if aal.current_level != "aal2"
if aal.next_level == "aal2"
# User has a factor enrolled but hasn't challenged it in this session.
redirect_to "/mfa/challenge"
else
# User hasn't enrolled MFA at all.
redirect_to "/mfa/setup"
end
endExample — show the user how they signed in
aal = supabase.auth.mfa.get_authenticator_assurance_level
aal.current_authentication_methods.each do |entry|
case entry.method
when "password" then puts "Signed in with password at #{Time.at(entry.timestamp)}"
when "otp" then puts "Verified email OTP at #{Time.at(entry.timestamp)}"
when "totp" then puts "Stepped up with TOTP at #{Time.at(entry.timestamp)}"
end
endExample — safe to call without a session
# Even if the user is signed out, this returns a Struct rather than raising.
aal = supabase.auth.mfa.get_authenticator_assurance_level
aal.current_level # => nil
aal.next_level # => nil
aal.current_authentication_methods # => []Invalid amr entries (e.g. missing method) are silently dropped via .compact. In practice GoTrue always emits well-formed amr entries, so the difference only matters with hand-forged tokens.