fix(rootless): Give each user a device grant of their own - #6
Merged
Merged
Conversation
brig-rootless-setup.sh wrote every user's /dev/kvm and /dev/vhost-vsock grant to one file, /etc/udev/rules.d/99-brig-kvm.rules. It also decided whether a grant was needed by comparing that file with the rule it wanted. On a host where one user already ran brig rootless, a second user's setup replaced the first user's rule with its own. The first user kept the ACL until the next udev event or reboot, and then lost both devices. A re-run by any user not named in that file asked for sudo again, even with the ACL in place from a rule of their own. So a user without sudo could not finish an install an admin had prepared. The grant now goes to 99-brig-kvm-<user>.rules. Whether one is needed is read from the devices: an ACL entry for the user, or mode 0666. The modules-load check reads the host the same way: any file under /etc/modules-load.d that lists vhost_vsock will do. --open-devices is a mode for the whole host, so it writes 99-brig-open-devices.rules. That name sorts after every per-user file, so its mode wins while it exists. A plain run leaves it in place. Closing the devices again is a root action, and docs/rootless.md shows it. A host set up by an older bundle keeps its 99-brig-kvm.rules. It still grants the user it names, and the setup never writes or removes it. tests/rootless-setup.sh generates the setup with the build's own function and runs it against a stub sudo, getfacl and stat. It checks that a first run writes the per-user file and never the shared one, that a user the devices already admit is not asked for sudo, and that --open-devices and a later plain run behave as above. Against the previous build-bundle.sh it fails on the first check, with the setup asking for `tee /etc/udev/rules.d/99-brig-kvm.rules`. CI runs it as a new step. Checked live on an Ubuntu 24.04 host where two users already had rootless brig, one of them through the old shared file. A third user's setup, given sudo, wrote 99-brig-kvm-<user>.rules. The other two files stayed byte-identical, and all three users held their ACLs. With sudo taken away again, a re-run asked for none. The previous setup, run as the same user, asked for `tee /etc/udev/rules.d/99-brig-kvm.rules` both before and after the grant. Signed-off-by: Anastassios Nanos <ananos@nofire.ai>
This was referenced Sep 25, 2026
…y close A user whose setup ran while --open-devices was in force gets no grant of their own: the setup reads the grant from the devices, and the open devices already let that user in. Removing the open rule then leaves them without access. Say that they run brig-ctl rootless again, which asks sudo for a grant in 99-brig-kvm-<user>.rules. Signed-off-by: Anastassios Nanos <ananos@nofire.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
brig-rootless-setup.shwrote every user's/dev/kvmand/dev/vhost-vsockgrant to one file,
/etc/udev/rules.d/99-brig-kvm.rules. It also decidedwhether a grant was needed by comparing that file with the rule it wanted.
On a host where one user already runs rootless brig, a second user's setup
replaced the first user's rule with its own. The first user kept the ACL until
the next udev event or reboot, and then lost both devices. A re-run by any user
not named in that file asked for sudo again, even with the ACL in place from a
rule of their own. So a user without sudo could not finish an install an admin
had prepared, and
docs/rootless.mdpromised that "any number of users run it".This patch gives each user a rule file of their own, and reads the grant back
from the devices instead of from one file's bytes.
Changes
/etc/udev/rules.d/99-brig-kvm-<user>.rules.Whether one is needed is read from the devices: an ACL entry for the user, or
mode
0666. A grant an admin wrote by hand, under any file name, counts./etc/modules-load.dthat listsvhost_vsockwill do.--open-devicesis a mode for the whole host, so it writes99-brig-open-devices.rules. That name sorts after every per-user file, soits
MODE="0666"wins over theirMODE="0660"while it exists. A plain runleaves it in place, since another user may depend on it.
99-brig-kvm.rules. Itstill grants the user it names, and the setup never writes or removes it.
Every other user gets a file of their own.
docs/rootless.mdcovers the per-user files, the old shared file, and howroot removes a grant or closes an open host.
tests/rootless-setup.sh, run by a newScript testsstep in CI. fix(bundle): Run brig-ctl's ctr inside the rootless namespace #8 and fix(install): Name the bundle in the install summary #9add the same step, word for word, so the three merge cleanly in any order.
One behavior changes. Going back from
--open-devicesused to be a plainre-run of the setup, which rewrote the one file. With a file per user, a
plain run cannot tell whose choice the open rule was, so closing the devices is
now a root action, and the docs show it.
Testing
tests/rootless-setup.shgenerates the setup with the build's ownwrite_brig_rootless_setupand runs it against a stubsudo,getfaclandstat. The stubs answer from the rule files the setup "writes" into a scratchdirectory, so nothing outside it changes.
The same test against
main'sbuild-bundle.sh:sh -n(dash) andshellcheck -s shpass overinstall.sh,build-bundle.sh, the three generated scripts and the test.Live, on an Ubuntu 24.04 host
The host had two users with rootless brig:
ananosthrough the old shared99-brig-kvm.rules, andbrigtestthrough a file of their own. A third user,brigtest2, was created for the test and removed afterwards. The setup wasgenerated from this branch with the build's own function.
main's generatorreproduces the v0.1.0-rc8 release's
brig-rootless-setup.shbyte for byte, sothe comparison below is like for like.
The previous setup, as
brigtest2, with a sudo shim that logs and refuses:This branch's setup, as
brigtest2, with a temporaryNOPASSWDsudo:With the sudo entry removed, a re-run of
brig-ctl rootlessasked for nothing:the shim log stayed empty. The previous setup, on the same granted host, still
asked for
tee /etc/udev/rules.d/99-brig-kvm.rules.On that grant,
brig run -d ubuntu ~/projbooted a 6.18 guest with qemurunning as
brigtest2, and read the project file from/work/proj. After thetest,
brigtest2, its rule, its ACL entry, its AppArmor profile and its subuidlines were removed. Both other rule files kept the hashes above, and both
users kept their ACLs.
🤖 Generated with Claude Code