In this article
October 19, 2026
October 19, 2026

Stop using phone numbers as a primary key

Android now verifies the handset's number and adds it to every Google account signed in on that device. A verified phone describes a SIM, not a person, so don't key customer identity on it.

Explore with AI
Open in ChatGPT
Open in Claude
Open in Perplexity

A phone number is a poor user identifier because it belongs to a SIM, not a person: numbers are shared, recycled by carriers, and, on Android, now attached automatically to every Google account signed in on the same device. Store phone numbers as contact data and key identity on an internal user ID.

Android verifies the number in your handset in the background and adds it to every Google account signed in on that device, including ones you add later. Google's Android help page states it plainly: "We verify the phone number and add them to all Google Accounts that are signed in on the device. This applies to both current and future accounts and phone numbers."

If your users table has a UNIQUE constraint on a phone column, that sentence describes a bug you've already shipped. A verified phone number records that a SIM in a handset answered a challenge. Which person holds the handset, and how many accounts they keep signed in on it, is outside the frame. Phone numbers are contact data. Use one as a primary key, as the value you link accounts on, or as the only anchor for account recovery, and your user table starts to mirror the SIM market.

Diagram of Android phone number verification. One Android device with one SIM is verified once, and its phone number is added to every Google account signed in on the device: a personal account, a work account, a secondary profile, and any account added later.
Verification happens at the device. Every account signed in on that handset inherits the result.

What does Android's phone number verification do?

Google's Android help page describes a device-wide behavior. Phone number verification "is turned on by default," the number is verified and added to all Google accounts signed in on the device, and the rule covers both current and future accounts and numbers. Add a new account and it picks up the device's number; add a new number and it lands on every account. The setting is in the device's Settings app, under Google, All services, Privacy & security, Phone number verification.

Android Authority reported on October 14, 2026 that Google's support documentation changed between August and October 2025 to describe this default-on behavior, and that the linking reaches secondary profiles, work accounts and throwaway accounts signed in on the same phone. Users reported confirmation emails arriving unprompted from noreply-phone-verification@google.com. Turning the setting off only stops future linking; numbers already attached have to be removed by hand from each account's Personal info page, under Contact info and Phone.

Nothing in that documentation says your application receives a user's number through Google sign-in, and we're not claiming it does. The point is narrower and more durable: the assumption behind phone-as-identity, that one number means one person who deliberately gave it to one account, is now visibly false on the platform that runs most of your customers' phones.

Why does a phone number belong to the SIM, not the person?

Numbers are a leased, recycled, regulated resource. In the US, the FCC requires carriers to "age telephone numbers for at least 45 days after permanent disconnection" before reassigning them, and to report permanent disconnections to the Reassigned Numbers Database on the 15th of every month. As of February 17, 2023, that database held over 305.9 million geographic and toll-free numbers. Reassignment is a normal, national-scale, monthly part of how the phone network runs.

Kevin Lee and Arvind Narayanan at Princeton measured what that churn leaves behind. Of 259 numbers available to new subscribers at Verizon and T-Mobile, 171 were still tied to existing accounts at popular websites, open to takeover through SMS-based recovery by whoever got the number next. About two thirds returned hits on people-search services exposing the previous owner's details. And 100 were tied to email addresses found in password breaches, which could let an attacker get past SMS-based two-factor authentication. The study was presented at the APWG Symposium on Electronic Crime Research in 2021.

Sharing is the same problem in the other direction, and standards bodies treat it as normal. NIST SP 800-63B-4 says that in public-facing applications, providers "should not prevent a device from being registered as an authenticator by multiple subscribers," because people share devices such as a family phone. A number that several people legitimately control can't also be the value that tells them apart.

How does a phone key break a customer identity schema?

  • ‍Signup collisions. A UNIQUE constraint on a phone column turns every shared and recycled number into a failed registration. The second person on a family plan, the contractor using a company handset, the new owner of a recycled line: each hits a conflict on a value they genuinely control. Support has one way out, and takes it. They strip the number off the older account and attach it to the new one, and nobody notices it mattered until the first account needs it for recovery.‍
  • Merges across customer accounts. In B2B it's worse, because the same person is deliberately two people. An engineer with a work profile and a personal profile on one Android phone now has the same verified number on both Google accounts. Any logic that links or deduplicates on phone will fuse a company's record with a personal one. Then someone has to pull a customer's audit log, billing history and role assignments back out of a personal account by hand, and explain to their security team how the two ever touched. Stop using email as a primary key covers the email version of this failure; phone has every one of those problems, plus carrier reassignment.‍
  • Identity that drifts with the hardware. A number verified today describes a SIM and handset today. NIST treats "setting or changing the pre-registered telephone number" as binding a new authenticator, not editing a profile field. If your model stores the number as the identity, there's no event to fire when it changes hands, because the row still looks correct.

How do attackers take over accounts through a recycled number?

Walk through the recycled-number case as a sequence, because that's how it gets exploited:

Five-step account takeover through a recycled phone number. A number is recycled to a new subscriber. The new holder looks up the previous owner with people-search services, requests a password reset, and receives the one-time code because the carrier routes it to the current subscriber. The account is taken over without any bug.
The recovery path follows the number. Whoever holds it next inherits every account anchored to it.

Someone gets a recycled number. They look up the previous holder, which works with ordinary people-search services for most available numbers, and find live accounts still tied to it. They request a password reset. Your system sends a one-time code to the number on file, and it arrives on their phone because the carrier, correctly, routes it to the current subscriber. NIST caps that code's validity at 10 minutes, which is plenty. Possession of the number was the whole test, and they possess the number.

Nobody misconfigured anything. The flow assumed that possessing a number means possessing an identity. NIST SP 800-63B-4 lists out-of-band authentication over the phone network as a restricted authenticator, currently the only one, and notes that "out-of-band authentication is not phishing-resistant." Accepting a restricted authenticator obliges you to offer at least one unrestricted alternative, give users meaningful notice of its risks, cover it in your risk assessment, and keep a migration plan for the day it's no longer acceptable. NIST also says verifiers should consider risk indicators such as "device swap, SIM change, number porting" before sending a secret over the phone network.

For recovery specifically, NIST's bar at AAL2 is two recovery codes obtained by different methods, or one recovery code plus authentication with a single-factor authenticator already bound to the account, or repeated identity proofing. Every one of those requires something beyond holding the SIM. Google, for comparison, warns that when you add or change a recovery phone number, "it may take up to 7 days for those changes to take effect."

Our view on the channel itself is in Why SMS is not a secure MFA method, and the carrier-side attack is in the SIM swapping guide. The account-model consequence is what teams skip: even a perfectly delivered SMS to a correctly routed number only proves possession of a SIM, and your recovery flow decided long ago that possession was enough.

What should you key identity on instead?

Fixing this is a schema change, not a feature flag. Identity is an internal user ID, linked to federated logins by the issuer and subject pair the token already gives you. Phone numbers hang off that record as contact rows with provenance and a timestamp.

  
CREATE TABLE users (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Federated logins resolve to a user. The issuer + subject pair is the identity.
CREATE TABLE identities (
  user_id   UUID NOT NULL REFERENCES users(id),
  issuer    TEXT NOT NULL,   -- the OIDC iss
  subject   TEXT NOT NULL,   -- the OIDC sub
  PRIMARY KEY (issuer, subject)
);

-- Phone numbers are contact data: several per user, and the same number
-- can legitimately reach different users at different times.
CREATE TABLE phone_numbers (
  id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id       UUID NOT NULL REFERENCES users(id),
  e164          TEXT NOT NULL,
  verified_at   TIMESTAMPTZ,   -- when possession was last proven
  verified_via  TEXT,          -- which challenge proved it
  released_at   TIMESTAMPTZ,   -- set when we stop trusting this binding
  UNIQUE (user_id, e164)
);
  

The uniqueness constraint is (user_id, e164), so a number can appear on more than one account without a failed registration, and no row treats the number as a name. verified_at does the work downstream: possession proven eight months ago, on a SIM that has since been swapped, isn't possession proven now.

Diagram of the recommended identity model. An internal user ID is the key that never changes. Federated identities, each an issuer and subject pair, attach to it. Phone numbers attach as contact data with the time possession was last verified: one verified two days ago, and one verified eight months ago that should no longer be trusted for recovery.
The key never moves. Phone numbers hang off the record as contact data, each with a record of how recently possession was proven.

That makes the lookup rule simple. A phone number is a hint about which account someone might mean, never the answer to who they are.

  
// Never resolve a user from a number alone.
const candidates = await db.phoneNumbers.findMany({
  where: { e164, releasedAt: null },
});

if (candidates.length !== 1) {
  // A family handset, or a work and personal profile on one device.
  // Ambiguity here is normal, not an error state.
  return askForAccountIdentifier();
}

// Exactly one candidate still only proves the number reaches this account.
// Recovery needs a second, independent factor before anything changes.
return offerRecoveryChallenge(candidates[0].userId);
  

Three rules follow:

  • Never link or merge accounts because their phone numbers match. Link only inside an authenticated session, where the user is signed in and confirms it.
  • Expire verification. Don't treat it as permanent, and clear it on the signals NIST names: device swap, SIM change, number porting.
  • Make recovery require something the SIM holder doesn't automatically get: a second verified channel, a bound authenticator such as a passkey, or identity re-proofing.

The constraint to go delete

Run one query against your production schema: look for a UNIQUE index on a phone column, or a lookup that resolves a user from phone = ?. If either exists, Google just widened its blast radius on every Android device your customers own. The number is still worth storing. It's good for reaching people, useful as a signal, and acceptable as one factor among several. What it can never do is stand in for the person. If that query returned rows, the migration is the three tables above, and that's where to start.

If you use AuthKit, users already have a stable WorkOS user ID, and sign-ins from SSO and social providers are linked to it, so your own tables can key on that ID and treat phone and email as attributes. For moving recovery off SMS, Passkeys stop phishing. Your MFA fallbacks undo it. covers what to offer instead.