Recommendations for basic libvirt access control
Hello, I noticed that (at least on my Fedora installation), adding a user to the libvirt group is equivalent to giving full root access (since the user can add arbitrary block devices to VMs, and then use the VM to modify the block device). Therefore, I'd like to give users more limited permissions - but I'm a bit lost about the best way to approach that. It seems that I could: - tighten (or relax) socket permissions in the systemd config - switch off socket activation and configure socket permissions in libvirtd.conf - Configure socket-dependent permissions in libvirt - Enable policykit ACL checks, and configure permissions there. Could someone give me a recommendation what (combination?) of these options would most suitable for a simple "users can interact with their predefined VMs" model? Ideally, users would be able to configure and interact with VMs that are assigned to them, without having access to operations that are trivially root-equivalent (like adding new storage devices from the host). If that's difficult, I'd also settle for a simpler model where users can't change VM permissions at all, and are limited to starting, stopping, and connecting to the console of their VM. What's the best way to accomplish that? Best, -Nikolaus
On Fri, Dec 05, 2025 at 12:43:55 +0000, Nikolaus Rath wrote:
Hello,
I noticed that (at least on my Fedora installation), adding a user to the libvirt group is equivalent to giving full root access (since the user can add arbitrary block devices to VMs, and then use the VM to modify the block device).
In addition they can also exec any program with root permissions via libvirt's system instance.
Therefore, I'd like to give users more limited permissions - but I'm a bit lost about the best way to approach that. It seems that I could:
- tighten (or relax) socket permissions in the systemd config
- switch off socket activation and configure socket permissions in libvirtd.conf
- Configure socket-dependent permissions in libvirt
None of this will help unless you trust the user. Whoever is able to define a full XML is effectively root.
- Enable policykit ACL checks, and configure permissions there.
Polkit gives you the possibility to restrict users to certain APIs ...
Could someone give me a recommendation what (combination?) of these options would most suitable for a simple "users can interact with their predefined VMs" model?
... which apart from this you must restrict to only APIs such as starting the VM with existing configuration.
Ideally, users would be able to configure and interact with VMs that are assigned to them, without having access to operations that are trivially root-equivalent (like adding new storage devices from the host).
If that's difficult, I'd also settle for a simpler model where users can't change VM permissions at all, and are limited to starting, stopping, and connecting to the console of their VM.
We have some documentation, which also links to some examples, but I didn't personally try them: https://libvirt.org/aclpolkit.html https://libvirt.org/acl.html#objects-and-permissions Another possibility is to make the users use the unprivileged session instance (virsh -c qemu:///session) where the daemon runs as the user itself. Obviously that doesn't work with stuff like device assignment, access to raw block devices etc and has also some limitations in how network is accessed (e.g. use of passt). But this version is secure by default as everything happens as the user
Hi Peter! On Fri, 5 Dec 2025, at 14:40, Peter Krempa wrote:
Therefore, I'd like to give users more limited permissions - but I'm a bit lost about the best way to approach that. It seems that I could:
- tighten (or relax) socket permissions in the systemd config
- switch off socket activation and configure socket permissions in libvirtd.conf
- Configure socket-dependent permissions in libvirt
None of this will help unless you trust the user. Whoever is able to define a full XML is effectively root.
I was thinking that perhaps there is a socket that I can configure in such a way that it doesn't allow defining the XML? (I thought that the -ro.socket might do something like this) Best, -Nikolaus
On Fri, Dec 05, 2025 at 14:51:35 +0000, Nikolaus Rath wrote:
Hi Peter!
On Fri, 5 Dec 2025, at 14:40, Peter Krempa wrote:
Therefore, I'd like to give users more limited permissions - but I'm a bit lost about the best way to approach that. It seems that I could:
- tighten (or relax) socket permissions in the systemd config
- switch off socket activation and configure socket permissions in libvirtd.conf
- Configure socket-dependent permissions in libvirt
None of this will help unless you trust the user. Whoever is able to define a full XML is effectively root.
I was thinking that perhaps there is a socket that I can configure in such a way that it doesn't allow defining the XML? (I thought that the -ro.socket might do something like this)
The read-only connection doesn't allow defining XML, but also doesn't allow starting/stopping the VM or any other state change for that matter, just looking at the state. You need to use fine-grained ACL on the "write-enabled" socket for that.
On Fri, Dec 05, 2025 at 04:05:36PM +0100, Peter Krempa via Users wrote:
On Fri, Dec 05, 2025 at 14:51:35 +0000, Nikolaus Rath wrote:
Hi Peter!
On Fri, 5 Dec 2025, at 14:40, Peter Krempa wrote:
Therefore, I'd like to give users more limited permissions - but I'm a bit lost about the best way to approach that. It seems that I could:
- tighten (or relax) socket permissions in the systemd config
- switch off socket activation and configure socket permissions in libvirtd.conf
- Configure socket-dependent permissions in libvirt
None of this will help unless you trust the user. Whoever is able to define a full XML is effectively root.
I was thinking that perhaps there is a socket that I can configure in such a way that it doesn't allow defining the XML? (I thought that the -ro.socket might do something like this)
The read-only connection doesn't allow defining XML, but also doesn't allow starting/stopping the VM or any other state change for that matter, just looking at the state.
You need to use fine-grained ACL on the "write-enabled" socket for that.
We have an example for the config for this here: https://gitlab.com/libvirt/libvirt/-/blob/master/examples/polkit/libvirt-acl... With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (4)
-
Daniel P. Berrangé -
Nikolaus Rath -
Nikolaus Rath -
Peter Krempa