WebAuthn: Is it possible to filter passkey authenticators?

264 Views Asked by At

We use passkey in application and we want to restrict Passkey only by Google, Apple, Microsoft authenticators is it possible to do that? Because for example right now Android show me 1Password like a default authenticator.

Create call looks like this right now:

{
  "challenge": "nhkQXfE59Jb97VyyNJkvDiXucMEvltduvcrDmGrODHY",
  "rp": {
    "name": "CredMan App Test",
    "id": "credential-manager-app-test.glitch.me"
  },
  "user": {
    "id": "2HzoHm_hY0CjuEESY9tY6-3SdjmNHOoNqaPDcZGzsr0",
    "name": "[email protected]",
    "displayName": "[email protected]"
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 1800000,
  "attestation": "none",
  "excludeCredentials": [],
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}
2

There are 2 best solutions below

7
On BEST ANSWER

No, this is not possible with creation parameters, by design.

Why do you want to restrict authenticators? What is a user supposed to do if they don't have access to an authenticator that you allow? Will you keep them on a phishable sign in method?

5
On

Yes, it is possible. However, not purely through a WebAuthn based create request like you have included in your question.

FIDO2

WebAuthn in itself is a part of the FIDO2 standards. WebAuthn is the standard for how to implement FIDO2 in Web Applications and covers both server, referred to as Relying Party, and Clients. Authenticators are then covered by CTAP letting both communicate with each other.

WebAuthn

How one triggers the create request for WebAuthn varies a bit but I'll assume we are doing this through navigator.credentials.create(...) in a browser. The rest of the answer doesn't really change depending on this.

As the create is a client side request you don't have a lot of restrictions possible to you, which is why it is impossible to actually purely restrict it through the client side, as faking client side data to circumvent security restrictions is in general trivial. So we must use the relying party to determine if we accept the key created or reject it.

So we would need to validate if we want to accept this on the Relying Party. First thing that would need changing in your request is that you'd require a attestation with the key being generated. This can be done by setting Attestation to direct in your request.

When the request finishes and you have generated a key you'll get back an attestationObject which first of all will include something called attStmt. The attStmt contains a certificate from the authenticator used to be able to validate its authenticity.

You also have another part of the response that is authData which in turn has attestedCredentialData which in turn has a aaguid field containing the unique identifier of the authenticator used.

With this info, your Relying Party can validate that the certificate is authentic and that the aaguid matches whatever whitelist you might have. Or doesn't match any blacklist you might have.

FIDO2 Metadata Blob

Now the above is a bit limited as you'd need to maintain your own list of approved authenticators. However, FIDO Alliance also hosts a metadata blob . More info on the actual blob can be found here.

The metadata blob itself contains all certified FIDO authenticators including the aaguid and the certificate for each. So validating that one truly used the authenticator would be as simple as validating the certificate towards the aaguid. The metadata blob is also maintained so if there is new authenticators from producers you trust/distrust the could easily be added to any whitelist/blacklist.

TL;DR

Set your request to include attestation by changing "attestation": "none" to "attestation": "direct". Then on your server side use the Fido metadata blob to validate the certificate and aaguid returned from the credential creation on your server and reject/approve them as fits your setup.