Request for auto-connection of u2f-devices for Brave

Hi,

I’m an engineer at Brave and I’d like to request auto-connection for u2f-devices for the Brave browser package.

Brave is developed with privacy and security in mind, so putting obstacles in the way of people trying to use their yubikeys is something we’d like to avoid.

This has been requested by users (https://github.com/brave/brave-browser/issues/6782) and also granted to other browsers (Firefox, Chromium).

Thanks.

1 Like

+1 for me for auto-connect u2f-devices for brave since it’s a browser (even designed with privacy and security in mind) and this was already discussed and granted for other snaps such as firefox and chromium.

So, it’s been a week - does this require another vote in favor? Like I said, other browsers already have this autoconnection, so this seems like it should be pretty much automatic…

+1 from me, if another vote is required - @emitorino’s rationale is sound.

  • Daniel

+2 votes for, 0 votes against, granting auto-connect of u2f-devices to brave. This is now live.

@roadmr, @emitorino the autoconnection works, but requires the u2f device to be (re)connected after the snap starts.

snappy-debug suggested adding hardware-observe and that did the trick. After connecting it manually, my yubikey worked without the need to disconnect and connect it again. However, the docs (https://snapcraft.io/docs/hardware-observe-interface) say the plug can’t be autoconnected, which seems to defeat its purpose, at least in my case.

Interestingly, while Chromium has the same issue as Brave, Firefox doesn’t and it doesn’t use the hardware-observe plug. I thought maybe it was removable-media that they have autoconnected, that made it work, but I tried adding it to Brave and connecting manually and that didn’t solve the problem.

What is the proper way to make u2f devices be detected without having to (re)connect them after the snap starts?

The docs should maybe be updated to be more clear about this, but the interface is just not auto-connected by default, it can be made to be auto-connecting by going through this process by requesting it on the forum.

@ijohnson so hardware-observe is the right plug for this? How is Firefox doing it without it?

Sorry I don’t know which interface is needed for your application, I was just pointing out that if your snap needs hardware-observe connected, it can be made to auto-connect by requesting it on this thread.

Eh, actually, hardware-observe doesn’t solve this. Bizarrely, it appears to make it worse. Currently (re)connecting the device makes it work. With hardware-observe, that no longer applies.

So let me ask again - what is the proper way to make u2f devices be detected without having to (re)connect them after the snap starts? I didn’t see it documented anywhere.

@emitorino? @roadmr?

Hi! You asked how firefox does it. Its snap-declaration assertion shows the interfaces it has allowed, assertions are not secret so here it goes (plug config only):

plugs:
  avahi-observe:
    allow-auto-connection: true
  browser-support:
    allow-auto-connection: true
  camera:
    allow-auto-connection: true
  cups-control:
    allow-auto-connection: true
  pulseaudio:
    allow-auto-connection: true
  removable-media:
    allow-auto-connection: true
  u2f-devices:
    allow-auto-connection: true

I wonder if for comparison you could try FIrefox in the same scenario and see if it also needs the reconnection dance you mention.

  • Daniel

That is my entire point. With Firefox this is not needed.

This problem affects both Brave and Chromium, so these are the candidates:

% snap interfaces 2>&1|grep firefox|grep -vE 'chromium|brave'
firefox:dbus-daemon                    -
firefox:mpris                          -
-                                      firefox:avahi-observe
-                                      firefox:joystick
-                                      firefox:network-observe
%

I was hoping this wouldn’t require guessing, but didn’t find it documented anywhere. Hence my question here.

I can only get the Yukibey to work if I insert it AFTER brave-snap started.

See also here:

Yes, this is still a problem in both Chromium and Brave.

If the yubikey is inserted before the snap is started, an attempt to use it results in

ERROR:udev_watcher.cc(98)] Failed to begin udev enumeration.

This is preceded with

ERROR:object_proxy.cc(577)] Failed to call method: org.freedesktop.DBus.Properties.Get: object_path= /org/freedesktop/portal/desktop: org.freedesktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.FileChooser”
ERROR:select_file_dialog_linux_portal.cc(285)] Failed to read portal version property

in both Chromium and Brave.

None of this applies to Firefox.

There are some differences in connections between Firefox and Brave/Chromium. The ones that look like the could be relevant include dbus and hardware-observe.

@roadmr should we enable some additional connections to make this work? I could not find the answer in the snap documentation.

Thanks

EDIT: Our GitHub issue for this https://github.com/brave/brave-browser/issues/15003

Audit logs are the same for Brave and Chromium when trying to use the Yubikey.

Brave:

audit: type=1400 audit(1699024951.108:779): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c510:0" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.131:780): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c511:0" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.131:781): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c511:1" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.168:782): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c90:0" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.168:783): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c90:3" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.168:784): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c90:1" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.168:785): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/c90:2" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.188:786): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/b254:0" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699024951.191:787): apparmor="DENIED" operation="open" class="file" profile="snap.brave.brave" name="/run/udev/data/+dmi:id" pid=3139833 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

Chromium:

audit: type=1400 audit(1699025177.632:839): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c510:0" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.658:840): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c511:0" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.658:841): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c511:1" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.695:842): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c90:0" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.695:843): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c90:3" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.695:844): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c90:1" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.695:845): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/c90:2" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.735:846): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/b254:0" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
audit: type=1400 audit(1699025177.738:847): apparmor="DENIED" operation="open" class="file" profile="snap.chromium.chromium" name="/run/udev/data/+dmi:id" pid=3143459 comm="ThreadPoolForeg" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

Neither u2f-devices, nor raw-usb sorts this out, so what does?

Welp, looks like hardware-observe is the answer. I’ll start another thread for the auto connection.