How to create template VM for custom software?

I am a Qubes newbie, and would like to get some guidance on setting up my Qubes. Below some specific issues and questions.

For context, I have some level of linux command line and general OS / dev experience but found the first steps of getting into Qubes OS unnecessarily hard. It’s not so hard to get the OS installed and up but then you are facing a major “now what” moment. I did read through the How to Organize your Qubes guide but that one was too theoretical on how to actually install software that I need.

I decided that for my circumstances I want proper isolation of some apps, e.g. my chat app should live it its own isolated Qube. So I figured (guess?) that I should install my chat app on a Template VM first from which I then create an App VM from that one. That already introduces the first thing that seems a little weird: Every software package that should live in isolation, leads to one Template VM and one App VM which spam my Qube menu unnecessarily. Also the workflow here feels somehow clunky (to create two separate VMs each time). Is this two-VM approach the best way forward for all software that I want to store in isolation?

Many software packages do not have vanilla apt packages or require some manual steps. For example, take the install instructions for how to install Element chat:

sudo apt install -y wget apt-transport-https
sudo wget -O /usr/share/keyrings/element-io-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] default main" | sudo tee /etc/apt/sources.list.d/element-io.list

sudo apt update

sudo apt install element-desktop

The wget is obviously going to fail in the default Template VM. That’s why I always resort to enabling sys-firewall in the newly created Template VM, ignore the warning, feel bad about it and hope that nothing goes wrong in that moment. I then shut down the newly created Template VM set its network to none and then create an App VM from that one and connect the App VM to sys-firewall. I read that there is some fancy firewall process that I could use, but that seems even harder to then install any software that I need on daily basis. So my second question is: What is the best way to install software that needs to wget something from the internet in the install process?


1 Like

Interesting - I learned something new, thank you! I would suggest to add such details to the How to Organize guide (or some other guide).

More generally is my clunky-feeling approach of creating a Template VM from which I then create an App VM for every isolated software package the way to go?

As far as I know, yes it is, if you want that sort of compartmentalization. (As a matter of fact, I do.)

Yes, qubes do proliferate that way and your menu gets choked. It’s even more so if you start using named disposables, because you end up with a TemplateVM, an AppVM that is set to act as a dispsosable template, and then the named disposable itself.

Unfortunately the default xfce menu will get clogged up pretty quickly that way. There is an experimental release of a menu proposed for Version 4.2 out there (and it is much better), or if you’re really ambitious, you can start using KDE, where you can organize your menu and set it up just as you like (I took all templates and dvm templates and put them off in submenus so I can still get to them if I need to, but they’re not in the way when I don’t).

1 Like

wonderful - thank you so much, I was gonna ask about how to unclog that menu next. I will look into that although that does sound like a bit much for me.


Not a guide. Moved to User Support > General

1 Like

Maybe I’m missing something but the snipped from @cayce does not work for me (I also had to prefix the first line and the last two lines with sudo):

apt install -y wget apt-transport-https

export http_proxy=

‍wget -O /usr/share/keyrings/element-io-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] default main" | tee /etc/apt/sources.list.d/element-io.list

sudo apt update
sudo apt install element-desktop

I cloned a blank Debian 11 template into a new Template VM, opened the terminal and pasted the above which fails on the last step with:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package element-desktop

But following this community install guide for Signal I managed to amend the instructions via curl instead of wget as follows:

curl --proxy | sudo tee /usr/share/keyrings/element-io-archive-keyring.gpg >> /dev/null

echo "deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] default main" | sudo tee /etc/apt/sources.list.d/element-io.list

sudo apt update

sudo apt install element-desktop -y

sudo shutdown -h now
1 Like


1 Like

Creating a TemplateVM for each application you want to use is one way to go. That way is not wrong.

Another possibility is to install the applications you want in a single TemplateVM and create an AppVM for each of those applications. That might be an acceptable approach depending on your threat model.

There are few things I’d take into account:

  • Applications are installed in the TemplateVM but never executed in the TemplateVM. Most bugs and security issues happen when the code is executed (that is why TemplateVM exist in the first place.) Having two applications installed in the same template but never executed in the same AppVM might be sufficient in some scenarios.
  • Installing a package from the official Debian or Fedora repositories carries a different risk than installing a package that was downloaded from a website, e.g. GitHub because Debian and Fedora build the packages they provide and ensure they can be verified automatically when installing them. That is something that may change how comfortable you are with Application A and B being installed in the same
  • If you only use Application A in a given AppVM, and Application B in a different AppVM, then Application A won’t have access to the data you create/use with Application B, even though both AppVMs may be created from the same template, and both applications are available in both AppVMs. It may be worth considering what you’re trying to compartimentalize and hide from Application A: the data you work with when using Application B, or the fact that sometimes you use Application B (metadata)?

All that depends on your theat model and personal compartimentalization goals. And of course, you can mix and match! Maybe application A, B and C can be installed in the same template, used in distinct AppVMs, but application D is better isolated in it’s own TemplateVM–AppVM pair.


These are incredibly good points that I would have like to read in the documentation.

1 Like

Which pages in the documentation were you looking at @SCBuergel, where do you think these notes could go?

This has moved somewhat off topic, and is more related to many of the
existing threads about use of minimal templates, where these issues have
been already discussed.

I’d like to give a different perspective, which may be of use depending
on your threat model.

Very often when you install a software package the application brings
with it numerous libraries and/or helper applications. These can greatly
increase the attack surface - an attacker might be able to chain
exploits, hopping from the application you executed, to take advantage
of a flaw in a library associated with another application that you have
not run.
Chaining in this way might allow for privilege escalation or data
extraction that would not be possible if the other application were
not installed, even though you have not run it in that qube.

If you have all the applications you want in a single template, then you
make it more likely that you will run those applications in a single
For example, if you have a storage qube with viewers installed, then you
make it more likely that you will open a file in that qube. If the
file contents are malicious you run the risk of compromising the qube.
A simple way to deal with this is to use a minimal template for the
storage qube, and mimetypes set to open files in an offline
disposable based on a loaded template. This removes the risk, (barring
exploits based on writing to/reading from disk, or flaws in qvm-open

A good deal more can be, and has been, said on the topic already.

I never presume to speak for the Qubes team. When I comment in the Forum or in the mailing lists I speak for myself.