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

FIDO U2F/WebAuthn abstraction/permission/portal/… #989

Open
rugk opened this issue Mar 19, 2019 · 56 comments
Open

FIDO U2F/WebAuthn abstraction/permission/portal/… #989

rugk opened this issue Mar 19, 2019 · 56 comments
Labels
new portals This requires creating a new portal interface

Comments

@rugk
Copy link

rugk commented Mar 19, 2019

IMHO what is missing as a todo item for the sandbox, is FIDO U2F/WebAuthn abstraction for USB devices.

Problem

User story: I, as a user of a flatpak'ed browser, want to be able to login with my cool U2F/WebAuthn keys, because they are very convenient & secure & with increased adoption I may also be able to use a passwordless authentication.

So one could do so when you enable the --device=all permission, but obviously (for isolation/sandboxing reasons, i.e. security reasons) one does not want to expose all USB devices to a browser application.

WebAuthn spec has recently been finalized: https://www.w3.org/TR/webauthn/

Support for U2F/WebAuthn is available in major browsers like Firefox and Chrome/ium.

Proposed solution

Another special abstraction (and permission) for U2F/WebAuthn access.

Actually, the security and isolation-focused distro Qubes OS does already have developed a model, abstraction and even software that can be used in their distro to abstract that: https://www.qubes-os.org/doc/u2f-proxy/
source code: https://github.com/QubesOS/qubes-app-u2f

The doc is really worth a read!

So maybe some kind of new portal? Or new permission?

Also discussed at

Other useful links

https://en.wikipedia.org/wiki/Universal_2nd_Factor
https://en.wikipedia.org/wiki/WebAuthn

(sponsored sites, but visibly nice)
https://webauthn.guide/
https://webauthn.io/

@rugk rugk changed the title FIDO U2F/WebAuthn abstraction FIDO U2F/WebAuthn abstraction/permission/portal/… Mar 19, 2019
@rugk
Copy link
Author

rugk commented Jul 25, 2019

Any official reply? Are you evaluating this or what?

4 users have already upvoted this, and the issues that it causes come up again and again. And as I think the prevalence of WebAuthn/hardware keys or similar will only increase in the future, this topic/problem will likely come up/get bigger again and again.

@rugk
Copy link
Author

rugk commented Sep 7, 2019

Cross-posted to the GNOME Discourse forum.

@TingPing
Copy link
Member

Since you seem quite passionate about this portal its likely going to come down to implementing it yourself.

@rugk
Copy link
Author

rugk commented Oct 11, 2019

If you look at https://github.com/QubesOS/qubes-app-u2f you'll see this may certainly not be easy.

@TingPing
Copy link
Member

I did glance over it and yeah it is very complex. I'm not super familiar with U2F but it seems deeply tied to USB which makes things harder.

@swick
Copy link
Contributor

swick commented Apr 7, 2020

I'm also interested but have not looked much into it. Does the browser have to use the CTAP spec? Can we not "just" have a daemon on the host talking CTAP with the devices and expose a simpler, more WebAuth-like API through a portal?

@ueno
Copy link
Contributor

ueno commented Apr 7, 2020

Hi Sebastian, that sounds reasonable. I have recently been working with a student who is trying to expose CTAP2 through D-Bus for similar purposes, and asked the developer of authenticator-rs about the possibility of future integration; adding it as an alternative transport seems to be an option, once the multiple transport support is implemented in the library.

That said, we haven't even figured out how the D-Bus protocol would look like. Perhaps we could collaborate on the design and implementation? :-)

@rugk
Copy link
Author

rugk commented Apr 7, 2020

BTW with the official release of a Firefox flatpak on Flathub, this is getting much more important now. 😃

@barthalion

This comment has been minimized.

@WayeeCool

This comment has been minimized.

@swick
Copy link
Contributor

swick commented Apr 9, 2020

That said, we haven't even figured out how the D-Bus protocol would look like. Perhaps we could collaborate on the design and implementation? :-)

I'm afraid that I can't help much with that without diving into the protocols but it should not be too hard when you already have a solid, simple C interface.

@AlfioEmanueleFresta
Copy link

