Qubes OS provides a way to manually move clipboard contents across AppVMs using the Shift+Ctrl+C / Shift+Ctrl+V shortcut, but sometimes it’s a bit clumsy.
The scenario: I use about ten VMs for local app development and copy-paste code between them, most of which are air-gapped. I also have a special VM exposed to the Internet where I run Claude and ChatGPT (it also belongs to this group).
So, I want to lower the “paranoia level” in this, let’s say, development group.
Are there any ready-to-use solutions before I start building my own?
Here’s how I see the solution: I need a dedicated VM running a clipboard server that is accessible only to the qubes in the dev group.
“Shared” Copy. When a user presses Ctrl+C in an AppVM, the clipboard data goes to the clipboard server. The local clipboard stays empty.
“Shared” Paste. When a user presses Ctrl+V and the local clipboard is empty, it:
i) gets clipboard data from the clipboard server to the local clipboard
ii) triggers the standard paste action
iii) clears the local clipboard
Qubes standard external Paste. When a user presses Ctrl+Shift+V to paste from the global Qubes clipboard, it goes into the local clipboard. Then the user can press Ctrl+V with local clipboard set, which pastes this content and clears the local clipboard as in (2) but from the local clipboard instead of the buffer stored on the clipboard server.
Qubes standard external Copy. When a user presses Shift+Ctrl+C, the selected content goes to the global Qubes clipboard instead of the custom clipboard server. The only difference is that you don’t need to press Ctrl+C before Shift+Ctrl+C.
So, (1) and (2) handle simple Ctrl+C/Ctrl+V across the dev qubes group, while (3) and (4) let you use the standard Qubes clipboard to copy/paste to qubes outside this group (for example, to copy access credentials from an outer qube). Distinguishing betwean this custom “shared” pasting and standard Qubes pasting is done using a flag “is local clipboard empty?” - our new mechanism always clears local clipboard.
Also it will break one essential decision, that the QubesOS Team has made. The global clipboard is controlled by Dom0, so it exists no way to access that clipboard from an lesser trusted domain without explizitely allowed by the user via Dom0 (Shift-Ctrl-C/V).
If the transport of potentially untrusted clipboard content only depends of something, that a qube can manage by itself, you open a door that better should be closed.
Even it exists no way to ask for the content of the central clipboard from a QubeVM or read the status.
It is always the decision of Dom0, if a clipboard content goes from a Qube to another. Think about your “clipboard-server” as a replacement of the central clipboard. Then you will see, that a Qube can decide by its own to copy content to that central clipboard replacement or fetch content from there only by it’s own.
I’m not sure that replacing the central Qubes clipboard mechanism is what I want. Actually, I want to keep it untouched. The only thing I want is to let a group of VMs operate with a clipboard shared across them, bypassing the central Qubes clipboard (clipboard contents won’t go outside the group), and to let them use simple Ctrl+C/Ctrl+V like before I split the projects into different VMs (previously I developed my whole ecosystem of JS projects on Ubuntu without using any VMs).
I know Qubes is an OS for hackers and whistleblowers, not for developers, but I’m convinced every developer should use it because security is essential. Maybe one day such solutions will be so natural that developers won’t imagine living without them - maybe someday…
So, I will probably need to write the code to implement this myself.
If you want to do it, you may look at qubes-gui-daemon and qubes-gui-agent-linux repositories which are written in C language and uses Xlib to communicate with X11 protocols. And the clipboard is handled there. The Qui Clipboard widget code is in qubes-desktop-linux-manager repository. But it is used mostly for notifications (except copying dom0 clipboard to global clipboard). And that is written in Python.
I had an idea that I could make something not touching the origin repos so that I could omit replacing any built-in Qubes OS components and just listen to shortcuts separately and making API calls (however this could have pitfalls as well).
Anyway, at this moment these are long-term plans, I have a huge list of what to fix and improve in my Qubes installation, but in the end I will reach the moment of starting this task implementation. Probably, these repos may be used as samples even if I would prefer my ley say Higher-Order-Component approach.