udev Input Device Permissions: How to Pin dialout and plugdev
To pin udev permissions for USB serial/HID, drop a rule under /etc/udev/rules.d/, match the USB parent with ATTRS{idVendor} / ATTRS{idProduct} (and serial when possible), then set GROUP="dialout", MODE="0660", and SYMLINK+="…". On Debian/Ubuntu, serial nodes default to the dialout group.
This article covers USB serial/HID groups and symlinks only—not a general udev primer.
Where do the rules live?
One-line answer: User rules go in /etc/udev/rules.d/99-….rules; add yourself to dialout (and your distro’s plugdev/replacement group if needed) and re-login.
Flow:
- Plug in and list nodes:
ls -l /dev/ttyUSB* /dev/ttyACM*(HID:/dev/hidraw*). sudo usermod -aG dialout "$USER"then log out/in.- Write a rule, e.g. FTDI-style serial:
# /etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
ATTRS{serial}=="A1B2C3D4", GROUP="dialout", MODE="0660", SYMLINK+="myboard"
HID sketch (replace with measured IDs):
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", \
GROUP="plugdev", MODE="0660", SYMLINK+="myhid"
systemd defaults already assign many tty* nodes to dialout. Custom rules mainly add a stable name and VID/PID lock-in. Ubuntu-style plugdev appears in desktop USB guides; systemd discussions often prefer uaccess or system groups over long-term plugdev dependence. For board serial, dialout + a logged-in session remains the common path.
If /dev/serial/by-id/… already exists, pointing the app there also avoids enumeration-order churn.
How does ATTR matching work?
One-line answer: Walk parents with udevadm info -a -n /dev/ttyUSB0, then combine ATTRS{…} that live on the same parent. Matching is case-sensitive.
udevadm info -a -n /dev/ttyUSB0 | grep -E 'ATTRS\{(idVendor|idProduct|serial|manufacturer|product)\}'
Tips:
ATTR{…}is the device itself;ATTRS{…}walks parents. VID/PID usually sit on the USB parent.- All
ATTRSkeys in one rule must be satisfied by one parent device—do not mix ancestors. - Hex values are often lowercase (
0403); avoid case/whitespace mismatches. - Add
ATTRS{serial}when identical dongles share a VID/PID. - Match the tty (
SUBSYSTEM=="tty") for serial apps; a symlink on the raw USB device alone may not be the node your tool opens.
How do you verify with udevadm?
One-line answer: control --reload-rules, trigger, then info / test to confirm GROUP, SYMLINK, and access.
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=tty
sudo udevadm trigger -n /dev/ttyUSB0
udevadm info -n /dev/ttyUSB0 | grep -E 'DEVNAME|DEVLINKS|ID_VENDOR|ID_MODEL|ID_SERIAL'
ls -l /dev/myboard /dev/ttyUSB0
sudo udevadm test /sys/class/tty/ttyUSB0 2>&1 | tail -n 40
Checks:
ls -lshows the intended group/dev/myboardpoints at the expected tty- Unprivileged open works after re-login
- If not:
groups, rule filename/syntax (==vs=), VID/PID typos
Wrap-up
Pin USB serial/HID access with ① /etc/udev/rules.d + dialout membership → ② ATTRS VID/PID(/serial) → ③ udevadm reload/trigger/test. Focus on group, symlink, and verification so board paths stay stable.