I agree - we certainly need a portal for FIDO authentication. However, I think this should expose the new FIDO2 interface, rather than CTAP. FIDO2 is a relatively simple API, and it can be used with CTAP2 authenticators, platform authenticators, and can also be mapped to CTAP1 U2F following the WebAuthn spec.

There is precedent for this approach on other platforms, including Android's Fido2ApiClient and the Windows Hello FIDO2 Win32 API.

Furthermore, a FIDO2 portal API would also enable another very important missing bit of functionality: platform authenticators. Think of Windows Hello's built-in authenticator - I believe this would be instrumental for the shift to passwordless authentication.

I have started working on a proposal for a new FIDO2 portal, xdg-credentials-portal. I would like to start with a D-Bus portal API specification, and FIDO U2F (CTAP1) support, backed by authenticator-rs. Please get in touch if you'd like to contribute, or if you have any feedback.

@ueno
Copy link
Contributor

ueno commented Apr 13, 2020

This looks like a great start! A couple of things I would like to suggest are:

  • We probably want to avoid re-serializing RPC (CBOR <-> D-Bus), so there should be either coordination with authenticator-rs (which is also used by the Firefox inside a sandbox) to directly use the WenAuthn-like D-Bus interface, or provide direct CBOR API calls through D-Bus
  • The portal should be able to provide access control per device; I guess a natural way to achieve this would be to expose a device as a D-Bus object and provide a device discovery mechanism in the protocol

@swick
Copy link
Contributor

swick commented Apr 13, 2020

@AlfioEmanueleFresta I believe it would be better to separate this into two projects:

  1. a system service which exposes a WebAuthn-like* API that supports CTAP1, CTAP2 and platform authenticators
  2. the actual portal in xdg-desktop-portal which coordinates between the portal backends, the system service from 1 and the permission store or whatever will be required

This has several advantages e.g. we could use the system service to implement a pam module, replace it with another implementation and make slightly different APIs for privileged clients (using the system service) and unprivileged clients (using the portal).

* you say FIDO2 API but afaik FIDO2 is actually two APIs: WebAutn and CTAP2

@AlfioEmanueleFresta
Copy link

AlfioEmanueleFresta commented Apr 15, 2020

Thanks for your feedback @ueno, @swick.

We probably want to avoid re-serializing RPC [...]

A WebAuth-like D-Bus interface is probably ideal for this. authenticator-rs has a similar high-level API (FIDO U2F), and takes care of CTAP1 encoding internally. For FIDO2 devices, authenticator-rs, or the BLE/NFC components, would be responsible for CTAP2 serialisation.

The portal should be able to provide access control per device; [...]

This is the intended behaviour for a WebAuthn call:

  1. Browser within sandbox (e.g. Firefox within Flatpak): proxies the WebAuthn request to the new D-Bus API, using high-level webauthn-like API
  2. xdg-credentials-portal displays some UI to ask the for user confirmation (e.g. "Firefox would like to create new credentials for example.com: [...]")
    • If multiple transports are available, the user is also asked which one they'd like to use (example screenshot).
  3. xdg-credentials-portal calls authenticator-rs using the parameters from the D-Bus request. authenticator-rs will use all available USB devices on the host. Some UI is displayed to the user (example screenshot) whilst the user chooses a security key and touches it (or cancels the operation from the UI)
  4. xdg-credentials-portal converts the successful response to the appropriate WebAuth-like format, which is returned as a signal to the application. The application would not learn about available devices, apart from any device-identifying information required within the WebAuthn response itself. The response returned to the application does not include any transport-specific framing (e.g. HID).

@ueno Does this sound reasonable? Are there any security concerns which aren't addressed by this, and would require explicit per-device permissions, or even require permissions for applications access the API?

I believe that by exposing a Webauthn-like interface via D-Bus, device enumeration functionality would not need to be exposed to client applications, either for permissions, nor pairing/user selection purposes.

Devices would still require a gesture from the user. Most importantly, I believe this to be the current behaviour of authenticator-rs, which does not expose any device enumeration functionality to its consumers - hence changing this may significantly increase the complexity. The parsed contents of the CTAP response, without device metadata would be returned to the sandboxed application.

