Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: passkey support #330

Open
tavrez opened this issue Oct 9, 2023 · 11 comments
Open

Feature request: passkey support #330

tavrez opened this issue Oct 9, 2023 · 11 comments
Labels
feature request New feature request

Comments

@tavrez
Copy link

tavrez commented Oct 9, 2023

Using Pass as passkey provider is a huge win, if you are interested, we can start creating a specific format for storing passkeys inside Pass files and use them with this extension. What do you think?

@erayd
Copy link
Collaborator

erayd commented Oct 9, 2023

Potentially keen. Can you provide a bit more info on the kind of workflow you're suggesting?

@erayd erayd added the feature request New feature request label Oct 9, 2023
@tavrez
Copy link
Author

tavrez commented Oct 24, 2023

Ok, it was a bit long I needed time to manage and write it

Intro

Passkey is actually webauthn, so lets first recap how it works

There is a web api called webauthn, which is for managing different authentication methods, one of those methods is public-key, which is what we need to cover, browser get the webauthn function call from websites and uses CTAP(or an API from OS which calls it) to connect to the security devices.

So we have two options here:

  1. Create a CTAP like interface for Pass, and add a feature to browserpass extension to call it.
  2. Directly write and read data from Pass and handle signing and generating the data by the extension.

First way is more complex but future proof, second way is easier so I suggest starting with the second way.

What to do

  • What we have to do is to monkey patch calls to webauthn apis(like navigator.credentials.create) and if the parameters are correct for Passkey, invoke a dialog and process or if its not, call the original method.

  • We also need to specify a format for storing Passkey data inside Pass files, this also needs to be discussed.

  • There are lots of flags and extensions to the webauthn, we can start simple first and then add them later.

How can I help

  1. I know the details of webauthn and CTAP protocols and I can help writing codes to create keys and sign challenges with them(with web crypto api for example)
  2. I don't know anything about writing browser extensions :D

Process

  1. Monkey-patching navigator.credentials.create, navigator.credentials.get, PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable, PublicKeyCredential.isConditionalMediationAvailable
  2. Creating a format inside Pass file
  3. Creating related dialogs in the extension(save passkey, ...)
  4. Adding support for flags like(UP,UV,...)
  5. Adding support for extensions of webauthn(credprot, blob,...)
  6. Adding support for conditional mediation
  7. Making Pass a hybrid CTAP authenticator(I believe this should be done inside pass itself, but I just write it here for visibility)

Good First Steps to Start

  1. For now lets just patch navigator.credentials.create in simple form:
    • Check parametes and answer only when needed
    • When the parametes are correct invoke a dialog and offer to save the Passkey
    • Create the actual data inside Pass file

Well thats it, you probably have lots of question and I'm sure I did not write this very well, so let me know what you need to know more and tell me from where we can start :)

@maximbaz
Copy link
Member

maximbaz commented Dec 6, 2023

Hi @tavrez!

We had a few internal discussions about it, but never ended up posting here a reply, sorry about that!

Would we like to explore idea this further?

Absolutely!

Should we make an extension for pass and call it from extension?

No, because extension is not dependant on pass today, we use directly gpg to decrypt files. Putting the code into extension is therefore not only easier as you suggest, but actually preferrable!

Next steps

You have a nice set of ideas for the process and good first steps. I hope our silence hasn't discouraged you from contributing?

Monkey patching Webauthn APIs and coming up with a format to store this in pass file is great first step. I'd even consider getting that to work without spending too much time on designing the necessary UI components - in the beginning we can add the necessary content to the pass file by hand. Let's get some proof of concept working, and make a way to save/edit passkeys in the next iteration? How does this sound to you?

