Note: this page is intended to collect all related information to what the individual qubes policies mean Hopefully it'll be a wiki that everyone can add to. Please contribute any information that you may have on the definitions of the policies.

The following things are included in this page: - If you know the name of the call - Searching the source code - Try doing qrexec calls directly - You know what you want to do, but dont know the name: - Just try it and read notifications - Just try it using sys-gui - Just try it using a sys-gui-vnc with no networking enabled and read notifications (much faster)

Intro on policies

The qubes admin policies are core to modern qubes. You have some reason you are using a computer (I.E. what you want to do with it, I.E. your use case). The idea is to editing the policies to make things secure for that use case. Of course you can edit the policies to make things less secure for that use case. Obviously understanding what the individual policies mean will be important to securing your system.

If you have never edited the policies files:

The policies can be viewed and edited by running: (gear icon) -> "qubes tools" -> qubes-global-config then clicking "open" and selecting any one of the policy files. (This is the prefered way to edit qubes policies because the qubes 4.2 policy editor does syntax checking before saving the file and can save you a lot of time.)

If you have no idea what policies are about, then run: (gear icon) -> "qubes tools" -> qubes-global-config. In this global config window then Clipboard, File Access, Split GPG, and URL handling screens are each a gui interfaces to small portions of the policy files. Changing options on one of those screens, then clicking "view policy file" at the bottom to see how changing the settings change the policies is probably the fastest way to learn the concept of policies in qubes