BLE would be easier - the application would still not have access to devices, and the platform would be responsible for listing, and pairing, available authenticators. This adds a bit of complexity in terms of UI (Chrome on Mac, and Windows Hello both do this, see example screenshot). authenticator-rs does not currently support BLE authenticators. I believe the easiest way to implement this would be using BlueZ's BLE D-Bus API, which does most of the heavy lifting (searching, pairing, listing available and paired devices, BLE GATT functionality).


I believe it would be better to separate this into two projects [...]

@swick I completely agree the new service should eventually be fronted by xdg-desktop-portal.

With regards to having different APIs for different privilege levels (e.g. a D-Bus API and a system service), I'm not yet convinced.

In fact, what Android calls the their privileged API could be made available to all applications, as long as the confirmation dialog is displayed (e.g. Firefox would like to create new credentials for example.org: [...]).

If in the future we crack how to verify associations between origins and the D-Bus API caller, we could introduce the unprivileged API, possibly skipping the confirmation dialog, eg. say the Spotify app tried to create credentials using the verified "spotify.com" origin. However, I have my doubts we would ever be able to verify this, as the Android approach relies on trusting the Play Store to verify the association on behalf of the user.

With phones soon becoming CTAP2/caBLE authenticators for the masses, I think the BLE transport will eventually become more important than U2F/USB. It appears the current best practice for new BLE applications, is to use the BlueZ D-Bus API, which in turn means the system component would also interact with D-Bus. I'm not yet sold on the advantages making the service a system service, resulting in an additional abstraction layer.

  • you say FIDO2 API but afaik FIDO2 is actually two APIs: WebAutn and CTAP2

You're right. I have to admit I like Google's choice to use FIDO2 to refer to the public API, (Fido2ApiClient), but it may be more accurate to use WebAuthn for naming purposes.

@swick
Copy link
Contributor

swick commented Apr 15, 2020

Currently reading through the WebAuthn and CTAP2 specs but that will take some time so I probably have more to say later.

With regards to having different APIs for different privilege levels (e.g. a D-Bus API and a system service), I'm not yet convinced.