Small single-focused PRs are easier to review and merge (especially in this case, as it won't affect existing users), and perhaps the best way forward. Let me know if you want to get started on the first PR!

On a practical side, it would be nice not to touch native host, but implement everything in the extension - upgrade path for the extensions is a lot easier than upgrading native host, so we tend to only modify it if absolutely necessary.

If you have any questions, or want feedback on anything in particular, please do not hesitate to post here!

@tavrez
Copy link
Author

tavrez commented Dec 8, 2023

Glad to hear back from you!
I'll start writing a function which should replace the browsers built-in functions and create a initial PR at my first free time.
Since I don't know how to monkey-patch with extensions, you probably should place my function is somewhere correct

@renehsz
Copy link

renehsz commented Dec 23, 2023

Hi! I just wanted to point out that the folks at KeePassXC have already implemented WebAuthn/PassKey support and there's issue keepassxreboot/keepassxc#1870 and PR keepassxreboot/keepassxc-browser#1786 that give very interesting insights on how they did it. The monkey patching in Browserpass could be similar.

@WIcheese
Copy link

This is not what passkeys were meant for... they are supposed to be protected by hardware and non-exportable - and if the keys are escrowed (non-device-bound passkeys), they are escrowed on a HSM farm like Apple and Google have in their datacenters for this purpose, and private keys only ever transit any links when you create or recover them - and since they are on HSMs even on the provider's end, your weak phone PIN or human memorized password is protected by a limit of ~10 tries.

The route KeePassXC and now potentially Browserpass are going is very different. Any time it's used, the private key gets decrypted and loaded into RAM memory and used to perform a cryptographic operation (sign an assertion) in the main CPU. This is a far cry from only existing outside TPM/HSM at the moment of backup or restore to a cloud account, in terms of the strength of the guarantee that it has not been copied even if you clicked on malware.

Passkeys are supposed to be idiot-proof, and TPM or some other form of smartcard-like technology is necessary to prevent the taking of a permanent copy of credentials if a user has fallen for a scam or malware at any past point. Producing things that claim, in talking to relying parties, to be "passkeys" and do not actually offer the guarantees passkeys offer, is poisoning the ecosystem. When someone gets their Pass private key compromised and later learns the attackers made off with a persistent copy of all their Passkeys (which are supposed to be immune to such things) it scares people and companies away from passkeys.

@erayd
Copy link
Collaborator

erayd commented Mar 27, 2024

@WIcheese You make valid points. Ultimately though, it's up to the user how they wish to handle their own security situation. Remember that browserpass does not target laypeople; it's very specifically a pgp-based credential manager. Similar arguments apply to TOTP, which we also support.

Remember also that many browserpass users are in fact using a hardware token for decryption; the assertion that the private key is sitting in system memory is not necessarily accurate.

@WIcheese
Copy link

WIcheese commented Mar 28, 2024

@erayd

Remember also that many browserpass users are in fact using a hardware token for decryption; the assertion that the private key is sitting in system memory is not necessarily accurate.

I am aware of this; I personally use a YubiKey with touch required for each decryption. However, pass or browserpass isn't going to manage the YubiKey's FIDO2 function and enroll passkeys directly with the YubiKey, nor will the OpenPGP function store a separate key per Passkey or sign FIDO2/WebAuthn assertions on-key... that would defeat the purposes of using a password manager (such as overcoming the limit on the number of discoverable credentials, or ensuring that you can recover when you lose your YubiKey as long as you have an airgapped backup of your GPG key).

So even though the keys to your entire pass repository may not exist in memory at any time, when you use a Passkey (which in itself is a public/private key pair), the private key of that specific Passkey is going to have to be in memory. Your software implementation of FIDO2/WebAuthn, not backed by TPM, is going to be signing the assertion. That passkey is 100% as copyable/exportable as a regular password.

In an ideal world I agree, users should have the option to take that risk. However, many developers want to use Passkeys for their products because they are more "idiot-proof" (phishing resistant, and resistant to persistence / credential export). They prefer it over TOTP because you CAN'T back up the QR code in some insecure place. WebAuthn and attestation are supposed to provide certain assurances to the relying party.

@Thaodan
Copy link

Thaodan commented Jun 14, 2024

Glad to hear back from you! I'll start writing a function which should replace the browsers built-in functions and create a initial PR at my first free time. Since I don't know how to monkey-patch with extensions, you probably should place my function is somewhere correct

Does this apply to all browsers? Some provide API's for extensions to be passkey handlers:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

@Thaodan
Copy link

Thaodan commented Jun 14, 2024

@erayd

Remember also that many browserpass users are in fact using a hardware token for decryption; the assertion that the private key is sitting in system memory is not necessarily accurate.

I am aware of this; I personally use a YubiKey with touch required for each decryption. However, pass or browserpass isn't going to manage the YubiKey's FIDO2 function and enroll passkeys directly with the YubiKey, nor will the OpenPGP function store a separate key per Passkey or sign FIDO2/WebAuthn assertions on-key... that would defeat the purposes of using a password manager (such as overcoming the limit on the number of discoverable credentials, or ensuring that you can recover when you lose your YubiKey as long as you have an airgapped backup of your GPG key).

How you secure your key depends on your pgp program and not on pass.

So even though the keys to your entire pass repository may not exist in memory at any time, when you use a Passkey (which in itself is a public/private key pair), the private key of that specific Passkey is going to have to be in memory. Your software implementation of FIDO2/WebAuthn, not backed by TPM, is going to be signing the assertion. That passkey is 100% as copyable/exportable as a regular password.

How can you prov this claim? Given that many users of pass use a smartcard the private isn't in memory but is stored on the smartcard, you can extract keys from smartcards.
Keys can be stored on a TPM if the user chooses to do so. TPM's are another can of worms but that topic
is offtopic.

In an ideal world I agree, users should have the option to take that risk. However, many developers want to use Passkeys for their products because they are more "idiot-proof" (phishing resistant, and resistant to persistence / credential export). They prefer it over TOTP because you CAN'T back up the QR code in some insecure place. WebAuthn and attestation are supposed to provide certain assurances to the relying party.

As others said given the nature of pass or this extension muss is given to the choice of the user to decide how secure they want their credentials to be. Since pass can use smarcards the credentials
can be stored much safer than on any other desktop solution or in some ways even smartphone solution
as a TPM is usually tied to the specific device.

I also want to add that pass gives the user better control to manage their credentials between applications than any builtin browser or solution of a closed source operating system can ever give.

@erayd
Copy link
Collaborator

erayd commented Jun 14, 2024

How you secure your key depends on your pgp program and not on pass.

Yes, but remember that the PGP key isn't the only one we're talking about here; the private key for the passkey would be managed by Browserpass. @WIcheese is correct in their assertions about that part of it.

In particular, note this part:

...when you use a Passkey (which in itself is a public/private key pair), the private key of that specific Passkey is going to have to be in memory. Your software implementation of FIDO2/WebAuthn, not backed by TPM, is going to be signing the assertion. That passkey is 100% as copyable/exportable as a regular password.
@WIcheese


How can you prov this claim?

Because Browserpass would by necessity be handling the key material for the passkey. The very existence of the functionality necessarily implies having the private key for the passkey somewhere that Browserpass can get at it, which means it is sitting in RAM somewhere.

As others said given the nature of pass or this extension muss is given to the choice of the user to decide how secure they want their credentials to be.

Yes. As per TOTP secrets.

Since pass can use smarcards the credentials can be stored much safer than on any other desktop solution or in some ways even smartphone solution as a TPM is usually tied to the specific device.

For the PGP key, yes. For other keys (e..g passkey private, TOTP secret etc), no.

I also want to add that pass gives the user better control to manage their credentials between applications than any builtin browser or solution of a closed source operating system can ever give.

No. You may prefer Browserpass, but that does not automatically make it superior. As with any field, picking the correct tool for the job matters. Browserpass fits a few very specific niches, but there are many areas in which it is not, in fact, the option which "gives the user better control to manage their credentials".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature request
Development

No branches or pull requests

6 participants