Qubes OS implements security through compartmentalization: run every application (browser, email, document editing) in a separate virtual machine (qube) so one compromised app cannot access others’ data or your entire system. Create domain-specific qubes: personal (browsing), work (confidential documents), banking (air-gapped payments), untrusted (opening suspicious files). Use disposable qubes for one-time tasks. Configure split-GPG to keep private keys isolated in a dedicated qube. Integrate USB devices into specific qubes to prevent cross-qube data leaks. Qubes demands higher hardware (16GB+ RAM, fast SSD) and patience with complexity, but provides defense-in-depth against malware, credential theft, and data exfiltration unmatched by traditional operating systems.
Prerequisites
Before you begin, make sure you have the following ready:
- A computer running macOS, Linux, or Windows
- Terminal or command-line access
- Administrator or sudo privileges (for system-level changes)
- A stable internet connection for downloading tools
Step 1 - Security Model: Compartmentalization Over Antivirus
Traditional security relies on detecting malware: antivirus scans for known signatures, sandbox tools detect suspicious behavior. This fails when malware is novel or when a legitimate app is compromised (browser zero-day leaking your passwords).
Qubes OS inverts the model - assume applications will be compromised, design the system so compromise of one app cannot reach others. Each application runs in its own virtual machine. A compromised browser cannot read your password manager qube. A compromised email client cannot access your banking qube. Your private GPG key exists only in an isolated qube never touched directly by applications.
This requires discipline - assign qubes to specific purposes, never mix contexts. But the security guarantee is strong: even if your browser is fully owned by an attacker, they gain only temporary access to that qube’s temporary data, not your passwords, SSH keys, or other qubes’ files.
Hardware requirements:
- Minimum 16GB RAM (32GB recommended for smooth experience)
- Modern CPU with virtualization support (Intel VT-x or AMD-V)
- 100GB+ SSD for qubes and templates
- Laptop or desktop model verified on Qubes HCL (Hardware Compatibility List)
Supported computers - ThinkPad X1/X390, Dell Latitude, System76 laptops, and others. Check https://qubes-os.org/hcl/ before purchasing.
Step 2 - Install ation and Initial Setup
Installation Process
Download Qubes OS ISO from the official repository. Verify checksum:
On a trusted computer
sha256sum -c Qubes-R4.2-x86_64.iso.asc
Burn to USB (macOS)
diskutil list # Find USB device identifier (e.g., /dev/disk2)
diskutil unmountDisk /dev/disk2
sudo dd if=Qubes-R4.2-x86_64.iso of=/dev/disk2 bs=4m
diskutil eject /dev/disk2
Boot from USB, follow installation prompts. Key decisions:
Installation decisions:
Disk encryption: YES (required for any confidentiality)
Encrypt with passphrase: Strong passphrase (30+ characters, random)
Default NetVM (network qube): Use default sys-net
Firewall qube: Use default sys-firewall
USB handling: Use sys-usb (isolates USB drivers)
Installation creates default qubes:
dom0(management domain, never user-facing)sys-net(network qube, only one accessing network hardware)sys-firewall(internal firewall and routing)sys-usb(USB device drivers isolated here)work(example qube for user)personal(example qube for user)
After installation, update all qubes:
In dom0 terminal
sudo qubes-dom0-update
In each qube (work, personal, etc.)
sudo apt update && sudo apt dist-upgrade # Debian-based
sudo dnf upgrade # Fedora-based
Step 3 - Create and Managing Qubes
Qube Templates
All qubes are based on templates. Templates contain the operating system and applications. Templates prevent redundant disk usage (all qubes based on fedora-39 share the same OS files).
View available templates:
In dom0
qvm-ls -k Template
Default templates - fedora-39 (lightweight, default), debian-12 (stable, larger).
Create specialized templates:
Create a template for banking (no networking)
qvm-clone fedora-39 tpl-banking
qvm-prefs tpl-banking netvm "" # No network access
Create a template for web (browser focus)
qvm-clone fedora-39 tpl-web
Install browser and utilities
qvm-run tpl-web 'sudo dnf install firefox tor'
Create a template for development
qvm-clone debian-12 tpl-dev
qvm-run tpl-dev 'sudo apt install git python3 nodejs'
Creating Domain-Specific Qubes
Organize your workflow into focused qubes:
Banking qube (air-gapped, no internet)
qvm-create banking -t tpl-banking
qvm-prefs banking netvm "" # No network
Work qube (corporate environment, network isolated)
qvm-create work -t tpl-web
qvm-prefs work netvm sys-firewall
qvm-prefs work uses-custom-config True
Personal qube (general browsing, social media)
qvm-create personal -t tpl-web
qvm-prefs personal netvm sys-firewall
Disposable for untrusted files
qvm-create untrusted -t tpl-web
qvm-prefs untrusted template-for-dispvms True
Development qube
qvm-create dev -t tpl-dev
qvm-prefs dev netvm sys-firewall
Offline qube for document storage
qvm-create documents -t tpl-web
qvm-prefs documents netvm "" # No network
Memory and Storage Allocation
Each qube gets a memory allocation. Default is dynamic, but configure static minimums:
View current memory settings
qvm-ls -k MEMORY
Increase banking qube RAM for smooth operation (air-gapped qube)
qvm-prefs banking memory 2000 # 2GB minimum
qvm-prefs banking maxmem 4000 # 4GB max
Lightweight qube for throwaway tasks
qvm-prefs untrusted memory 512
Adjust based on available RAM and qube purpose. Memory is the most precious resource in Qubes.
Step 4 - Networking and Firewalling
Network Isolation
By design, sys-net is the only qube with network hardware access. All other qubes route traffic through sys-firewall.
Architecture:
User qubes (work, personal, dev)
↓
sys-firewall (routing and filtering)
↓
sys-net (wifi/ethernet drivers)
↓
Physical network hardware
This prevents malware in personal qube from interacting with network hardware or discovering network properties not intentionally routed through firewall.
Firewall Rules
Configure per-qube firewall rules:
Deny all, allow specific targets (whitelisting)
qvm-firewall work rule add action=drop
qvm-firewall work rule add action=accept dsthost=github.com
qvm-firewall work rule add action=accept dsthost=jira.company.internal
Personal qube - allow all HTTP/HTTPS
qvm-firewall personal rule add action=accept service=http
qvm-firewall personal rule add action=accept service=https
qvm-firewall personal rule drop # Default deny
Banking qube - no network
qvm-firewall banking rule add action=drop
View active rules:
qvm-firewall work list
DNS Handling
DNS leaks qube contents to ISP and DNS provider. Configure Qubes DNS:
In sys-firewall qube
sudo vi /etc/qubes-firewall/qubes-firewall.sh
Set custom DNS resolver (use Quad9, Cloudflare, or Mullvad DNS)
DNS_SERVER="1.1.1.1" # Cloudflare
Or use privacy-first resolver:
DNS_SERVER="9.9.9.9" # Quad9
Alternatively, route all DNS through Tor:
In sys-firewall
sudo dnf install tor
Configure Tor as DNS resolver via dnsmasq
Step 5 - USB Device Handling and Isolation
sys-usb Qube
All USB devices connect through sys-usb qube before reaching user qubes. This prevents USB malware from directly accessing your system and prevents side-channel attacks via USB.
Attach USB devices to specific qubes:
List USB devices in sys-usb
qvm-usb list
Attach USB flash drive to work qube temporarily
qvm-usb attach work sys-usb:1-1
In work qube, access mounted drive
/media/user/DRIVENAME/
Eject when done
qvm-usb detach work sys-usb:1-1
Create a disposable VM for untrusted USB devices:
Create disposable template for USB work
qvm-create --class DispVM untrusted-usb -t tpl-web
Attach USB device to disposable
qvm-usb attach untrusted-usb sys-usb:1-1
Work with files, then close qube
Disposable is discarded; no persistent malware
USB Whitelist
Prevent accidental USB connection to sensitive qubes:
Forbid banking qube from accessing USB
qvm-prefs banking devices '[("sys-usb", "1-1")]' --persistent=False
Whitelist specific USB device for work qube
qvm-prefs work devices '[("sys-usb", "1-2-KINGSTON:0000:0000")]'
Step 6 - Disposable VMs (Disposables)
Disposables are temporary qubes created on-demand, used once, then destroyed. Ideal for opening suspicious files, testing software, or one-time tasks.
Creating and Using Disposables
Create a disposable from default template
qvm-create-dispvm personal
Open a file in disposable (safer than opening in personal qube)
qvm-open-in-dispvm ~/Downloads/suspicious.pdf
This creates a temporary qube, opens the file, then disposes VM
Any malware in the PDF is contained to the temporary qube
Named Disposables
For workflow efficiency, create persistent disposable templates:
Create named disposable template for untrusted files
qvm-create --class DispVM untrusted-temp -t tpl-web
Use by name
qvm-run --dispvm=untrusted-temp 'firefox http://untrusted-site.com'
Qube is created, used, then destroyed on close
Disposable Lifespan
Disposables are ephemeral:
1. Qube created on demand
2. User opens file or runs application
3. User closes all windows
4. Qube destroyed (no data persisted)
5. Private.img discarded (no recovery possible)
This is powerful for isolation but means:
- No persistent storage (files are lost on close)
- No installed applications persist (must reinstall each time)
- Maximum isolation with minimal resource footprint
Use disposables for:
- Opening emails or files from untrusted sources
- Testing untrusted websites
- Temporary development environments
- File conversions or format inspection
Step 7 - Split-GPG: Isolated Cryptographic Operations
GPG private keys are the crown jewels of cryptography, if compromised, an attacker can forge your signature, decrypt your messages, and impersonate you.
Split-GPG runs GPG operations in an isolated “vault” qube. Your applications (email, git, documents) never touch the private key. Instead, they request cryptographic operations through a secure socket, and the vault qube approves or denies each operation.
Setup
Create a GPG vault qube:
qvm-create gpg-vault -t tpl-dev
qvm-prefs gpg-vault netvm "" # No network
qvm-prefs gpg-vault memory 1000
In gpg-vault qube, import your GPG key:
In gpg-vault qube
gpg --import /path/to/private.gpg
Verify import
gpg --list-secret-keys
Configure Qubes Split-GPG:
In dom0, create split-gpg socket configuration
sudo vi /etc/qubes/split-gpg-client.conf
Set vault qube name
VAULT_QUBE=gpg-vault
In client qube (work, personal, etc.), enable split-GPG:
In work qube
Create qubes.GPG RPC file
echo "ask" | sudo tee /etc/qubes-rpc/qubes.GPG.Ask
Point to vault qube
echo "gpg-vault" | sudo tee /etc/qubes-rpc/qubes.GPG
Usage
In client qube (e.g., work), sign files without direct key access:
In work qube
export QUBES_GPGDIR=/home/user/.gnupg/qubes-split-gpg
Sign a file
qubes-gpg-split --sign document.txt
This sends request to gpg-vault
gpg-vault shows approval prompt
User approves in gpg-vault qube
Signed document returned to work qube
Workflow Example
Secure Git workflow with split-GPG:
In work qube (untrusted or less trusted)
git config gpg.program qubes-gpg-split
Commit with signature
git commit -S -m "Add security hardening"
This triggers:
1. work qube requests GPG signature from gpg-vault
2. Approval prompt appears in gpg-vault (isolated from work qube)
3. User approves in gpg-vault
4. Signature returned to work qube, commit signed
5. Git operation completes in work qube
Private key never enters work qube. Attacker compromising work qube cannot extract GPG key.
Step 8 - Inter-Qube File Transfer
Transfer files between qubes securely:
Copy to Qube
From dom0, copy file from one qube to another
qvm-copy-to-vm work ~/important-document.pdf
This opens a dialog in work qube
User approves the transfer in work qube
File lands in /home/user/QubesIncoming/personal/
Copy from Qube
From personal qube, copy file to dom0 (discouraged, but possible)
qvm-copy-to-vm dom0 ~/Downloads/document.pdf
File appears in dom0:/home/user/QubesIncoming/personal/
Avoid transferring to dom0; instead, create a dedicated “files” qube:
qvm-create files -t tpl-web
qvm-prefs files netvm "" # Air-gapped storage
Transfer files between user qubes and files qube
qvm-copy-to-vm files ~/important-document.pdf
Directory Sharing (Advanced)
For persistent shared directories, use qvm-mount:
Mount files qube directory into work qube
qvm-mount work files:/root/shared /mnt/shared
Work qube can now access files in /mnt/shared
Changes synced back to files qube
Be cautious with shared directories, they bypass some isolation protections.
Step 9 - Qubes Manager GUI
Most operations can be performed via Qubes Manager (graphical interface):
Applications → System Tools → Qubes Manager
Qubes Manager displays:
All qubes (colored by status)
CPU and memory usage per qube
Networking status
Qube creation/management dialogs
Right-click on qube:
Start/Pause/Shutdown
Open Terminal
File Manager
Firewall Rules
Qube Settings
For most users, Qubes Manager suffices. Advanced users use command-line tools (qvm-*) for automation and scripting.
Step 10 - Common Workflows
Secure Email Workflow
1. Create email qube: qvm-create email -t tpl-web
2. Install email client: qvm-run email 'sudo dnf install thunderbird'
3. Configure email with standard security (TLS, DKIM verification)
4. Disable plugins and JavaScript to minimize attack surface
5. Open attachments in disposable: right-click → Open in disposable VM
6. Reply to emails without exposing email qube to attachment malware
Development Workflow
1. Create dev qube: qvm-create dev -t tpl-dev
2. Install development tools: git, Python, Node, etc.
3. Clone code repository
4. Commit and push using split-GPG for signed commits
5. Test code changes locally
6. For untrusted dependencies, use disposable VMs to test
7. Code remains in dev qube; compilation artifacts can be moved to work qube
Sensitive Document Workflow
1. Create documents qube (air-gapped): qvm-create documents -t tpl-web
2. Transfer sensitive document via qvm-copy-to-vm
3. Open document in LibreOffice (no network access possible)
4. Edit and save in documents qube
5. When ready to share, transfer to transfer qube (networked)
6. Original document remains in air-gapped qube
7. Transfer qube handles network operations safely
Performance Optimization
Qubes requires significant resources. Optimize for speed:
Increase Memory Allocation
For qubes used frequently, increase memory
qvm-prefs personal memory 2000 # 2GB minimum
qvm-prefs personal maxmem 4000 # 4GB dynamic maximum
Use PVHDX Format for Faster I/O
On new installations, PVHDX is default
For older installations, convert VMs to PVHDX:
qvm-shutdown personal
sudo /usr/libexec/qubes-manager/qvm-move-to-pool personal -p fast
Increase Swap
If RAM is constrained, increase swap space:
In dom0
sudo dd if=/dev/zero of=/swapfile bs=1G count=8
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
SSD Placement
Place Qubes directory on fast NVMe SSD. Spinning disks are too slow.
Lightweight Templates
Use minimal templates for less powerful systems:
Instead of fedora-39 (heavy), use fedora-39-minimal
qvm-clone fedora-39-minimal tpl-lightweight
Step 11 - Backup Strategy
Qubes stores everything in /var/lib/qubes/ including all qube filesystems. Regular backups are critical:
Backup all qubes and templates
qvm-backup-restore --backup-dir /mnt/backup /path/to/backup.tar
Create backup (in dom0)
tar -czf ~/qubes-backup-$(date +%Y%m%d).tar.gz /var/lib/qubes/
Move to external drive
sudo mv ~/qubes-backup-*.tar.gz /mnt/external-drive/
Store backups encrypted
gpg --symmetric ~/qubes-backup-*.tar.gz
Store backups on external encrypted drive, stored physically separately from computer.
Troubleshooting
Configuration changes not taking effect
Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.
Permission denied errors
Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.
Connection or network-related failures
Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.
Frequently Asked Questions
How long does it take to use qubes os for maximum compartmentalization?
For a straightforward setup, expect 30 minutes to 2 hours depending on your familiarity with the tools involved. Complex configurations with custom requirements may take longer. Having your credentials and environment ready before starting saves significant time.
What are the most common mistakes to avoid?
The most frequent issues are skipping prerequisite steps, using outdated package versions, and not reading error messages carefully. Follow the steps in order, verify each one works before moving on, and check the official documentation if something behaves unexpectedly.
Do I need prior experience to follow this guide?
Basic familiarity with the relevant tools and command line is helpful but not strictly required. Each step is explained with context. If you get stuck, the official documentation for each tool covers fundamentals that may fill in knowledge gaps.
Is this approach secure enough for production?
The patterns shown here follow standard practices, but production deployments need additional hardening. Add rate limiting, input validation, proper secret management, and monitoring before going live. Consider a security review if your application handles sensitive user data.
Where can I get help if I run into issues?
Start with the official documentation for each tool mentioned. Stack Overflow and GitHub Issues are good next steps for specific error messages. Community forums and Discord servers for the relevant tools often have active members who can help with setup problems.
Related Articles
- Qubes OS Compartmentalized Workflow Guide
- Air Gapped Computer Setup For Maximum Security Practical
- Browser Compartmentalization Guide Separating Identities 2026
- How To Use Multiple Identities Online Compartmentalization
- Implement Data Minimization Principle in Application Design
- AI Coding Assistant Session Data Lifecycle Built by theluckystrike. More at zovo.one