When the portal API is used the user interface for the ceremony is provided by the portal backend. When we want to use the same API in a login managed to log a user in (i.e. we don't have a user session and no portals yet) how would that work? Same question for the portal backends: how are they supposed to show you a user interface?

We need to provide some API to those things that allows them to create user interfaces and we can not provide portal users the same API because it gives them information they should not have.

(we really should give those two APIs names. Maybe the platform API and the portal API)

I think you just assumed the platform API to simply be the authenticator-rs API. IMO that would be a mistake because we want to support system authenticators and things like that. How to expose the API I'm really not sure. Just a shared object, system daemon, user session daemon?

In fact, what Android calls the their privileged API could be made available to all applications, as long as the confirmation dialog is displayed (e.g. Firefox would like to create new credentials for example.org: [...]).

That wasn't what I meant with privileged API but it's a good point nevertheless. I don't fully understand why there is two APIs for Android. The only difference seems to be that the privileged one allows you to set the origin. What is the origin in the unprivileged version?

@AlfioEmanueleFresta
Copy link

AlfioEmanueleFresta commented Apr 18, 2020

Got it. Here's a summary, as revised:

  • The portal API should expose high-level WebAuthn (MakeCredentials, GetAssertion) and FIDO U2F (Register, Sign) methods to all applications.
  • The platform API should allow host applications -such as the portal backend- to:

The reason why I believe transport enumeration and transport-specific APIs are required, is that transports have drastically different characteristics:

  • CTAP1/HID and CTAP2/HID do not necessarily require device enumeration, nor pairing (as implemented by authenticator-rs and Chrome)
  • CTAP2/BLE requires device enumeration, discovery, pairing, adapter status (on/off), and may not be available on all devices
    • Some of this could happen out-of-band (ie. requiring users to pre-pair authenticators, or using existing bluez APIs, etc.)
  • CTAP2/caBLE will require device enumeration, discovery and pairing, but it'll likely involve QR codes rather than BLE scanning
  • CTAP2/NFC won't be available on all devices, and may require checking NFC status
  • CTAP2 platform authenticators may have wildly varying requirements (touch the fingerprint sensor, scan your iris, etc.), so each could have its own API

How to expose the [platform] API I'm really not sure. Just a shared object, system daemon, user session daemon?

I will note there is at least one transport which may involve user-specific authenticators: Android phones as CTAP2 over cloud-assisted BLE (caBLE). Unfortunately the spec hasn't been published yet. Additionally, whilst I believe BLE devices are paired to the system's adapter, it may desirable to only show users authenticator devices they've paired themselves (and decouple the concepts of authenticator pairing, and BLE/physical pairing). I'm unsure as to whether this is a point in favour of an user-session daemon, or simply a 'user' parameter for a system daemon/library.

I don't have any strong opinions on library vs daemon. I am now leaning towards a D-Bus daemon, as I've just learned about the Linux NFC D-Bus APIs. This is in addition to the BlueZ GATT D-Bus APIs I've already mentioned for BLE authenticators. Finally, D-Bus introspection (listing available interfaces on a well-known object) would make for a very elegant transport enumeration system.

I don't fully understand why there is two APIs for Android. The only difference seems to be that the privileged one allows you to set the origin. What is the origin in the unprivileged version?

To access the unprivileged API, native Android applications need to declare an origin value within the app manifest, and prove they control the origin by serving a file on their website (the app store verifies the file on behalf of the user).

Accessing the privileged API allows specifying arbitrary origins. However I believe it requires submitting a request for human review to the Play store, to certify the app as a web browser.

@swick
Copy link
Contributor

swick commented Apr 18, 2020

Sounds good! Thanks for explaining how it works on Android. I've noticed a few more things…

  • a system service is not a good idea because it would give access to authenticators of other users
  • it might be easier to put everything into the portal process first and move it to a user session service eventually
  • WebAuthn requires the RP ID to be a valid domain string but a login manager would not be able to specify one. I'm not entirely sure if the authenticator model allows us to use something like linux:pam (i.e. not a valid domain string) for the RP ID?
  • we might be able to combine the privileged and unprivileged APIs (from Android) into one and return an error if the set RP ID is not allowed
  • by default the only RP ID that should be allowed is something like flatpak:$APP_ID (if we don't have to use valid domains; otherwise nothing should be accessible by default)
  • flatpak manifest should offer a way to specify additional RP IDs (for applications like discord, steam, etc) and a way to get access to all valid domains (for browsers)

Does it make sense?

@ItsJamie9494
Copy link

I believe the main reason we had an external service was because it would allow the system to benefit from the shared code?

@ItsJamie9494
Copy link

If we're in agreement to implement most of the code into xdp, I'll get started on something this week

@swick
Copy link
Contributor

swick commented May 11, 2023

I can only speak for myself and still believe it's a good idea. There seem to be some reservations regarding how viable a portal will be to implement in firefox though.

@pinkflames
Copy link

Is there some problem with viewing XDG Desktop Portal as the API to use for the Linux platform? If so, Firefox may consider XDG desktop to be its own platform and target that instead. 😉

@ItsJamie9494
Copy link

@swick that was why we were considering offering a portal on a separate service. However, for now, I think we should try and add it to xdp. If we find that it needs to be separate, we can separate it later. Let’s stick with what’s established for right now

@jadahl
Copy link
Collaborator

jadahl commented May 11, 2023

There seem to be some reservations regarding how viable a portal will be to implement in firefox though.

Got some bugzilla link or something about this? Firefox already depends on portals for some things, so don't get why it couldn't use it for more.

@swick
Copy link
Contributor

swick commented May 11, 2023

Just something I've been told. I have no better information here unfortunately. I'm still all for going ahead with the portal fwiw and will try to help out as much as possible.

@TingPing
Copy link
Member

TingPing commented May 11, 2023

I didn't see it mentioned here but this project also exists, though dead: https://gitlab.freedesktop.org/dueno/fido2-proxy

Personally I found xdg-credentials-portal more promising but I'm not sure of the details.

@ueno
Copy link
Contributor

ueno commented May 11, 2023

There seem to be some reservations regarding how viable a portal will be to implement in firefox though.

Got some bugzilla link or something about this? Firefox already depends on portals for some things, so don't get why it couldn't use it for more.

See the above comment #989 (comment). The 4th bullet point provides a link (note that Firefox's FIDO support goes through authenticator-rs, in case it is not clear). Here is also a previous attempt to integrate the D-Bus service into Firefox.

@ItsJamie9494
Copy link

We can access portals through D-Bus, so I don't see that being an issue?

@msirringhaus
Copy link

Just to quickly chime in with a few links regarding Firefox:
https://bugzilla.mozilla.org/show_bug.cgi?id=1827410
https://bugzilla.mozilla.org/show_bug.cgi?id=1530370#c36

There is no explicit restriction to not use portals, as far as I know.
And there is a lot of effort currently going on (including from myself) to have full CTAP2.1 support in auth-rs.
So at least there is some active development going on in that area at the moment.

@mcatanzaro
Copy link
Contributor

@AlfioEmanueleFresta if you're still around, your input here would be very valuable

@mcatanzaro
Copy link
Contributor

We can access portals through D-Bus, so I don't see that being an issue?

If Firefox blocks Rust code from making networking calls, then that's presumably also going to block D-Bus and most other forms of IPC. Of course that should not have any impact on how we design our APIs. Firefox should either not do that, or not use Rust for this.

@ItsJamie9494
Copy link

ItsJamie9494 commented May 12, 2023 via email

@iinuwa
Copy link

iinuwa commented Jul 18, 2023

Is there a call to action here? From this thread I wasn't sure if someone from Red Hat/Gnome/Flatpak teams were going to take it from here, or whether this was still up for discussion.

I've been working on a platform authenticator implementation on Linux that sort of ties into this discussion. (It's very similar to the work that Daiki Ueno and Norbert Pocs did in fido2-proxy mentioned above.)

It seems that these are some of the open questions:

API Design

Privileged & Unprivileged API (or binding Flatpak WebAuthn origins to their App Id)

I think this comes down to . If portals can lookup the App ID of the caller (in case of Flatpaks; I assume in normal native apps, this is not a thing), then I don't think we need a separate API. We could allow all Flatpak apps to create/read credentials for all credentials in the beginning, and then we could later on enforce that the origin matches some origin derived from the app ID, returning a NotAllowedError if it doesn't. We could also use the same thing to support hosting manifests for other origins over HTTPS if we wanted, though I don't know realistically how many services would add new manifests for Flatpak/Linux users.

Should CBOR-encoding be part of the public API?

Should callers need to know CBOR? This can go either way, but I'm leaning toward passing CBOR data through. Attestation objects returned from created credentials are encoded in CBOR. From the limited persusal that I've done of a few client/server libraries, it seems that most libraries pass through the CBOR data straight through from the client (browser) to the relying party, which would do the CBOR decoding.

There are helper WebAuthn APIs that parse the CBOR data so that web developers don't have to parse it in JavaScript. If browsers want to parse the CBOR to implement those helper APIs, that's fine for them to do. For other non-browser native/Flatpak applications, passing through the CBOR data to the RP is probably sufficient.

This would mean that if we implemented a platform authenticator, we would need to CBOR-encode the attestation objects, but we will likely need a CBOR decoder anyway to support cross-platform authenticators, so I don't think that's a big deal.

This is what the Windows Hello/WebAuthn API does: https://github.com/microsoft/webauthn/blob/master/webauthn.h#L904

Concrete D-Bus API design

So far, I haven't seen a concrete D-Bus API design on this thread. @AlfioEmanueleFresta has some interface XML docs on his repo; would it be helpful if I formatted a design doc draft for critique? I think I could do that sometime in the next couple weeks.

Transport enumeration for Hybrid/caBLE transports

Do we need transport enumeration in the portal API? I don't think so. FIDO2 Hybrid transports are intended to be implemented by the client platform. So the "transport selection dialog" shown in this comment is eventually going to go away from Chrome. macOS can already handle hybrid authenticators in the platform, and in Windows 23H2+, Windows Hello will handle the hybrid transport itself. If we want to support hybrid authenticators, then that should be in the portal implementation. (The CTAP 2.2 spec draft describes the hybrid transport method, so this could now be implemented in client platforms.)

Password credential support

Here's a point I'll add to the mix: do we want to leave the door open to support other credentials?
We may want to model this portal after the w3C Credential Management API, which is what WebAuthn built on top off. This could allow the same API to be used to request/store both asymmetric (FIDO2) and symmetric (passwords) credentials, using the same framework/UX for user origin-based user consent. It could also resolve issues with standardizing password formats, as in gitlab.gnome.org/gnumdk/passbook/#17. Of course, to focus on FIDO2, we don't need to implement or even fully define the APIs for the other credential types, but it may be good to keep in mind while designing the FIDO2 methods

Firefox integration

Are we going to be able to convince Mozilla to use a portal instead of their authenticator-rs library? (This could be opportunistic: if org.freedesktop.portal.Credential exists, then use that portal over D-Bus, else use authenticator-rs). Perhaps, if we can get a good adoption from distributions. The authenticator-rs work can be re-used in the portal implementation itself.

Display Manager/PAM integration

Providing the ability to login to the computer with locally registered FIDO2 credentials, a la Windows Hello and macOS's TouchID and FaceID, would be a neat feature. I think it's out of scope for this issue though. This relates more closely to a platform authenticator than to the portal itself. (Personally, I would love to tackle it though. :) )

