I didn't find something related to udev backend in the doc, so I wrote it down here. Please correct me if I was mistaken at some point below.
We have several security backends implemented in snapd, including apparmor, seccomp, kmod. And udev is one of those backends that provides most interfaces the capabilities of access restrictions for some sort of devices(/dev/tty, /dev/fb0, /dev/video0, etc). When a plug and a slot with the same interface name are connected, a udev rule will be added to '/etc/udev/rules.d/70-snap.[snap-name].[app].rules' and corresponding udev devices will be tagged and recorded in udev rule entries. An example of udev tagging for framebuffer is
const udevRule = `KERNEL=="fb[0-9]*", TAG+="snap_<snap_name>_<app>"
When launching an app, the context(snap-confine) it runs will search the udev database for any devices with matching tag, setup device cgroup and add device nodes to it.
Here is a bug filed on launchpad that currently we have tagged udev devices for a few snapd interfaces(A) but for many other snapd interfaces(B), we don't. When a snap contains a combination of an interface from A and an interface from B, a device access denial issue occurs since we only have tagged device nodes for the interface from A in the generated udev ruls.
I started working on this recently. A PR can be found here. There are still a few remaining interfaces that need to be done. They will be covered in a separated PR.