I understand that FIDO2/WebAuthn generates a separate key-pair for each web-site (domain), and only allows a specific key-pair to be used for authentication on the same web-site (domain) who originally generated/registered that key-pair with the browser/authenticator. Also, I'm aware that this is done in order to prevent Man-in-the-Middle and "Phishing" attacks.
Generating an independent key pair per site—and per account at the site—isn't about defeating MITM or phishing attacks.
An independent key pair per registration is critical for privacy, to prevent webauthn from becoming yet another method of tracking users across sites.
This makes it safe to use one device (plus a backup!) for as many sites and accounts as you want—work, personal, &c.—without turning webauthn into a passive instrument of mass surveillance.
No need to carry around a keyring full of devices for different purposes.
The advantage of the above approach would be that we don't need tons of separate key-pairs for the same user. Keep in mind, that most FIDO2 devices (e.g. YubiKey) can only store a few...
There is no limit to the number of key pairs that can be ‘stored’ by a U2F/FIDO device for normal webauthn registrations, because the device doesn't actually store the key pairs at all!
Instead, the device need only store one master secret key, say $k$.
This is typically used in one of two ways with credential ids (‘key handles’, in older U2F nomenclature):
A credential id is $s \mathbin\Vert A_k(s)$, where $s$ is a uniform random byte string and $A_k$ is a symmetric authenticator (e.g., AES-GMAC).
(This is how Solokeys work (steps (1), (2), (3), (4)) and how older Yubikeys work (older reference).)
A credential id is $E_k(s \mathbin\Vert m)$, where $s$ is a uniform random byte string, $m$ is some metadata, and $E_k$ is an authenticated cipher (e.g., AES-GCM).
(This is how newer Yubikeys and Yubico security keys work (newer reference).)
In both cases, the key pair is derived from the seed $s$ stored in the credential id, using the device's master secret key.
The key pairs are not actually stored on the device; the device derives them on the fly from the credential ids stored on the server.
Of course, you could design a FIDO device badly so that it does store a key pair for each site it has registered.
But U2F/FIDO was designed from the start to make such a bad design unnecessary.
You may be thinking of resident keys, also known as discoverable credentials.
Resident keys do have the limitations you mention.
They also require special software configuration tools, have poor software compatibility, require PINs, and generally make the user experience abysmal—which hurts security.
Fortunately, resident keys are normally not used in FIDO2/webauthn.
You will usually encounter resident keys only in ill-conceived enterprise deployments, or if you go out of your way to inflict the trouble on yourself.
For example, you can use resident keys with OpenSSH ssh-keygen
, but ssh-keygen -t ecdsa-sk
works fine to make non-resident FIDO ssh keys—no need for resident keys with ssh unless you want to make life difficult for yourself.
You won't accidentally hit any limit on the number of normal webauthn site registrations, because there is no such limit for any serious FIDO device on the market.