The policy decided on #332, written down in code and pinned by tests. Small, and the most security-sensitive phase in the project.
The rule, in order
An identity row matches. Sign in. Nothing else is consulted.
No identity row, Google asserts email_verified: true, and a customer exists with that exact address. Create the identity against that customer and sign in.
No identity row, Google does not assert a verified address, and a customer exists with that address.Refuse. Send them back to the password form with a message saying to sign in the way they usually do.
No identity row and no matching customer. Create both, as #342 does.
Step 1 comes before the email comparison deliberately. An identity that has signed in before keeps working even if the address on either side has since changed.
Why auto-linking is safe here and only here
Google verifying the address means whoever completed that sign-in demonstrably controls the mailbox, which is already the root of trust for every other route into the account. Never link on an unverified address — that is a takeover path, and it is why this is a written rule rather than a default that arrives with a library.
Also in scope
Normalise the address the way registration does — lowercased and trimmed. A stricter comparison silently fails to link and produces a duplicate account instead of an error anyone sees.
Say what happened. Show the linked Google account on the account page, where the passkeys are listed. A silent link is indistinguishable from a bug when the customer later wonders why the password is no longer needed.
Done when
All four branches have a test; an unverified Google address never links; and linking is visible to the customer afterwards.
Part of #332. Phase 4 of six. Depends on #342.
The policy decided on #332, written down in code and pinned by tests. Small, and the most security-sensitive phase in the project.
## The rule, in order
1. **An identity row matches.** Sign in. Nothing else is consulted.
2. **No identity row, Google asserts `email_verified: true`, and a customer exists with that exact address.** Create the identity against that customer and sign in.
3. **No identity row, Google does not assert a verified address, and a customer exists with that address.** **Refuse.** Send them back to the password form with a message saying to sign in the way they usually do.
4. **No identity row and no matching customer.** Create both, as #342 does.
Step 1 comes before the email comparison deliberately. An identity that has signed in before keeps working even if the address on either side has since changed.
## Why auto-linking is safe here and only here
Google verifying the address means whoever completed that sign-in demonstrably controls the mailbox, which is already the root of trust for every other route into the account. **Never link on an unverified address** — that is a takeover path, and it is why this is a written rule rather than a default that arrives with a library.
## Also in scope
- **Normalise the address the way registration does** — lowercased and trimmed. A stricter comparison silently fails to link and produces a duplicate account instead of an error anyone sees.
- **Say what happened.** Show the linked Google account on the account page, where the passkeys are listed. A silent link is indistinguishable from a bug when the customer later wonders why the password is no longer needed.
## Done when
All four branches have a test; an unverified Google address never links; and linking is visible to the customer afterwards.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #332. Phase 4 of six. Depends on #342.
The policy decided on #332, written down in code and pinned by tests. Small, and the most security-sensitive phase in the project.
The rule, in order
email_verified: true, and a customer exists with that exact address. Create the identity against that customer and sign in.Step 1 comes before the email comparison deliberately. An identity that has signed in before keeps working even if the address on either side has since changed.
Why auto-linking is safe here and only here
Google verifying the address means whoever completed that sign-in demonstrably controls the mailbox, which is already the root of trust for every other route into the account. Never link on an unverified address — that is a takeover path, and it is why this is a written rule rather than a default that arrives with a library.
Also in scope
Done when
All four branches have a test; an unverified Google address never links; and linking is visible to the customer afterwards.