Abhishek Jakhar

IDV as 2FA at Coinbase

2021–2022

Usually 2FA is a code from a text, an authenticator app, or a hardware key. But if the phone is lost, or a login looks suspicious, all of these fail. At Coinbase I made identity verification a second factor for exactly those cases.

Coinbase already asked for a passport, a national ID, or a photo at sign-up. We needed that same identity verification as a second factor in exactly those cases. Otherwise, users had to wait five days to get back into their account.

Document capture already lived in the old sign-up app. The 2FA work happened in a different, newer frontend monorepo, and I could not import the old screens: they were tightly coupled to old libraries and an old version of React, written as class components. So I pulled document capture into its own package, cut the old dependencies, moved it to the new design system library and a newer React with hooks, and installed it in the new app.

What I built

A new React package for document capture:

The existing auth path assumed a credential that only exists after 2FA, and this flow was the 2FA. The package stops at the verification id. Sign-in owns the wait, then lets the person in or asks them to set up 2FA again.

The steps, the ID types on offer, and the two ways to capture.
The camera with autocapture on, the photo back to use or retake, and then the selfie.
The wait, and the result.
A computer with no camera hands off to a phone: the desktop shows a code, waits, and lets you take it back.
The same screens on a phone.

Where it shipped

It went live on Coinbase sign-in and account recovery in 2022. That is the IDV as 2FA path: if you lost your authenticator, or a login looked risky, you proved who you were and you were back in.

The same library later became one of the web captures for onboarding too. By 2025 its consumers were sign-in 2FA, account recovery, and onboarding.

Outcome

The feature is still in production. Sign-in and account recovery still treat identity verification as a second factor. A locked-out user gets back in under a day instead of waiting five.

The library I built ran for four years, from 2022 to 2026. In April 2026 it was retired and marked deprecated, replaced by a package with the same API, a new name, and new internals. I shipped the first web capture library that made this flow possible.

What I learned