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.

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? Thinks 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:

While the names of the policies/services have been documented list of the names of the policy/service calls, the detailed explanation of what they actually do does not appear to be well documented. In fact that link appears to be unofficial documentation that is someones attempt to fill in some details for us, that never got merged into the qubes official documentation

NOTE: the table should have 6 columns. If you do not see 6 columns, then you need to scroll the table horizontally

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 supposedly

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.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.property.Set * {qube1} {qube2} allow Allow qube1 to set any property listed by qvm-prefs for qube2 (same as above, just using a wildcard)