Does that about sum things up? Should I work on a design document?

@mcatanzaro
Copy link
Contributor

Does that about sum things up? Should I work on a design document?

Sounds like you are on the right track here. This would be helpful. Thanks!

Are we going to be able to convince Mozilla to use a portal instead of their authenticator-rs library?

I'm sure they'll ultimately use whatever API we define because (a) they want Firefox to work, and (b) Red Hat does much of the portal integration work anyway.

@swick
Copy link
Contributor

swick commented Jul 21, 2023

Sounds great!

We could allow all Flatpak apps to create/read credentials for all credentials in the beginning, and then we could later on enforce that the origin matches some origin derived from the app ID, returning a NotAllowedError if it doesn't.

This is the only part I have a problem with. Going from an open to a restricted policy is going to break someones use case. However, this policy is really independent of the rest of the system so I'd say go ahead with your plan, and before we merge anything we should revisit this point.

@msirringhaus
Copy link

The authenticator-rs work can be re-used in the portal implementation itself.

Just a quick note: While not a Mozilla-employee (and thus not able to steer the crate in whatever direction I want), I'm responsible for a large part of that code (CTAP2/2.1).
If you need special work done, to integrate auth-rs into the portal, feel free to ping me (or open a bugreport over at auth-rs). I'll see, if I can help.

