AUTHENTICATION METHODS · LAB
Sign in by email link, email code and authenticator code
Sign Mia in by link and by code, watch expired and reused secrets fail, and show that an authenticator code cannot be replayed.
Partly readyIncludes a simulationUses your lab tenant
The lesson
Builds on: Methods, credentials, and factors.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Partly ready. Most of this lab runs today. Steps that wait on platform features are marked, and Missing infrastructure says what they need.
- G43 Push approvals with number matching
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.
Turn on the email and authenticator methods
Recorded as
tenant.authentication.updatesucceeded.Ask for a sign-in link
Recorded as
account.sign_insucceeded (link_sent).Finish signing in from the link
Recorded as
account.sign_insucceeded (signed_in).Enter a wrong email code
Recorded as
account.sign_inrejected (invalid_code).Set up the authenticator app
Recorded as
account.securitysucceeded (method_enrolled).Replay an authenticator code that was already used
Recorded as
account.second_steprejected (invalid_code).
Setup
Email steps need a real inbox, so this lab uses Mia, who receives mail at your own plus-address.
Keep Mia's address in the shell and create her in the portal: Users > Create user, first name
Mia, last nameLane, email your plus-address. Then Set password with a unique password from your password manager.
export MIA_EMAIL="[email protected]"
Open Authentication and set:
Email sign-in link Optional, lifetime 5 minutes, cross-device links off.
Email one-time code Optional, lifetime 5 minutes.
Authenticator app Optional, issuer
Lab Photos.
Save. Audit records
tenant.authentication.updatenaming the sections you changed.Open a private window for Mia, sign in at
$ISSUER/loginwith her password, and open$ISSUER/account/security. Confirm her email address with the code sent to your inbox, then turn on the email link and email code methods.
Walkthrough
Sign Mia out. At
$ISSUER/loginenter her address and choose Email me a link. Open the email in the same browser. The link opens a page that says "Continue to finish signing in", and only pressing its button signs Mia in.
Why it matters: a mail scanner that fetches the link only loads that page. It neither consumes the link nor signs anyone in, which is the lesson's warning about automatic link checks.
In Mia's window open
$ISSUER/token-decoderand sign in. The ID token says"amr": ["email"].
Why it matters: the evidence is control of the mailbox, not of a particular device. Anyone who can read Mia's mail could have done the same.
Ask for another link and open it in a different browser or another private window. It is refused with "Open this link in the browser where you asked for it."
Why it matters: with cross-device links off, a link works only in the browser that asked for it, which limits forwarded or intercepted links.
Open the link from step 1 again. It is refused because it was already used.
Why it matters: a delivered secret must work once, even if two requests race to use it.
Sign out and choose Email me a code. Type a wrong six-digit code first: it is refused. Then wait more than 5 minutes and enter the real code: it is refused as expired. Ask for a new code and enter it promptly: Mia is signed in, and the Token Decoder shows
"amr": ["otp"].
Why it matters: the lesson's table in action. Matching digits are not enough; the account, the pending attempt, the lifetime and the unused state are all checked, and wrong guesses are limited.
Sign out and sign in with Mia's password. Because Mia now has an email code method and the second step is set to
enrolled, the tenant asks for a second step: send yourself a code and enter it. Then open$ISSUER/account/securityand set up the authenticator app: scan the QR code and confirm a current code. Save the recovery codes shown once in your password manager.
Why it matters: the QR code carries the shared secret. Anyone who copies it can produce Mia's codes for as long as the secret is enrolled, which is why the setup needs a recent sign-in.
Sign out and sign in with Mia's password. At the second step, choose the authenticator app and enter its current code. Sign out again at once, sign in with the password, and enter the same code within its 30-second window. It is refused.
Why it matters: the tenant records the last time step it accepted, so a code someone watched Mia type cannot be used again.
Number matching, as a paper exercise.
Simulation. the tenant has no push approval method, and a relay of a real sign-in through a fake page must never be run against a tenant. Draw the flow instead.
Draw two lanes. In the first, Mia's own sign-in page shows the number 47 and her app asks her to type it, so a tired tap on an unexpected prompt does nothing. In the second, a fake page passes Mia's password to the real $ISSUER/login, receives the real number and shows it to her. Mark where number matching helps and where only a phishing-resistant method helps.
Why it matters: number matching stops prompt fatigue but not a relay, which is the lesson's closing point about every method that depends on something Mia reads or types.
Break it
The wrong email code in step 5 is recorded as
account.sign_inrejected with reasoninvalid_code. The expired one is counted in Logs, because no live attempt remained to record it against.The wrong-browser link and the reused link in steps 3 and 4 are refused with reason
invalid_linkin Logs.The replayed authenticator code in step 7 is recorded as
account.second_steprejected with reasoninvalid_code. Repeated wrong second steps are limited per account, so guessing six digits does not scale.
Check your work
Press Check my progress. The checks follow the policy change, the link sign-in, the wrong code, the authenticator enrollment and the refused replay.
Also confirm by hand:
Your inbox holds a security notification for each method Mia added.
Mia's ID tokens showed
["email"]after the link and["otp"]after the code.
Cleanup
Restore: in Authentication, set the email link and email code lifetimes back to 15 minutes.
Keep the three methods Optional and keep Mia's authenticator app and recovery codes. The next labs use them.
Missing infrastructure
G43, push approvals with number matching. A tenant-hosted approval method, such as a lab authenticator page bound to the user, would let step 8 run for real: send a prompt, deny an unexpected one, and show in Audit that a denied or expired approval fails the sign-in. Text-message codes are deliberately not proposed, in line with the lesson's note that they are a restricted option.