Note that changing the policies without thinking through the security implications of your changes could lead to you compromising the security of your system.
[Open question: Is it mentioned anywhere what people should do to learn qubes that we can point to? Things like how it's preferable to learn and make your mistakes on a system that does not have security critical data on it, and not on a security critical production system?]

Back to the point on decoding the policy/services:

The names of all the policies/services appear to be listable by doing ls /etc/qubes-rpc/ in dom0

While the names of the policies/services are documented there, it would also be nice to know what they do! 🙂

actually it looks like they are missing the whonix.* policies, so that list might not be complete.

Some of the policies have been partially documented here: list of the names of the policy/service calls ( alternate version?), the detailed explanation of what they actually do does not appear to be well documented. NOTE: the table should have 6 columns. If you do not see 6 columns, then you need to scroll the table horizontally

[details="Maybe still useful (since last edit)?"] What seems to be a partial list of the qubes.* policies/services can be found at: https://github.com/QubesOS/qubes-doc/blob/78b074236271586a3522caa2a793cc951cfe812d/developer/debugging/vm-interface.md?plain=1#L203 There is also a partial list of the policies/services in the filenames in this directory: https://github.com/QubesOS/qubes-core-admin/tree/b4df77dc253343f86f01b96c41f0bb732a88e268/qubes-rpc [/details]

So this document will be split into a "how to try to figure it out" section, and a "best information/guesses so far for what they actually do" section.

Approaches to figure out what the policy/services do:

If you know the name of the policy/service and want to know what it does:

You can try searching the source code

Then you can try searching the source code on the name of the policy/service. Doing this with admin.vm.list eventually finds "List all the domains" which I believe is currently incorrect. I believe it actually the description of the service is something closer to "Lists all domains for which we have permissions for (example: we are the guivm for)" and description of the policy/servicename would be something like . "allows system1 to see system2 in its qvm-ls list". So anyway, this does not always help.

Follow up: After a couple days I found a old post talking about it in the old format , saved in a "qubes-posts" repo on github that confirms it's supposed to be the qvm-ls list

You can try doing qrexec calls

From any qubes other then dom0, you can do qrexec calls. For example, by doing things like

qrexec-client-vm work admin.vm.List

but even when you set the policy to allow it, the above still returns nothing.

and going:

qrexec-client-vm dom0 admin.vm.List
just seems to hang when you give it permission.

(same with qrexec-client-vm dom0 admin.label.List)

Obviously qubes needs admin.vm.List to operate, so qrexec is working, there is just some kind of missing information on how to interact with it

Maybe there is a way to turn on debugging info for qrexec so we can get a log of the actual requests coming in? Currently the logs (including the systemd log) do not seem to provide any more detail then the notification messages whenever qubes denies a request

Just try it:

Some good news is that whenever qubes denies a request/action becuase of policy, a notification is sent to the screen, that includes the name of the policy/service. This means that if you know what functionality you want your new policy to allow, just try it and look at what appears on the screen.

Qubes functionality comes in 2 versions, gui functionality and command line functionality.

Just try it - (for command line programs):

For example, pick a qube (other then dom0 or the "work" qube) and lets say we had a good reason to want the qube you picked to be able to run a command in the work qube. To figure out the name of the policy/service for it, just try running a command in the work qube: qvm-run-vm work echo 'hi'

You should see a notification pop up with a error saying "qubes.VMShell" from {current qube} to work was denied.

This is good, cause we normally don't have a good reason for arbitrary qubes to run programs in the work qube, but if we did have a good reason, and had thought through the security implications of doing it, we could just add that to the policy with:

qubes.VMShell * {current qube} work allow

Just try it - (for GUI applets/programs):

Ok, by browsing the list generated by doing: ps aux | grep '^user' | less in dom0, we can find /usr/bin/bash /usr/bin/widget-wrapper qui-domains, which looks like it could be the blue qubes widget that lists all the currently running qubes.

Neither /usr/bin/widget-wrapper or qui-domains is available in normal qubes.

Introducing sys-gui!:

You can set up a sys-gui qube by doing:

qvm-prefs default-mgmt-dvm template fedora-38
(Note: fedora-40-xfce is another option, but sometimes gives a "no such module" salt.{something}.six} error### (also, dont use debian)

sudo qubesctl top.enable qvm.sys-gui
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl --all state.highstate

if everything worked, you can then:

sudo qubesctl top.disable qvm.sys-gui

Give yourself a way to unlock the screen when logged into sys-gui:

sudo /bin/sh -c "sudo grep '^user:' /etc/shadow | sed 's/^user:\([^:]*\):.*/sys-gui:\1/' >  /etc/qubes-sys-gui-user-passwords"
sudo chmod 600 /etc/qubes-sys-gui-user-passwords
now create a file in dom0 called /home/user/fix-guivm-password.sh, that contains:

NEW_PASSWORD_HASH=`sudo grep "^$1:" /etc/qubes-sys-gui-user-passwords | sed 's/^[^:]*://'`

ESCAPED_PASSWORD_HASH="${NEW_PASSWORD_HASH//\//\\\/}"

qvm-run --pass-io --no-gui --user=root $1 "sed -i 's/^user:[^:]*:/user:$ESCAPED_PASSWORD_HASH:/' /etc/shadow"
then do:
chmod a+x /home/user/fix-guivm-password.sh
Then add this line to /usr/bin/qubes-guivm-session:
/home/user/fix-guivm-password.sh $1
right before this line:
exec qvm-run -p --no-gui --service "$1" qubes.GuiVMSession

Then finally create a qube called work-sys-gui and then do:

qvm-prefs  work-sys-gui guivm sys-gui

Then you can logout, then change the upper right corner option on the login screen to "sys-gui" then login again.

You should now be logged into sys-gui. (sys-gui now seems to have a blue hamster as the desktop background). If you look at the qubes available, it's just the work-sys-gui qube. Now, you can load the settings for the work-sys-gui qube, and you can run things in work-sys-gui with your default network. You can also change the network from sys-firewall (or whatever your default network was) to "none", and network access will no longer be available. perfect.

However, you are not allowed to change network access back from "none" to sys-firewall (or whatever your default network was). This looks like a policy issue! But we have 2 problems now. #1. Every time we want to change the policies, we need to log out and log back in as dom0. And #2 dom0 gets the notifications of what policy was denied when we tried to enable sys-firewall. This takes forever and is not condusive to trial and error.

We will fix those parts now by installing a "useless sys-gui-vnc" that does not have network access (and cant be reached remotely).

sys-gui-vnc (with no networking)

Create sys-gui-vnc qube:

sudo qubesctl top.enable qvm.sys-gui-vnc
sudo qubesctl top.enable qvm.sys-gui-vnc pillar=True
sudo qubesctl --all state.highstate
sudo qubesctl top.disable qvm.sys-gui
Then create sys-gui-vnc-viewer qube (that will just run a vnc viewer):
qvm-run --pass-io debian-12 'sudo apt update'
qvm-run --pass-io debian-12 'sudo apt install -y xtightvncviewer'
qvm-shutdown debian-12
qvm-create --template debian-12 --label purple --property netvm=none sys-gui-vnc-viewer
(note: netvm=none does not work, so you'll need to go into the gui and set the network to none)

Then allow sys-gui-vnc-viewer to connect to the "local" port 5900 in sys-gui-vnc:

echo 'sys-gui-vnc-viewer @default allow,target=sys-gui-vnc'  >> /etc/qubes.d/policy/30-user.qubes.ConnectTCP.policy
qvm-run --pass-io  sys-gui-vnc-viewer "echo 'qvm-connect-tcp 5900:sys-gui-vnc:5900' >> /rw/config/rc.local"
(note: if sys-gui-vnc-viewer is currently running then restart it)

Then allow ourselfs to log in:

sudo /bin/sh -c "sudo grep '^user:' /etc/shadow | sed 's/^user:\([^:]*\):.*/sys-gui-vnc:\1/' >>  /etc/qubes-sys-gui-user-passwords"
/home/user/fix-guivm-password.sh sys-gui-vnc

Then finally, in sys-gui-vnc-viewer run:

xtightvncviewer localhost
and log in.

Then finally create a qube for sys-gui-vnc to use called work-sys-gui-vnc and then do:

qvm-prefs  work-sys-gui-vnc guivm sys-gui

If you cannot see it in the "big Q" menu on the left, then try rebooting sys-gui-vnc

You may notice that the menu acknowledges the existance of the qube, but not of any of the applications. This is because sys-gui-vnc does not have access to the template that work-sys-gui-vnc uses.

Try launching the settings for work-sys-gui-vnc and watch the error messages:

Opportunities!:

admin.vm.property.Get+netvm is not a real policy. admin.vm.property.Get is though, and +netvm probably just means that its asking for just the netvm property. so the assocated policy would be:

admin.vm.property.Get * sys-gui-vnc default-dvm accept

It is probably asking about devault-dvm because default-dvm is set as the default disposable template. This would be a opportunity to explore that policy.

the admin.vm.feature.List sys-gui-vnc to debian-12 error would be the policy:

admin.vm.feature.List * sys-gui-vnc debian-12

and the admin.vm.property.Get+template sys-gui-vnc to debian-12 error would be:

admin.vm.property.Get * sys-gui-vnc to debian-12

Start the work-sys-gui-vnc qube. Notice the following error messages:

Now, note that the network is set to sys-firewall (or whatever your default firewall is).

change the network to none

Now try changing the network back to sys-firewall

this time we get policy errors. Success!

admin.vm.CurrentState to sys-firewall

then open the settings change the network to none, and then try to change the network back. Now you should get a actual error notification!

trying to update the applications gives one error that we havent seen before, before giving a overall failure message. The new policy error is:

admin.vm.Start from sys-gui-vnc to debian-12

which would be the policy:

admin.vm.Start * sys-gui-vnc debian-12

Summary: sys-gui-vnc's #1 use seems to be as a debugging tool. To use it for remote administration is possible, but requires special setup.

⭐️ List of What Qubes policies Mean (Best Information So Far) ⭐️

(plese contribute if you have any information)

policy CLI description GUI description
------------------------------------------------------------------------------- --------------------------------- -------------------------------------
admin.vm.List * {qube1} {qube2} allow verified experimentally: allow qube1 to see qube2 when it runs qvm-ls allow the "big Q" menu in qube1 to see qube2. Also, I conjecture that it will allow qui-domains widget in qube1 to see qube2 (It's a conjecture because after giving this and some other permissions qui-domains, it crashes). (Note: qui-domains also requires it to be running to be able to see it)
admin.vm.property.Get * {qube1} {qube2} allow speculation: Permission for qube1 to get all properties (the things displayed by "qvm-prefs {qubename}") from qube 2 but can only get one at a time (possibly this can be scoped to just allowing certain properties, but not others?). cannot confirm because qvm-prefs needs admin.vm.List and admin.vm.property.List to work, but after you give it just those, qvm-prefs crashes with a "QubesDaemonAccessError", however no notification of denied policies happen.
admin.vm.property.GetAll * {qube1} {qube2} allow speculation: Permission for qube1 to get all properties (the things displayed by "qvm-prefs {qube name}") at once (same notes as for admin.vm.property.Get
admin.vm.property.Set +{property} {qube1} {qube2} allow Verified: Allow qube1 to set the property {property} for qube2 (verified by inserting a deny policy for admin.property.Set (due to crashing issue)) (note: you have to actually type the + before the property, it's not a meta characte)
admin.vm.property.Set * {qube1} {qube2} allow Allow qube1 to set any property listed by qvm-prefs for qube2 (same as above, just using a wildcard)

We should probably group them, and then put in section headers like:

admin.vm.* - A vm is the same thing as a qube which is the same thing as a domain. They are first column that is output when you run qvm-ls in dom0

admin.vm.feature.* - A feature is what gets listed when you type qvm-features {qube name} in dom0. The output is quite sparse though. You can find a much more complete list of features in the man page (I.E. run "man qvm-features in dom0)

admin.vm.properties.* - A property is the same thing as a preference. It is what gets listed when you type qvm-prefs {qube name} in dom0.

admin.label.* - A label is probably referencing a "security label". Currently in qubes the only thing assigned to a label is the color the qube. (source: https://dev.qubes-os.org/projects/core-admin-client/en/latest/_modules/qubesadmin/label.html )