@iinuwa
Copy link

iinuwa commented Jan 26, 2024

FYI, for anyone following this issue, I haven't forgotten about it, I just have a lot less time than I thought, and estimating is hard :).

I've done some more research and I think I've landed on having the public API basically look like Google's Credential Manager Jetpack API. I think it's simple and pretty well designed.

I'm trying to figure out what the API for the backends will need to be; I'm working on a prototype to start working out the kinks. It's not high quality at all, but the repo is public if anyone wants to follow along. The sequence diagrams would be of most interest right now: https://github.com/iinuwa/linux-webauthn-platform-api/blob/main/doc/scenarios.md.

@TingPing
Copy link
Member

@iinuwa I think your repo is private.

@iinuwa
Copy link

iinuwa commented Jan 27, 2024

@iinuwa I think your repo is private.

@TingPing Fixed, thanks.

@mcatanzaro
Copy link
Contributor

See also this blog post by Alfio, which lays out a higher-level design

@reesericci
Copy link

Just chiming in here - for on-device passkeys, I think it would make sense for them to be stored in the system keyring (e.g. gnome-keyring), so I'm wondering how this portal would play with that. Also, for password managers that store passkeys (e.g. Bitwarden), how will that be handled?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new portals This requires creating a new portal interface
Projects
No open projects
Status: Needs Triage
Development

No branches or pull requests