IDENTITY FUNDAMENTALS · LAB
Sign in as Ava, then make her sign-in multi-factor
Watch your tenant check Ava's password, register an authenticator app and a passkey to her account, and read the evidence of each sign-in in amr and Audit.
ReadyUses your lab tenant
The lesson
Builds on: What is Identity?.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Your progress
Press Start before you begin. Only events your tenant records after that count, in the order below. Checking reads your tenant's Audit, so you need Audit read access in it.
Sign in to start this lab and check your progress. Log in or create an account.
Sign in as Ava with her password
Recorded as
account.sign_insucceeded (signed_in) about[email protected].Try a wrong password
Recorded as
account.sign_inrejected (invalid_credentials).Register an authenticator to Ava's account
Recorded as
account.enrollsucceeded (method_enrolled) about[email protected].Complete a second step as Ava
Recorded as
account.second_stepsucceeded (second_step_completed) about[email protected].Use one recovery code
Recorded as
account.second_stepsucceeded (recovery_code_used).
Setup
You need Ava's password from the first lab and an authenticator app on your phone. A passkey-capable browser or a security key is optional.
On this lab page choose Lab Photos and press Start.
Authentication > Authenticator app: set it to Optional with the issuer name
Lab Photos. Save.Authentication > Passkey or security key: set it to Optional and keep the other defaults. Save.
Confirm that the second step setting is the default: users who have registered a second step are asked for it.
Set the issuer in your shell:
ISSUER=https://tenant-<id>.beyondthelogin.dev
Walkthrough
In a private window open
$ISSUER/loginand sign in as Ava. You land on/account.
Why it matters: the email identified the account; the password was the evidence supporting her claim to use it.
Sign out. Try Ava with a wrong password, then
[email protected]with any password. Both attempts get the same message and the same401status. In Audit, bothaccount.sign_inrejections have no actor.
Why it matters: typing an email address is only a claim. Nobody was authenticated, so the tenant records no actor and the page reveals nothing about which accounts exist.
Sign in as Ava through
$ISSUER/token-decoderwithopenid profile. The ID token has"amr": ["pwd"]and anauth_time.As Ava open
$ISSUER/account/securityand add an authenticator app. Scan the QR code, enter the current code, and store the recovery codes somewhere safe.
Why it matters: the authenticator works for Ava only because it was registered to her account while she was signed in. Holding some authenticator app is not enough; the association made through a trusted process is what counts.
Sign out and sign in again at
$ISSUER/login. After the password you land on/login/verifyand enter the six-digit code.In the Token Decoder, tick the option that asks for a fresh sign-in (
prompt=login) and sign in again with the password and code. The new ID token has"amr": ["pwd", "otp", "mfa"].
Why it matters: mfa appears because the second step is a different kind of factor, something you have rather than something you know. A second password on a second screen would not earn it.
As Ava, open
/account/securityagain and register a passkey. Sign out. Open DevTools > Network, then sign in with the passkey from/login. Find the options response with a randomchallenge, and the request your browser sends back withauthenticatorData,clientDataJSONand asignature. Your fingerprint, face or PIN is nowhere in it.
Why it matters: the biometric or PIN unlocks the authenticator on your device, which then proves control to the tenant with a signature over the tenant's challenge. The fingerprint itself never reaches the website, and the signature is bound to the tenant's own origin.
In the Token Decoder with a fresh sign-in requested, sign in with the passkey.
amrshowsswkfor a synced passkey orhwkfor a key that stays on one device, plusmfawhen the device verified you.As Ava open
$ISSUER/manage. You are sent back to/account.
Why it matters: Ava is authenticated, but she holds no management role. Deciding what she may do is authorization, the subject of the next lab.
Break it
Sign in with the password, and at
/login/verifyenter a wrong code three times. Each is refused and Audit showsaccount.second_steprejected. Stop after three; repeated failures are limited per day.Now use one recovery code instead of the authenticator code. Audit shows
account.second_stepwith reasonrecovery_code_used. At the next sign-in, try the same recovery code again: it is refused, because each code works once.
Why it matters: a recovery code is still evidence of control, but single use limits how long a copied code is worth anything.
Check your work
Press Check my progress. It looks for:
account.sign_insucceeded with reasonsigned_infor Ava, and rejected with reasoninvalid_credentials.account.enrollsucceeded with reasonmethod_enrolledfor Ava.account.second_stepsucceeded with reasonsecond_step_completedfor Ava.account.second_stepsucceeded with reasonrecovery_code_used.
Compare the three ID tokens you collected: ["pwd"], ["pwd", "otp", "mfa"] and the passkey's amr.
Cleanup
Keep Ava's authenticator app, her passkey and the Optional settings. Later labs rely on Ava having a second step.
Store Ava's remaining recovery codes with her password.