Agent Wranglers

Sign-in methods Recommended

Weigh email links before making them the only way in

Use email links or codes as the only sign-in for low-risk accounts only. Bind each link to the browser that asked for it, and offer a passkey after the first sign-in.

How to do it

An email link proves access to an inbox, not who someone is. NIST SP 800-63B-4 section 3.1.3.1 forbids email for out-of-band authentication. Mail also arrives late, lands in spam, or opens on a phone when sign-in began on a laptop. Set a random cookie in the browser that asks. When the link opens in a browser without that cookie, show a 6-digit code to type in the first browser instead of signing in. Make the token as the sign-in links rule says. Require a passkey or second factor for admins and accounts that hold money or business data.

Example

app.get('/sign-in/link', async (req, res) => {
  const request = await signInRequests.findUnusedByTokenHash(sha256(req.query.token));
  if (!request) return res.status(410).render('link-expired');
  const sameBrowser = safeEqual(req.cookies.signin_nonce ?? '', request.browserNonce);
  res.render(sameBrowser ? 'confirm-sign-in' : 'type-this-code', { code: request.code });
});
@app.get("/sign-in/link")
def open_sign_in_link():
    sign_in = sign_in_requests.find_unused_by_token_hash(sha256(request.args["token"]))
    if sign_in is None:
        return render_template("link-expired.html"), 410
    same_browser = hmac.compare_digest(request.cookies.get("signin_nonce", ""), sign_in.browser_nonce)
    page = "confirm-sign-in.html" if same_browser else "type-this-code.html"
    return render_template(page, code=sign_in.code)

How to check

Ask for a link in one browser and open it in another. The second browser is not signed in and shows a code. Typing the code in the first browser signs it in.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers accounts playbook: https://agentwranglers.se/playbook/accounts/sign-in-methods/email-sign-in-trade-offs.